Spaces:
Configuration error
Configuration error
modified Dockerfile readme.md and app.py
Browse files- Dockerfile +2 -2
- README.md +56 -0
- app.py +2 -3
- gunicorn_config.py +60 -0
Dockerfile
CHANGED
|
@@ -18,5 +18,5 @@ RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
|
| 18 |
|
| 19 |
COPY --chown=user . /app
|
| 20 |
|
| 21 |
-
# Run with gunicorn
|
| 22 |
-
CMD ["gunicorn", "--
|
|
|
|
| 18 |
|
| 19 |
COPY --chown=user . /app
|
| 20 |
|
| 21 |
+
# Run with gunicorn using config file
|
| 22 |
+
CMD ["gunicorn", "--config", "gunicorn_config.py", "app:app"]
|
README.md
CHANGED
|
@@ -9,4 +9,60 @@ license: mit
|
|
| 9 |
short_description: An AI resume builder
|
| 10 |
---
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 9 |
short_description: An AI resume builder
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Resume Builder
|
| 13 |
+
|
| 14 |
+
An AI-powered resume builder application that allows users to create professional resumes with multiple format exports.
|
| 15 |
+
|
| 16 |
+
## Features
|
| 17 |
+
|
| 18 |
+
- User authentication with email/password and GitHub OAuth
|
| 19 |
+
- AI-powered profile summary generation using OpenAI
|
| 20 |
+
- Multiple resume sections: Introduction, Work Experience, Projects, Education, Skills, Achievements
|
| 21 |
+
- Export resumes in Word (.docx) and PDF formats
|
| 22 |
+
- Admin panel for user management
|
| 23 |
+
- Responsive design with Bootstrap
|
| 24 |
+
|
| 25 |
+
## Hugging Face Deployment
|
| 26 |
+
|
| 27 |
+
This app is configured to run on Hugging Face Spaces with Docker.
|
| 28 |
+
|
| 29 |
+
### Required Environment Variables
|
| 30 |
+
|
| 31 |
+
Set these in your Space settings:
|
| 32 |
+
|
| 33 |
+
- `SECRET_KEY` - Flask secret key
|
| 34 |
+
- `DATABASE_URL` - PostgreSQL connection string (using Neon)
|
| 35 |
+
- `SQLALCHEMY_DATABASE_URI` - Same as DATABASE_URL
|
| 36 |
+
- `GITHUB_CLIENT_ID` - GitHub OAuth client ID
|
| 37 |
+
- `GITHUB_CLIENT_SECRET` - GitHub OAuth client secret
|
| 38 |
+
- `GITHUB_OAUTH_BACKEND_REDIRECT` - OAuth redirect URL
|
| 39 |
+
- `ADMIN_EMAIL` - Admin user email
|
| 40 |
+
- `OPENAI_API_KEY` - OpenAI API key for AI features
|
| 41 |
+
- `OPENAI_MODEL` - OpenAI model (default: gpt-4o)
|
| 42 |
+
|
| 43 |
+
### Setup Instructions
|
| 44 |
+
|
| 45 |
+
1. Create a Neon PostgreSQL database
|
| 46 |
+
2. Set all environment variables in Space settings
|
| 47 |
+
3. The app will automatically create tables on first run
|
| 48 |
+
4. GitHub OAuth app should be configured with callback URL:
|
| 49 |
+
`https://your-space-name.huggingface.space/api/auth/github/callback`
|
| 50 |
+
|
| 51 |
+
## Local Development
|
| 52 |
+
|
| 53 |
+
1. Copy `.env.example` to `.env`
|
| 54 |
+
2. Fill in your environment variables
|
| 55 |
+
3. Install dependencies: `pip install -r requirements.txt`
|
| 56 |
+
4. Create tables: `python create_tables.py`
|
| 57 |
+
5. Run app: `python app.py`
|
| 58 |
+
|
| 59 |
+
## Tech Stack
|
| 60 |
+
|
| 61 |
+
- Backend: Flask, SQLAlchemy, PostgreSQL
|
| 62 |
+
- Frontend: HTML, CSS, JavaScript, Bootstrap
|
| 63 |
+
- Authentication: Flask-Login, OAuth
|
| 64 |
+
- AI: OpenAI GPT
|
| 65 |
+
- PDF Generation: ReportLab
|
| 66 |
+
- Deployment: Docker, Gunicorn
|
| 67 |
+
|
| 68 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
CHANGED
|
@@ -1479,10 +1479,9 @@ def create_tables_if_needed():
|
|
| 1479 |
except Exception as e:
|
| 1480 |
print(f"Migration error: {e}")
|
| 1481 |
|
| 1482 |
-
# Initialize database
|
| 1483 |
-
create_tables_if_needed()
|
| 1484 |
-
|
| 1485 |
if __name__ == "__main__":
|
|
|
|
| 1486 |
port = int(os.environ.get('PORT', 5000))
|
| 1487 |
# Railway requires binding to 0.0.0.0
|
| 1488 |
# Check if we're running on Railway
|
|
|
|
| 1479 |
except Exception as e:
|
| 1480 |
print(f"Migration error: {e}")
|
| 1481 |
|
| 1482 |
+
# Initialize database only when running directly, not when imported
|
|
|
|
|
|
|
| 1483 |
if __name__ == "__main__":
|
| 1484 |
+
create_tables_if_needed()
|
| 1485 |
port = int(os.environ.get('PORT', 5000))
|
| 1486 |
# Railway requires binding to 0.0.0.0
|
| 1487 |
# Check if we're running on Railway
|
gunicorn_config.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import multiprocessing
|
| 2 |
+
import os
|
| 3 |
+
from app import create_tables_if_needed
|
| 4 |
+
|
| 5 |
+
# Server socket
|
| 6 |
+
bind = "0.0.0.0:7860"
|
| 7 |
+
|
| 8 |
+
# Worker processes
|
| 9 |
+
workers = 1
|
| 10 |
+
worker_class = "sync"
|
| 11 |
+
worker_connections = 1000
|
| 12 |
+
|
| 13 |
+
# Timeout
|
| 14 |
+
timeout = 120
|
| 15 |
+
keepalive = 2
|
| 16 |
+
|
| 17 |
+
# Max requests
|
| 18 |
+
max_requests = 1000
|
| 19 |
+
max_requests_jitter = 50
|
| 20 |
+
|
| 21 |
+
# Logging
|
| 22 |
+
accesslog = "-"
|
| 23 |
+
errorlog = "-"
|
| 24 |
+
loglevel = "info"
|
| 25 |
+
|
| 26 |
+
# Process name
|
| 27 |
+
proc_name = "resumebuilder"
|
| 28 |
+
|
| 29 |
+
# Preload app - this ensures database initialization happens once
|
| 30 |
+
preload_app = True
|
| 31 |
+
|
| 32 |
+
# Hook function to run after app is loaded
|
| 33 |
+
def on_starting(server):
|
| 34 |
+
"""Called when gunicorn starts"""
|
| 35 |
+
pass
|
| 36 |
+
|
| 37 |
+
def when_ready(server):
|
| 38 |
+
"""Called when gunicorn is ready"""
|
| 39 |
+
# Initialize database tables when ready
|
| 40 |
+
try:
|
| 41 |
+
print("Initializing database tables...")
|
| 42 |
+
create_tables_if_needed()
|
| 43 |
+
print("Database initialization completed")
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(f"Database initialization error: {e}")
|
| 46 |
+
|
| 47 |
+
def on_reload(server):
|
| 48 |
+
"""Called when gunicorn reloads"""
|
| 49 |
+
pass
|
| 50 |
+
|
| 51 |
+
# Environment variables
|
| 52 |
+
raw_env = [
|
| 53 |
+
"PORT=7860",
|
| 54 |
+
"PYTHONUNBUFFERED=1",
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
# Security
|
| 58 |
+
limit_request_line = 4096
|
| 59 |
+
limit_request_fields = 100
|
| 60 |
+
limit_request_field_size = 8190
|