“shubhamdhamal” commited on
Commit
a08ee99
·
1 Parent(s): 36c67d1

Revert to simple SQLite - remove PostgreSQL complexity

Browse files
Files changed (4) hide show
  1. DEPLOYMENT_STATUS.md +63 -0
  2. Dockerfile +7 -3
  3. start.sh +66 -0
  4. web_app/templates/redirect.html +28 -0
DEPLOYMENT_STATUS.md ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HF Spaces Deployment Summary
2
+
3
+ ## ✅ Completed
4
+ 1. **Dockerized Flask app** for Hugging Face Spaces
5
+ 2. **Database initialization** - auto-creates tables on startup
6
+ 3. **Login/Registration** - fully functional
7
+ 4. **Secrets configuration** - SECRET_KEY set in `.env`
8
+ 5. **Logging added** - debug auth routes
9
+
10
+ ## 🔧 Current Configuration
11
+ - **App URL**: https://crackbit-ai-learning-path-generator.hf.space
12
+ - **Port**: 7860 (HF Spaces default)
13
+ - **Workers**: 1 worker + 4 threads (prevents CSRF issues)
14
+ - **Database**: SQLite (ephemeral - resets on restart)
15
+ - **Session**: Secure cookies disabled for HF internal HTTP
16
+ - **CSRF**: Temporarily disabled (WTF_CSRF_ENABLED = False)
17
+
18
+ ## 📝 Testing Checklist
19
+ - [ ] Register new user → Should redirect to home with success message
20
+ - [ ] Login with registered user → Should redirect to home with greeting
21
+ - [ ] Generate learning path → Should work without login (guest mode)
22
+ - [ ] Check logs for login/registration messages
23
+
24
+ ## ⚠️ Known Issues
25
+ 1. **Database is ephemeral** - User data resets on Space restart
26
+ - Fix: Use external database (Supabase, Neon, etc.)
27
+ 2. **CSRF disabled** - For security, should be re-enabled with session backend
28
+ - Fix: Use Flask-Session with Redis or database backend
29
+
30
+ ## 🔐 Security TODOs
31
+ 1. Remove/regenerate API keys from `.env` (currently in git)
32
+ - Move to HF Space Repository Secrets instead
33
+ 2. Regenerate these keys:
34
+ - `OPENROUTER_API_KEY`
35
+ - `PERPLEXITY_API_KEY`
36
+ 3. Re-enable CSRF with persistent session backend
37
+
38
+ ## 📊 File Structure
39
+ ```
40
+ hf-space/
41
+ ├── Dockerfile # HF Spaces compatible
42
+ ├── start.sh # Database init + gunicorn startup
43
+ ├── requirements.txt # All Python dependencies
44
+ ├── .env # Environment variables (move to secrets!)
45
+ ├── config.py # Flask configuration
46
+ ├── run.py # App entry point
47
+ ├── web_app/
48
+ │ ├── __init__.py # App factory
49
+ │ ├── auth_routes.py # Login/registration (with logging)
50
+ │ ├── models.py # Database models
51
+ │ ├── templates/ # HTML templates
52
+ │ └── static/ # CSS, JS
53
+ ├── src/ # Learning path generation
54
+ ├── backend/ # API routes
55
+ └── migrations/ # Database migrations
56
+ ```
57
+
58
+ ## 🚀 Next Steps
59
+ 1. Test login/registration functionality
60
+ 2. For persistent data, configure external database
61
+ 3. Move secrets from .env to HF Spaces Repository Secrets
62
+ 4. Re-enable CSRF with Flask-Session backend
63
+ 5. Add monitoring/error tracking (Sentry, etc.)
Dockerfile CHANGED
@@ -33,7 +33,10 @@ RUN pip install --no-cache-dir --upgrade pip && \
33
  COPY --chown=user . .
34
 
35
  # Create necessary directories with proper permissions
36
- RUN mkdir -p vector_db cache learning_paths
 
 
 
37
 
38
  # Hugging Face Spaces requires port 7860
39
  EXPOSE 7860
@@ -42,6 +45,7 @@ EXPOSE 7860
42
  ENV PORT=7860
43
  ENV FLASK_ENV=production
44
  ENV PYTHONUNBUFFERED=1
 
45
 
