A production-ready REST API that predicts depression risk in teenagers using a trained machine learning model. Built with FastAPI, PostgreSQL, and scikit-learn, featuring JWT authentication, role-based access control, and structured logging.
- 🤖 ML Prediction — scikit-learn model classifies depression risk from 5 behavioral inputs
- 🔐 JWT Auth — access & refresh tokens delivered via
HttpOnlycookies - 👥 Role-based access —
userandadminroles with per-endpoint enforcement - 🛡️ Rate limiting — login endpoint protected against brute-force (10 req/min)
- 🗄️ PostgreSQL — connection pooling, cascading deletes, DB-level check constraints and indexes
- 📋 Structured logging — timestamped logs with per-module context,
DEBUGin dev /INFOin production - 🚀 Production-ready — docs/redoc/openapi disabled in production, CORS strictly configured, cookies set to
Secure+SameSite=Lax
| Layer | Technology |
|---|---|
| Framework | FastAPI 0.136 |
| Language | Python 3.11+ |
| Database | PostgreSQL + SQLAlchemy 2.0 |
| Migrations | Alembic |
| ML | scikit-learn 1.8 + NumPy |
| Auth | python-jose (JWT) + passlib (Argon2) |
| Validation | Pydantic v2 |
| Rate limiting | SlowAPI |
| Server | Uvicorn |
predict-teen-health/
├── app/
│ ├── auth/
│ │ ├── auth_service.py # Login, refresh session logic
│ │ ├── dependencies.py # JWT extraction, current user, role guards
│ │ ├── hashing.py # Argon2 password hashing
│ │ └── jwt_handler.py # Token creation
│ ├── core/
│ │ ├── config.py # Pydantic settings (validated from .env)
│ │ ├── database.py # SQLAlchemy engine + session + connection pool
│ │ ├── limiter.py # SlowAPI rate limiter instance
│ │ └── logger.py # Centralized logging setup
│ ├── data/
│ │ ├── analysis/ # Exploratory data analysis scripts
│ │ ├── data_service/ # Model loader
│ │ └── predict/ # Training pipeline
│ ├── models/
│ │ ├── base.py # SQLAlchemy declarative base
│ │ ├── predict.py # Predict table (constraints + indexes)
│ │ └── user.py # User table (roles, active flag)
│ ├── routers/
│ │ ├── auth_router.py # Auth & user management endpoints
│ │ └── predict.py # Prediction endpoints
│ ├── schemas/
│ │ ├── auth_schema.py # UserCreate, UserResponse
│ │ ├── predict_schema.py # DepressionInput, PredictResponse
│ │ └── common.py
│ ├── services/
│ │ ├── auth_service.py # User CRUD
│ │ └── predict_service.py # Prediction business logic + DB persistence
│ └── main.py # App factory, CORS, middleware, lifecycle hooks
├── alembic/ # Database migration history
├── .env.example # Environment variable template
├── requirements.txt
└── README.md
Copy .env.example to .env and fill in your values:
cp .env.example .env| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://user:pass@localhost:5432/db |
SECRET_KEY |
JWT signing key — min 32 chars | openssl rand -hex 32 |
ALGORITHM |
JWT algorithm | HS256 |
ACCESS_TOKEN_EXPIRE_MINUTES |
Access token lifetime | 15 |
REFRESH_TOKEN_EXPIRE_DAYS |
Refresh token lifetime | 7 |
CORS_ORIGINS |
Comma-separated allowed origins | https://yourapp.com |
ENV |
Runtime environment | development or production |
⚠️ Never commit your.envfile. It is already listed in.gitignore.
git clone https://github.com/your-username/predict-teen-health.git
cd predict-teen-healthpython -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activatepip install -r requirements.txtcp .env.example .env
# Edit .env with your database URL, secret key, and CORS originsalembic upgrade head# Development
uvicorn app.main:app --reload
# Production
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/login |
— | Sign in (rate-limited: 10/min) |
POST |
/logout |
✅ | Clear session cookies |
POST |
/refresh |
✅ | Rotate access & refresh tokens |
GET |
/users/me |
✅ | Get current user info |
| Method | Endpoint | Description |
|---|---|---|
POST |
/users |
Create a new user |
GET |
/all/users |
List all users (paginated) |
GET |
/users/{email} |
Find user by email |
DELETE |
/users/{user_id} |
Delete a user |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/ |
✅ | Submit data and get a depression risk prediction |
GET |
/predict/{predict_id} |
✅ | Retrieve a past prediction by ID |
{
"sleep_hours": 6.5,
"stress_level": 8,
"daily_social_media_hours": 4.0,
"anxiety_level": 7,
"academic_performance": 3.2
}{
"id": "019746a2-...",
"sleep_hours": 6.5,
"stress_level": 8,
"daily_social_media_hours": 4.0,
"anxiety_level": 7,
"academic_performance": 3.2,
"prediction": 1,
"probability": 0.87,
"message": "El modelo detectó posibles síntomas de depresión",
"created_at": "2026-05-02T14:30:00Z"
}users
├── id UUID (PK, uuid7)
├── email VARCHAR(255) UNIQUE
├── hashed_password VARCHAR(255)
├── role ENUM('user', 'admin')
├── is_active BOOLEAN
├── created_at TIMESTAMPTZ
└── updated_at TIMESTAMPTZ
predict
├── id UUID (PK, uuid7)
├── user_id UUID (FK → users.id CASCADE DELETE)
├── sleep_hours FLOAT [0 < x ≤ 24]
├── stress_level INT [1–10]
├── daily_social_media_hours FLOAT [0–24]
├── anxiety_level INT [1–10]
├── academic_performance FLOAT [0–5]
├── prediction INT [0 or 1]
├── probability FLOAT [0–1]
├── message VARCHAR(255)
└── created_at TIMESTAMPTZ
- Passwords hashed with Argon2 via passlib
- JWTs signed with HS256 and validated on every request
- Tokens delivered exclusively via
HttpOnlycookies (Secureflag enabled in production) SECRET_KEYvalidated at startup — minimum 32 characters, known-weak values rejected- API docs (
/docs,/redoc,/openapi.json) disabled inproductionmode - CORS restricted to explicitly configured origins
This project is licensed under the MIT License.
Built with ❤️ using FastAPI