🚀 FastAPI Laravel-Style Boilerplate
The "batteries-included" developer experience of Laravel, powered by the high-performance async capabilities of FastAPI.
This boilerplate is designed for developers who love Laravel's elegant syntax, clear structure, and powerful CLI, but want to build their next high-performance microservice or AI platform using Python.
🔥 Why This Boilerplate?
Most FastAPI projects start as a single main.py and grow into a chaotic mess. This project brings opinionated structure and production-ready patterns out of the box:
- 🏛️ Domain-Driven Design: Clear separation of Controllers, Models, Services, and Jobs.
- 🛠️ Artisan CLI: A powerful command-line interface for migrations, code generation, and task management.
- 📡 Real-time Broadcasting: Laravel-like WebSocket channels (Public/Private/Presence).
- 📦 Unified Storage: Fluent API for Local, S3, FTP, and SFTP.
- ⚡ Redis Everything: Caching (Laravel-like Cache facade) and Task Queuing (Celery) pre-configured.
- 🛡️ Security First: JWT auth, RBAC (Policies & Gates), Rate Limiting, and CORS protection.
🛠️ Tech Stack
- Framework: FastAPI
- ORM: SQLAlchemy 2.0 (PostgreSQL & MySQL support)
- Migrations: Alembic
- Validation: Pydantic v2
- Task Queue: Celery with Redis
- Testing: Pytest with Coverage
- Linting: Ruff (The fastest Python linter)
🚀 Getting Started
🐳 Option 1: Docker (Recommended)
Launch the entire stack (App, DB, Redis, Worker, Flower) with a single command:
# 1. Clone the repo
git clone https://github.com/gargashwani/fastapi_boilerplate.git && cd fastapi_boilerplate
# 2. Setup environment
cp .env.example .env
# 3. Start everything
docker-compose up -d
🐍 Option 2: Local Installation (Recommended)
If you prefer running without Docker:
-
Install uv (if not already installed):
-
Setup environment & dependencies:
-
Run Interactive Installer:
-
Start the server:
🎮 Artisan CLI Usage
Just like Laravel, we provide an artisan.py script to speed up development:
# Generate a new Controller
python artisan make:controller UserProfile
# Run database migrations
python artisan migrate
# List all scheduled tasks
python artisan schedule:list
# Generate secure APP_KEY
python artisan key:generate
Authentication Examples
Register a New User
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "Test@12345",
"full_name": "John Doe",
"is_active": true,
"is_superuser": false
}'
Response:
{
"id": 1,
"email": "user@example.com",
"full_name": "John Doe",
"is_active": true,
"is_superuser": false,
"created_at": "2025-12-18T07:40:47.076834",
"updated_at": "2025-12-18T07:40:47.076838"
}
Note: After registration, use the /api/v1/auth/login endpoint to get an authorization token.
Login
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=user@example.com&password=Test@12345"
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"user": {
"id": 1,
"email": "user@example.com",
"full_name": "John Doe",
"is_active": true,
"is_superuser": false,
"created_at": "2025-12-18T07:40:47.076834",
"updated_at": "2025-12-18T07:40:47.076838"
}
}
Using the Authorization Token
All API endpoints (except /api/v1/auth/login and /api/v1/auth/register) require authentication.
After login, use the access_token in the Authorization header for all subsequent requests:
curl -X GET http://localhost:8000/api/v1/users/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Without authentication, you'll receive:
| Endpoint | Status | Access |
|---|---|---|
/api/v1/users/* | ✅ | Requires authentication |
/api/v1/files/* | ✅ | Requires authentication |
/api/v1/broadcasting/* | ✅ | Requires authentication |
/api/v1/auth/login | ❌ | Public (no authentication) |
/api/v1/auth/register | ❌ | Public (no authentication) |
Password Requirements
- Minimum 8 characters
- Maximum 512 characters (bcrypt limitation handled automatically)
- At least one uppercase letter (A-Z)
- At least one lowercase letter (a-z)
- At least one digit (0-9)
API Endpoints
Authentication
Public Endpoints (No authentication required):
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/auth/register | Register a new user (returns user info only) |
POST | /api/v1/auth/login | Login and get access token + user info |
All other endpoints require authentication. Include the Authorization header:
Users (Authentication Required)
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/users/me | Get current user |
PUT | /api/v1/users/me | Update current user |
GET | /api/v1/users | Get all users (admin only) |
GET | /api/v1/users/{user_id} | Get specific user |
DELETE | /api/v1/users/{user_id} | Delete user (admin only) |
Files (Authentication Required)
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/files/upload | Upload a file |
GET | /api/v1/files/download/{file_path} | Download a file |
GET | /api/v1/files/info/{file_path} | Get file information |
DELETE | /api/v1/files/delete/{file_path} | Delete a file |
GET | /api/v1/files/list | List files in directory |
POST | /api/v1/files/copy | Copy a file |
POST | /api/v1/files/move | Move a file |
Broadcasting (Authentication Required)
| Method | Endpoint | Description |
|---|---|---|
WS | /api/v1/broadcasting/ws | WebSocket connection endpoint (requires token in query parameter: ?token=<access_token>) |
POST | /api/v1/broadcasting/auth | Authorize private/presence channel access |
Documentation
| Method | Endpoint | Description |
|---|---|---|
GET | /docs | Swagger UI documentation |
GET | /redoc | ReDoc documentation |
GET | / | API welcome message |
Configuration
Database Selection
The boilerplate supports both PostgreSQL and MySQL. Switch between them by changing DB_CONNECTION in your .env file:
PostgreSQL (Default):
DB_CONNECTION=postgresql
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=fastapi_boilerplate
DB_USERNAME=postgres
DB_PASSWORD=postgres
MySQL:
DB_CONNECTION=mysql+pymysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=fastapi_boilerplate
DB_USERNAME=root
DB_PASSWORD=root
# Optional: For MAMP
# DB_UNIX_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
The same SQLAlchemy models work with both databases - no code changes needed!
File Storage Configuration
The boilerplate provides a Laravel-like file storage system supporting multiple drivers:
Local Storage (Default):
Amazon S3:
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your-bucket-name
FTP:
FILESYSTEM_DISK=ftp
FTP_HOST=ftp.example.com
FTP_PORT=21
FTP_USERNAME=your-username
FTP_PASSWORD=your-password
SFTP:
FILESYSTEM_DISK=sftp
SFTP_HOST=sftp.example.com
SFTP_PORT=22
SFTP_USERNAME=your-username
SFTP_PASSWORD=your-password
SFTP_KEY=/path/to/private/key
Switch between storage drivers by changing FILESYSTEM_DISK - same API for all!
Redis Configuration
Redis is used for both caching and message queue. Configure in .env:
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=
# Cache Configuration
CACHE_PREFIX=cache:
CACHE_DEFAULT_TTL=3600
CACHE_SERIALIZER=json
Development
Prerequisites
- Python 3.8+
- PostgreSQL or MySQL
- Redis (for caching and message queue)
- pip and virtualenv
Running the Development Server
The API will be available at: - API: http://localhost:8000 - Swagger UI: http://localhost:8000/docs - ReDoc: http://localhost:8000/redoc
Database Migrations
# Create a new migration
alembic revision --autogenerate -m "description"
# Apply migrations
alembic upgrade head
# Rollback one migration
alembic downgrade -1
Redis Setup
macOS (Homebrew):
Docker:
Linux:
Using Redis Cache
The boilerplate provides a Laravel-like caching interface:
from app.core.cache import cache
# Basic operations
cache().put("key", "value", ttl=3600)
value = cache().get("key")
cache().forget("key")
# Cache-aside pattern (recommended)
user = cache().remember(
f"user:{user_id}",
ttl=300,
callback=lambda: User.get(db, id=user_id)
)
# Advanced operations
cache().increment("counter")
cache().forever("key", "value")
tagged = cache().tags("users")
See Redis Usage Guide for comprehensive examples.
Background Tasks (Celery)
Start Celery Worker:
# Development (with auto-reload)
celery -A app.core.celery_app worker --loglevel=info --reload
# Production
celery -A app.core.celery_app worker --loglevel=info
Monitor with Flower:
Using Tasks:
from app.jobs.tasks import send_welcome_email
# Queue a background task
send_welcome_email.delay(user.id)
Task Scheduling
The boilerplate provides a Laravel-like task scheduler:
from app.core.scheduler import schedule
# Define tasks in app/console/kernel.py
def schedule_tasks():
# Run every minute
schedule().job(cleanup_task).every_minute()
# Run daily at specific time
schedule().job(send_report).daily_at('09:00')
# Run hourly
schedule().job(process_queue).hourly()
# Run weekly
schedule().job(backup).weekly_on('sunday', '02:00')
Run the scheduler:
List scheduled tasks:
See Task Scheduling Guide for comprehensive examples.
File Storage Usage
The boilerplate provides a Laravel-like Storage facade:
from app.core.storage import storage
# Store a file (private - in storage/app)
storage().put('path/to/file.txt', 'content')
# Store a public file (accessible via URL)
storage('public').put('images/logo.png', image_content)
# Accessible at: http://localhost:8000/storage/images/logo.png
# Get file content
content = storage().get('path/to/file.txt')
# Check if file exists
if storage().exists('path/to/file.txt'):
print("File exists")
# Delete a file
storage().delete('path/to/file.txt')
# Get file URL
url = storage().url('path/to/file.txt')
# Use different disk
storage('s3').put('file.txt', 'content')
Public vs Private Storage: - Private (storage/app): Files NOT publicly accessible - use for sensitive data - Public (public/storage): Files publicly accessible via /storage/ URL
See File Storage Guide for comprehensive examples.
Running Tests
Documentation
- Security Guide - Security best practices and features
- Redis Usage Guide - Caching and message queue
- Task Scheduling Guide - Scheduled task management
- Broadcasting Guide - Real-time event broadcasting
- HTTP Client Guide - HTTP client for making requests
- File Storage Guide - File storage system
- Environment Variables - Complete configuration guide
- Development Guide - Development workflow and best practices
Key Features Explained
Database Support
- PostgreSQL & MySQL: Switch databases via configuration - same ORM, same code
- Alembic Migrations: Version-controlled database schema changes
- Connection Pooling: Optimized database connections
Redis Caching
- Laravel-like API: Familiar
cache().get(),cache().put(),cache().remember()methods - Automatic Serialization: JSON and pickle support
- Tagged Cache: Group related cache keys
- TTL Support: Automatic expiration
Message Queue
- Celery Integration: Background task processing
- Redis Backend: Fast and reliable message broker
- Task Monitoring: Flower dashboard included
- Retry Logic: Built-in task retry support
Task Scheduling
- Laravel-like API: Familiar
schedule().job()syntax - Multiple Frequencies: Every minute, hourly, daily, weekly, monthly, etc.
- Task Types: Commands, jobs, and shell commands
- Advanced Features: Timezone support, overlap prevention, conditional execution
Real-time Broadcasting
- Laravel-like API: Familiar
broadcast().event()syntax - Multiple Drivers: Redis, Pusher, Ably, Log, Null
- Channel Types: Public, Private, Presence channels
- WebSocket Support: Real-time bidirectional communication
- Channel Authorization: Secure access control
HTTP Client
- Laravel-like API: Familiar
http().get(),http().post()syntax - Fluent Interface: Chain methods for easy configuration
- Authentication: Basic auth, Bearer tokens
- Retry Logic: Automatic retries on failure
- Middleware: Custom request/response processing
- Concurrent Requests: Pool and batch multiple requests
- Testing Support: Fake responses and request recording
File Storage
- Laravel-like API: Familiar
storage().put(),storage().get()methods - Multiple Drivers: Local, S3, FTP, SFTP support
- Easy Switching: Change driver via configuration
- Unified Interface: Same API for all storage backends
Security
- JWT Authentication: Secure token-based auth with timezone-aware tokens
- Password Hashing: bcrypt password encryption with strength requirements
- Authorization: Policy and Gate-based access control
- CORS Support: Configurable cross-origin requests (validated in production)
- Rate Limiting: Built-in request throttling with Redis support
- Security Headers: X-Frame-Options, CSP, HSTS, and more
- Path Traversal Protection: Secure file operations with validation
- File Upload Security: Type, size, and content validation
- Command Injection Prevention: Secure command execution in scheduler
- Secure Error Handling: No information disclosure in production
- Request ID Tracking: Unique IDs for all requests
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.