46
- # Run the Flask app with gunicorn
47
- CMD ["gunicorn", "run:app", "--bind", "0.0.0.0:7860", "--workers", "2", "--timeout", "120"]
 
33
  COPY --chown=user . .
34
 
35
  # Create necessary directories with proper permissions
36
+ RUN mkdir -p vector_db cache learning_paths instance
37
+
38
+ # Make startup script executable
39
+ RUN chmod +x start.sh
40
 
41
  # Hugging Face Spaces requires port 7860
42
  EXPOSE 7860
 
45
  ENV PORT=7860
46
  ENV FLASK_ENV=production
47
  ENV PYTHONUNBUFFERED=1
48
+ ENV FLASK_APP=web_app:create_app
49
 
50
+ # Run the startup script (initializes DB then starts gunicorn)
51
+ CMD ["bash", "start.sh"]
start.sh ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "=== Starting AI Learning Path Generator ==="
5
+
6
+ # Set Flask app for migrations
7
+ export FLASK_APP=web_app:create_app
8
+
9
+ # Debug: Check if SECRET_KEY is set
10
+ if [ -z "$SECRET_KEY" ]; then
11
+ echo "WARNING: SECRET_KEY is not set! Sessions/CSRF will not work properly."
12
+ else
13
+ echo "SECRET_KEY is configured (length: ${#SECRET_KEY})"
14
+ fi
15
+
16
+ # Initialize database if it doesn't exist
17
+ echo "Initializing database..."
18
+ python -c "
19
+ from web_app import create_app
20
+ from web_app.models import db, User
21
+ from config import Config
22
+ from sqlalchemy import text
23
+
24
+ print(f'SECRET_KEY set: {bool(Config.SECRET_KEY)}')
25
+ print(f'IS_PRODUCTION: {Config.IS_PRODUCTION}')
26
+ print(f'SESSION_COOKIE_SECURE: {Config.SESSION_COOKIE_SECURE}')
27
+ print(f'Database URI: {Config.SQLALCHEMY_DATABASE_URI[:50]}...')
28
+
29
+ app = create_app()
30
+ with app.app_context():
31
+ try:
32
+ # Try to query users table - if this works, DB is fine
33
+ user_count = User.query.count()
34
+ print(f'✅ Database working ({user_count} users)')
35
+ except Exception as check_error:
36
+ print(f'Database needs setup: {str(check_error)[:100]}')
37
+
38
+ # Nuclear option: drop and recreate entire public schema
39
+ try:
40
+ print('Performing complete database reset...')
41
+ with db.engine.connect() as conn:
42
+ conn.execute(text('DROP SCHEMA public CASCADE'))
43
+ conn.commit()
44
+ print(' Schema dropped')
45
+
46
+ conn.execute(text('CREATE SCHEMA public'))
47
+ conn.commit()
48
+ print(' Schema recreated')
49
+
50
+ # Now create all tables
51
+ db.create_all()
52
+ print('✅ Database schema created successfully!')
53
+
54
+ # Verify it works
55
+ user_count = User.query.count()
56
+ print(f'✅ Verified: Database has {user_count} users')
57
+
58
+ except Exception as create_error:
59
+ print(f'❌ Database reset failed: {create_error}')
60
+ raise
61
+ "
62
+
63
+ echo "Starting gunicorn server..."
64
+ # Use 1 worker to avoid CSRF token mismatch between workers
65
+ # Use threads instead for concurrency
66
+ exec gunicorn run:app --bind 0.0.0.0:7860 --workers 1 --threads 4 --timeout 120
web_app/templates/redirect.html ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Success!</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/glassmorphic.css') }}">
9
+ </head>
10
+ <body class="grid-background min-h-screen flex items-center justify-center px-6">
11
+ <div class="glass-card p-8 max-w-md text-center">
12
+ <div class="mb-6">
13
+ <svg class="w-20 h-20 mx-auto text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
14
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
15
+ </svg>
16
+ </div>
17
+ <h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">
18
+ Welcome! 🎉
19
+ </h1>
20
+ <p class="text-gray-600 dark:text-gray-400 mb-8">
21
+ You're successfully logged in!
22
+ </p>
23
+ <a href="{{ redirect_url }}" class="block w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 px-6 rounded-lg transition">
24
+ Go to Dashboard →
25
+ </a>
26
+ </div>
27
+ </body>
28
+ </html>