A production-ready FastAPI boilerplate with authentication, database management, AI chatbot, and essential middleware.
-
Authentication & Authorization
- Email/Password registration with email verification
- OAuth2 (Google, Apple Sign-In)
- JWT access tokens with secure refresh token rotation
- Device tracking and multi-device session management
- Password reset with rate-limited verification codes
-
User Management
- Extensible user model with timezone support
- Profile management endpoints
- Account deactivation
- User repository pattern
-
AI Chatbot
- Real-time streaming responses via WebSocket
- Thread-based conversation management
- File attachments support (images, documents, audio, video)
- Automatic message summarization
- Content moderation with fallback safety
- Context-aware conversations
-
Database & ORM
- PostgreSQL with async SQLAlchemy
- Alembic migrations
- Base repository pattern for CRUD operations
- Proper foreign key relationships and indexes
- Security Headers: HSTS, CSP, X-Frame-Options, X-Content-Type-Options
- Request Logging: Structured JSON logging for production
- Rate Limiting: Redis-backed rate limiting
- CORS: Configurable cross-origin requests
- Max Request Size: File upload size limits
- Caching: Redis response caching decorator
- Storage: Google Cloud Storage for file uploads
- Email: ZeptoMail with Jinja2 HTML templates (mock mode for development)
- Celery: Background task processing
- Countries API: Country list with timezone inference
- OpenAPI: Bearer token auth in Swagger UI
fastapi-boilerplate/
├── api.py # FastAPI application entry point
├── src/
│ ├── core/ # Core application logic
│ │ ├── config.py # Settings and environment variables
│ │ ├── database.py # Database connection and session
│ │ ├── security.py # JWT, password hashing, tokens
│ │ ├── logging.py # JSON/structured logging
│ │ ├── exception.py # Custom exception classes
│ │ ├── handler.py # Global exception handlers
│ │ ├── repository.py # Base repository pattern
│ │ ├── schema.py # Base Pydantic schemas
│ │ ├── websocket.py # WebSocket base handler
│ │ ├── middlewares/ # Request/response middlewares
│ │ │ ├── security.py # Security headers (CSP configured for Swagger)
│ │ │ ├── logging.py # Request logging
│ │ │ ├── ratelimit.py # Rate limiting
│ │ │ └── cache.py # Response caching
│ │ ├── services/ # Shared services
│ │ │ ├── email_service.py # ZeptoMail with templates
│ │ │ │ └── email_templates/ # Jinja2 HTML templates
│ │ │ ├── storage.py # Google Cloud Storage
│ │ │ ├── redis_service.py # Redis operations
│ │ │ └── ai_service.py # AI integrations
│ │ ├── utils/ # Utility functions
│ │ │ └── timezone.py # Timezone inference
│ │ └── models/ # Core database models
│ │ └── user.py # BaseUser model
│ └── modules/ # Feature modules
│ ├── auth/ # Authentication
│ │ ├── router.py # Auth endpoints
│ │ ├── service.py # Auth business logic
│ │ ├── schemas.py # Request/response models
│ │ ├── dependencies.py # Auth dependencies
│ │ ├── repositories/ # Refresh token repo
│ │ └── tasks/ # Cleanup background tasks
│ ├── users/ # User management
│ │ ├── router.py # User endpoints (/users/me)
│ │ ├── service.py # User business logic
│ │ ├── models.py # User model (extends BaseUser)
│ │ ├── repository.py # User data access
│ │ └── schemas.py # User schemas
│ ├── chatbot/ # AI Chatbot
│ │ ├── routes/ # WebSocket & upload endpoints
│ │ ├── models/ # Thread, Message, Summary models
│ │ ├── repositories/ # Data access layer
│ │ └── services/ # Business logic
│ │ ├── chat_service.py # Main orchestrator
│ │ ├── agent_service.py # AI streaming
│ │ ├── context_service.py # Context building
│ │ ├── moderation_service.py # Content safety
│ │ └── websocket_service.py # WebSocket handler
│ ├── countries/ # Countries & Timezones
│ │ ├── router.py # Countries endpoint
│ │ └── service.py # Country data with timezones
│ └── health/ # Health check
│ └── router.py # Health endpoint
├── alembic/ # Database migrations
│ ├── env.py # Alembic environment
│ └── versions/ # Migration files
├── pyproject.toml # Dependencies (uv)
├── docker-compose.yml # Docker setup
├── Dockerfile # Application container
└── .env.example # Environment template
- Python 3.13+
- PostgreSQL 15+
- Redis 7+
- Google Cloud Platform account (for storage and AI)
Mac/Linux:
curl -LsSf https://astral.sh/uv/install.sh | shWindows:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"git clone git@github.com:0Baris/fastapi-boilerplate.git
cd fastapi-boilerplate
uv syncCopy the example environment file and configure:
cp .env.example .envEdit .env with your settings (see Environment Variables section below).
Create PostgreSQL database:
createdb fastapi_boilerplateRun migrations:
uv run alembic upgrade headDevelopment:
uv run uvicorn api:app --reload --port 8000Production:
uv run uvicorn api:app --host 0.0.0.0 --port 8000 --workers 4With Docker:
docker compose up -d --buildAccess the API:
- API: http://localhost:8000
- Swagger UI: http://localhost:8000/api/docs
- ReDoc: http://localhost:8000/api/redoc
# Application
PROJECT_NAME="FastAPI Boilerplate"
ENVIRONMENT=development # development, staging, production
SECRET_KEY=your-secret-key-min-32-chars
DEBUG_RETURN_VERIFICATION_CODE=true # Return codes in response (dev only)
# Database
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/dbname
# Redis
REDIS_URL=redis://localhost:6379/0
# Security
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
REFRESH_TOKEN_EXPIRE_DAYS=30# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
# Apple Sign-In
APPLE_BUNDLE_ID=com.yourapp.bundle
APPLE_SERVICE_ID=com.yourapp.service# Cloud Storage
PUBLIC_BUCKET_NAME=your-public-bucket
PRIVATE_BUCKET_NAME=your-private-bucket
GOOGLE_APPLICATION_CREDENTIALS_BASE64=base64-encoded-service-account-json
# Gemini AI
GOOGLE_API_KEY=your-gemini-api-key
GEMINI_CHAT_MODEL=gemini-2.0-flash-exp
GEMINI_MODEL_LOW=gemini-2.0-flash-exp# ZeptoMail
USE_MOCK_EMAIL=true # Set to false in production
ZEPTOMAIL_API_KEY=your-zeptomail-api-key
ZEPTOMAIL_FROM_EMAIL=noreply@yourdomain.com
ZEPTOMAIL_FROM_NAME="FastAPI Boilerplate"CHAT_SUMMARY_TRIGGER_COUNT=50 # Messages before auto-summary
CHAT_MAX_FILE_SIZE_MB=10 # Max file upload size# CORS
BACKEND_CORS_ORIGINS=["http://localhost:3000","http://localhost:8000"]
# Swagger Auth (production)
SWAGGER_USER=admin
SWAGGER_PASSWORD=secure-password
# Celery (Optional)
CELERY_BROKER_URL=redis://localhost:6379/1
CELERY_RESULT_BACKEND=redis://localhost:6379/1Register with Email:
POST /api/v1/auth/register
{
"email": "user@example.com",
"password": "SecurePass123!",
"full_name": "John Doe"
}Login:
POST /api/v1/auth/login
{
"email": "user@example.com",
"password": "SecurePass123!"
}
Response:
{
"access_token": "eyJ...",
"refresh_token": "...",
"token_type": "bearer"
}Get Profile:
GET /api/v1/users/me
Authorization: Bearer <access_token>Update Profile:
PATCH /api/v1/users/me
Authorization: Bearer <access_token>
{
"full_name": "Jane Doe",
"timezone": "America/New_York"
}WebSocket Connection:
const ws = new WebSocket('ws://localhost:8000/api/v1/chat/ws?token=<jwt_token>');
// Send message
ws.send(JSON.stringify({
type: 'send_message',
thread_id: null, // null for new thread
content: 'Hello, AI!',
upload_ids: []
}));
// Receive streaming response
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data.type, data.content);
};File Upload:
POST /api/v1/chat/upload
Authorization: Bearer <access_token>
Content-Type: multipart/form-data
file: <your-file>from src.core.middlewares.cache import cache_response
@router.get("/countries")
@cache_response(expire=3600) # Cache for 1 hour
async def get_countries():
return {"countries": [...]}The boilerplate includes beautiful, responsive HTML email templates:
- Verification Code: Email verification with OTP
- Welcome Email: Onboarding email after registration
- Password Reset: Password reset with security tips
Templates use Jinja2 and are located in src/core/services/email_templates/.
Development Mode:
Set USE_MOCK_EMAIL=true to log emails to console instead of sending.
uv run alembic revision --autogenerate -m "Add new field"uv run alembic upgrade headuv run alembic downgrade -1uv run alembic historyBuild and run:
docker compose up -d --buildProduction Checklist:
- Set
ENVIRONMENT=production - Use strong
SECRET_KEY(32+ characters) - Set
DEBUG_RETURN_VERIFICATION_CODE=false - Configure secure
SWAGGER_USERandSWAGGER_PASSWORD - Enable HTTPS and set proper
BACKEND_CORS_ORIGINS - Set up proper database connection pooling
- Configure Redis persistence
- Set up log aggregation (JSON logs ready for ELK/CloudWatch)
- Enable security headers (already configured)
- Set up rate limiting thresholds
- Configure Celery workers for background tasks
- Set
USE_MOCK_EMAIL=falseand configure ZeptoMail - Configure Google Cloud Storage buckets
Horizontal Scaling:
- Run multiple uvicorn workers:
--workers 4 - Use load balancer (nginx, Cloud Load Balancer)
- Redis for shared session state
- PostgreSQL read replicas
Performance:
- Use Redis caching for read-heavy endpoints
- Enable connection pooling in SQLAlchemy
- Implement database indexes (already configured)
- Use CDN for static assets
Format code with Ruff:
uv run ruff check .
uv run ruff format .Install pre-commit:
uv run pre-commit installRun manually:
uv run pre-commit run --all-filesEach feature is a self-contained module with:
router.py- API endpointsservice.py- Business logicrepository.py- Data accessschemas.py- Pydantic modelsmodels.py- SQLAlchemy models (if needed)
All database operations go through repositories:
class UserRepository(BaseRepository[User]):
async def get_by_email(self, email: str) -> User | None:
result = await self.db.scalars(
select(self.model).where(self.model.email == email)
)
return result.one_or_none()Business logic is separated from API routes:
class UserService:
def __init__(self, db: AsyncSession):
self.user_repo = UserRepository(db)
async def update_profile(self, user_id, update_data):
user = await self.user_repo.get(user_id)
return await self.user_repo.update(user, update_data)- Password Hashing: bcrypt with SHA-256 pre-hashing
- JWT Tokens: HS256 algorithm with configurable expiration
- Refresh Token Rotation: Automatic rotation with reuse detection
- Rate Limiting: Redis-backed request throttling
- Content Moderation: AI + keyword fallback for chatbot safety
- Security Headers: HSTS, CSP (configured for Swagger CDN), X-Frame-Options, etc.
- Input Validation: Pydantic v2 schemas
- SQL Injection Prevention: SQLAlchemy parameterized queries
- CORS: Configurable allowed origins
Once the server is running, access:
- Swagger UI: http://localhost:8000/api/docs
- ReDoc: http://localhost:8000/api/redoc
- OpenAPI Schema: http://localhost:8000/api/openapi.json
- Chatbot Docs: http://localhost:8000/api/v1/chat/docs
In production, documentation is protected by HTTP Basic Auth (configured via SWAGGER_USER and SWAGGER_PASSWORD).
MIT License - feel free to use this boilerplate for your projects.
For issues and questions:
- Create an issue in the repository
- Contact: bariscem@proton.me
Built with: