It's still a work in progress!
A production-ready FastAPI boilerplate with built-in authentication, RBAC, database migrations, email service, and type generation for cross-platform development.
- Unified Authentication - JWT (local) AND OAuth2 (Google, Auth0, Okta) can run simultaneously
- RBAC - Role-Based Access Control with granular permissions
- Email Service - Dual provider support (SMTP + AWS SES API)
- Database Migrations - Alembic integration with SQLAlchemy
- Type Generation - Export types for TypeScript, Dart/Flutter
- Test Suite - Comprehensive security and auth tests
- Background Jobs - Async job queue with priority and scheduling
- Caching - In-memory cache with TTL and LRU eviction
- Rate Limiting - Token bucket rate limiting per IP/user/endpoint
- Security First - Token hashing, timing attack prevention, account lockout, CORS
- API Documentation - Auto-generated OpenAPI/Swagger docs
JetApi/
├── app/
│ ├── main.py # FastAPI application entry
│ ├── api/v1/routes/ # API route handlers
│ │ ├── auth_routes.py # Authentication endpoints
│ │ ├── user_routes.py # User management endpoints
│ │ └── admin_routes.py # Admin/monitoring endpoints
│ ├── core/
│ │ ├── config.py # Application settings
│ │ ├── database.py # SQLAlchemy setup
│ │ ├── logger.py # Logging with data protection
│ │ ├── cache.py # In-memory caching
│ │ ├── middleware/ # Request middleware
│ │ │ ├── logging.py # Request/response logging
│ │ │ └── rate_limit.py # Rate limiting
│ │ ├── jobs/ # Background jobs system
│ │ │ ├── queue.py # Job queue
│ │ │ ├── worker.py # Job workers
│ │ │ └── scheduler.py # Job scheduler
│ │ ├── email/ # Email service
│ │ │ └── service.py # SMTP + AWS SES providers
│ │ └── security/ # Auth implementations
│ │ ├── __init__.py # Unified auth module
│ │ ├── jwt/ # JWT authentication
│ │ └── oauth2/ # OAuth2 authentication
│ ├── models/ # SQLAlchemy ORM models
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic (RBAC)
│ ├── seeders/ # Database seeders
│ └── tests/ # Test suite
├── alembic/ # Database migrations
├── logs/ # Application logs
├── scripts/ # Utility scripts
│ └── generate_types.py # Type generator
├── generated/ # Generated type files
├── quick_setup.py # Setup wizard
├── requirements.txt # Python dependencies
└── .env.example # Environment template
git clone <repo-url> JetApi
cd JetApi# Install Python dependencies
pip install -r requirements.txtOption A: Quick Setup (SQLite - Default)
# Automated setup with SQLite database
python quick_setup.py --quickOption B: Interactive Setup (Choose your database)
# Interactive wizard - choose MySQL, PostgreSQL, or SQLite
python quick_setup.pyOption C: Manual Configuration
# 1. Copy the example environment file
cp .env.example .env # On Windows: copy .env.example .env
# 2. Edit .env and configure your settingsFor MySQL Database:
# Update these in .env file
DATABASE_URL=mysql+mysqlconnector://username:password@localhost:3306/your_database_name
# Example:
DATABASE_URL=mysql+mysqlconnector://root:mypassword@localhost:3306/jetapi_dbFor PostgreSQL Database:
DATABASE_URL=postgresql://username:password@localhost:5432/your_database_nameFor SQLite Database (Development):
DATABASE_URL=sqlite:///./jetapi.db# Create/update database tables
alembic upgrade head# Create default admin and user accounts
python -m app.seeders.seed_usersThis creates:
- Admin: admin@example.com / Admin123!
- User: user@example.com / User123!
uvicorn app.main:app --reload- API Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Health Check: http://localhost:8000/health
- Ensure MySQL is running:
systemctl status mysql(Linux) or check Services (Windows) - Verify credentials in DATABASE_URL
- Create the database first:
CREATE DATABASE jetapi_db;
-- Fix MySQL authentication
ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
FLUSH PRIVILEGES;# Reinstall dependencies
pip install -r requirements.txt# Reset database (WARNING: deletes all data)
alembic downgrade base
alembic upgrade headJetApi supports both JWT and OAuth2 simultaneously. You can enable local authentication, external OAuth2 providers, or both at the same time.
# Enable both authentication methods
ENABLE_LOCAL_AUTH=true # JWT-based local authentication
ENABLE_OAUTH2=true # OAuth2/OIDC external providersWhen ENABLE_LOCAL_AUTH=true, these endpoints are available:
POST /api/v1/auth/register- Register new userPOST /api/v1/auth/login- Login and get tokensPOST /api/v1/auth/refresh- Refresh access tokenPOST /api/v1/auth/forgot-password- Request password resetPOST /api/v1/auth/reset-password- Reset password with tokenPOST /api/v1/auth/verify-email- Verify email addressPOST /api/v1/auth/change-password- Change password (auth required)GET /api/v1/auth/me- Get current user infoPOST /api/v1/auth/logout- Logout (invalidate refresh token)
When ENABLE_OAUTH2=true, configure your provider:
OAUTH2_ISSUER=https://accounts.google.com
OAUTH2_AUDIENCE=your-client-id
OAUTH2_JWKS_URL=https://www.googleapis.com/oauth2/v3/certs
OAUTH2_AUTO_PROVISION=true # Auto-create users on first OAuth2 loginSupported Providers:
- GitHub
- Microsoft
- Auth0
- Okta
- Any OIDC-compliant provider
| Feature | Description |
|---|---|
| Token Hashing | Refresh tokens, password reset tokens, and email verification tokens are hashed (SHA256) before storage |
| Timing Attack Prevention | Constant-time comparison prevents user enumeration |
| Account Lockout | Automatic lockout after failed login attempts |
| Auth Rate Limiting | Per-IP rate limiting on authentication endpoints |
| Email Verification | Optional email verification before login |
| Role | Permissions |
|---|---|
| admin | users:read, users:create, users:update, users:delete, roles:, permissions: |
| user | users:read |
from app.services.rbac import require_permissions, require_roles
@router.get("/admin-only")
def admin_endpoint(user = Depends(require_roles("admin"))):
return {"message": "Admin access granted"}
@router.delete("/users/{id}")
def delete_user(user = Depends(require_permissions("users:delete"))):
# Only users with users:delete permission can access
passGenerate types for frontend frameworks:
# Generate all types
python scripts/generate_types.py --all
# Specific formats
python scripts/generate_types.py --typescript # TypeScript interfaces
python scripts/generate_types.py --dart # Dart/Flutter classes
python scripts/generate_types.py --json-schema # JSON Schema
python scripts/generate_types.py --openapi # OpenAPI specGenerated files are placed in ./generated/:
typescript/api-types.tsdart/api_types.dartjson-schema/schemas.jsonopenapi/openapi.json
JetApi includes a dual-provider email service supporting both SMTP and AWS SES.
# Email sender
EMAIL_FROM=noreply@yourdomain.com
# SMTP Provider
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_TLS=true
SMTP_SSL=false
# AWS SES Provider (optional, takes priority if enabled)
AWS_SES_ENABLED=true
AWS_SES_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-keyfrom app.core.email import (
send_email,
send_password_reset_email,
send_verification_email,
send_welcome_email,
)
# Send generic email
await send_email(
to="user@example.com",
subject="Hello",
body_html="<p>Welcome!</p>",
body_text="Welcome!",
)
# Send password reset email (with HTML template)
await send_password_reset_email(
email="user@example.com",
token="reset-token-here",
user_name="John Doe",
)
# Send verification email
await send_verification_email(
email="user@example.com",
token="verify-token-here",
user_name="John Doe",
)
# Send welcome email
await send_welcome_email(
email="user@example.com",
user_name="John Doe",
)- AWS SES - Used if
AWS_SES_ENABLED=trueand configured - SMTP - Fallback if SES fails or is not configured
# Run migrations
alembic upgrade head
# Create new migration
alembic revision --autogenerate -m "description"
# Rollback
alembic downgrade -1# SQLite (default)
DATABASE_URL=sqlite:///./jetapi.db
# PostgreSQL
DATABASE_URL=postgresql://user:pass@localhost:5432/dbname
# MySQL
DATABASE_URL=mysql+mysqlconnector://user:pass@localhost:3306/dbname# Run all tests
pytest app/tests -v
# Run specific test file
pytest app/tests/test_auth.py -v
# Run with coverage
pytest app/tests --cov=app --cov-report=htmlBuilt-in async job queue with priority support:
from app.core.jobs import enqueue_job, JobPriority
# Enqueue a background job
job = await enqueue_job(
send_email_job,
"user@example.com",
"Welcome!",
priority=JobPriority.HIGH,
)
# Schedule job for later
from app.core.jobs import schedule_job
await schedule_job(cleanup_task, delay_seconds=3600)
# Recurring jobs
from app.core.jobs import schedule_recurring
await schedule_recurring(daily_report, interval_seconds=86400)Admin endpoints for job management:
GET /api/v1/admin/jobs/stats- Queue statisticsGET /api/v1/admin/jobs/{id}- Job statusDELETE /api/v1/admin/jobs/{id}- Cancel jobGET /api/v1/admin/scheduled- List scheduled jobs
In-memory cache with TTL and LRU eviction:
from app.core.cache import cache, cached
# Direct cache operations
await cache.set("key", {"data": "value"}, ttl=60)
value = await cache.get("key")
# Decorator for automatic caching
@cached(ttl=300, namespace="users")
async def get_user_profile(user_id: int):
# Expensive operation...
return user_dataAdmin endpoints:
GET /api/v1/admin/cache/stats- Cache statisticsDELETE /api/v1/admin/cache- Clear cache
Token bucket rate limiting per IP/user:
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60 # secondsRoute-specific rate limiting:
from app.core.middleware.rate_limit import rate_limit
@router.post("/expensive-operation")
async def expensive_op(_: None = Depends(rate_limit(requests=5, window=60))):
...Comprehensive logging with sensitive data protection:
- General logs:
logs/jetapi.log- Human-readable format - Error logs:
logs/errors.log- Errors and exceptions - Access logs:
logs/access.log- Apache/Nginx combined format - JSON logs:
logs/jetapi.json.log- For log aggregation - Security logs:
logs/security.log- Auth events
Automatic redaction of:
- Passwords
- Tokens (access, refresh, API keys)
- Authorization headers
- Credit card patterns
- SSN patterns
All settings are in .env. Key options:
# ===================
# Core Settings
# ===================
PROJECT_NAME=JetApi
DEBUG=true
SECRET_KEY=your-secret-key
# ===================
# Database
# ===================
DATABASE_URL=sqlite:///./jetapi.db
# ===================
# Authentication
# ===================
# Enable authentication methods (can enable both)
ENABLE_LOCAL_AUTH=true
ENABLE_OAUTH2=false
# JWT Settings
JWT_SECRET_KEY=your-jwt-secret # REQUIRED in production
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=60
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# OAuth2 Settings (if ENABLE_OAUTH2=true)
OAUTH2_ISSUER=https://accounts.google.com
OAUTH2_AUDIENCE=your-client-id
OAUTH2_JWKS_URL=https://www.googleapis.com/oauth2/v3/certs
OAUTH2_AUTO_PROVISION=true
# ===================
# Security
# ===================
# Auth Rate Limiting
AUTH_RATE_LIMIT_ATTEMPTS=5
AUTH_RATE_LIMIT_WINDOW=300 # seconds
# Email Verification
REQUIRE_EMAIL_VERIFICATION=false
# Password Policy
PASSWORD_MIN_LENGTH=8
PASSWORD_REQUIRE_UPPERCASE=true
PASSWORD_REQUIRE_DIGIT=true
# ===================
# Email Service
# ===================
EMAIL_FROM=noreply@yourdomain.com
# SMTP Settings
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_TLS=true
SMTP_SSL=false
# AWS SES Settings (optional)
AWS_SES_ENABLED=false
AWS_SES_REGION=us-east-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
# ===================
# RBAC
# ===================
ENABLE_RBAC=true
# ===================
# Rate Limiting
# ===================
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60
# ===================
# Caching
# ===================
CACHE_DEFAULT_TTL=300
CACHE_MAX_SIZE=1000- Create route file in
app/api/v1/routes/ - Import and include in
app/main.py - Add tests in
app/tests/
- Create model in
app/models/ - Create schema in
app/schemas/ - Create migration:
alembic revision --autogenerate -m "add model" - Apply:
alembic upgrade head
| Layer | Location | Purpose |
|---|---|---|
| Routes | app/api/v1/routes/ |
API endpoint definitions |
| Schemas | app/schemas/ |
Request/response validation |
| Models | app/models/ |
Database table definitions |
| Services | app/services/ |
Business logic (RBAC, etc.) |
| Core | app/core/ |
Config, database, security, email |
JetApi implements production-grade security:
| Feature | Implementation |
|---|---|
| Password Hashing | bcrypt with random salt |
| Token Storage | SHA256 hashing (refresh, reset, verification tokens) |
| Timing Attacks | Constant-time comparison on all auth checks |
| Account Lockout | Configurable lockout after failed attempts |
| Rate Limiting | Per-IP and per-endpoint limits |
| JWT Security | Short-lived access tokens, secure refresh rotation |
| CORS | Configurable allowed origins |
| Input Validation | Pydantic schemas on all endpoints |
| SQL Injection | SQLAlchemy ORM with parameterized queries |
| Sensitive Data | Automatic log redaction of passwords/tokens |
- Set
DEBUG=false - Set strong
SECRET_KEYandJWT_SECRET_KEY - Configure proper
CORS_ORIGINS - Enable
REQUIRE_EMAIL_VERIFICATION=true - Set up rate limiting
- Use PostgreSQL instead of SQLite
- Configure email service for password resets
- Review and adjust
AUTH_RATE_LIMIT_*settings
MIT License
Built with using FastAPI