FASTAPI Framework Development
By Himanshu Shekhar | 04 Feb 2022 | (0 Reviews)
Suggest Improvement on FastAPI Framework Development β Click here
Python & FastAPI Foundations β Deep Dive
FastAPI is a modern, high-performance web framework for building APIs with Python based on standard Python type hints. In this comprehensive module from NotesTime.in, you'll gain deep understanding of FastAPI internals, Python async execution model, ASGI architecture, and production-ready setup. This foundation is crucial for professional FastAPI development.
1.1 What is FastAPI & Why It's High Performance
FastAPI is a modern web framework for building APIs with Python 3.7+ based on standard Python type hints. Created by SebastiΓ‘n RamΓrez in 2018, it's designed to be fast, intuitive, and production-ready.
Key Features:
- β‘ High Performance: On par with Node.js and Go (thanks to Starlette and Pydantic)
- π Type Hints: Leverages Python type hints for automatic validation and serialization
- π Automatic Documentation: Interactive API docs (Swagger UI, ReDoc) out of the box
- π Validation: Request/response validation using Pydantic models
- π§© Dependency Injection: Powerful DI system for clean, testable code
- π Async Support: Native async/await for high concurrency
- π Security: Built-in support for OAuth2, JWT, HTTP Basic Auth
Performance Benchmarks:
| Framework | Requests/sec | Technology |
|---|---|---|
| FastAPI | ~70,000 | Python/ASGI |
| Node.js (Express) | ~65,000 | JavaScript |
| Go (Gin) | ~95,000 | Go |
| Flask | ~8,000 | Python/WSGI |
1.2 Python Execution Model & Async Basics
Python Execution Model:
Python code is compiled to bytecode, then executed by the Python Virtual Machine (PVM).
Synchronous vs Asynchronous:
- Synchronous (Blocking): Operations execute sequentially, blocking until complete
- Asynchronous (Non-blocking): Operations can run concurrently using an event loop
Async/Await Keywords:
# Synchronous function
def get_data():
return fetch_from_database() # Blocks until complete
# Asynchronous function
async def get_data_async():
data = await fetch_from_database_async() # Non-blocking
return data
Event Loop Explained:
The event loop continuously checks for I/O events and executes coroutines when ready:
- Register coroutines with event loop
- When await is encountered, control returns to event loop
- Event loop handles other tasks while waiting
- When I/O completes, coroutine resumes
1.3 ASGI vs WSGI (FastAPI vs Django/Flask)
WSGI (Web Server Gateway Interface):
Standard for Python web apps (PEP 3333) - synchronous only, one request at a time per worker.
ASGI (Asynchronous Server Gateway Interface):
Successor to WSGI supporting async operations, WebSockets, HTTP/2 (specified in ASGI specification).
| Feature | WSGI | ASGI |
|---|---|---|
| Protocol Support | HTTP only | HTTP, HTTP/2, WebSockets, gRPC |
| Concurrency | Process/thread based | Event-driven, single-threaded async |
| Long-lived connections | Not suitable | Perfect for WebSockets, SSE |
| Examples | Flask, Django (traditional) | FastAPI, Starlette, Django (ASGI mode) |
| Performance | Good for simple apps | Excellent for high concurrency |
1.4 FastAPI Project Structure (App, Routers, Core)
A professional FastAPI project follows clean architecture principles:
my_fastapi_project/
βββ app/
β βββ __init__.py
β βββ main.py # Application entry point
β βββ core/
β β βββ __init__.py
β β βββ config.py # Pydantic settings
β β βββ security.py # Auth, JWT, password hashing
β β βββ database.py # DB connection, session
β β βββ dependencies.py # Global dependencies
β βββ api/
β β βββ __init__.py
β β βββ v1/
β β β βββ __init__.py
β β β βββ routes/
β β β β βββ users.py
β β β β βββ items.py
β β β β βββ auth.py
β β β βββ endpoints/
β β βββ deps.py # API-specific dependencies
β βββ models/
β β βββ __init__.py
β β βββ user.py # SQLAlchemy models
β β βββ item.py
β βββ schemas/
β β βββ __init__.py
β β βββ user.py # Pydantic schemas
β β βββ item.py
β βββ services/
β β βββ __init__.py
β β βββ user_service.py # Business logic
β β βββ item_service.py
β βββ utils/
β β βββ __init__.py
β β βββ helpers.py
β βββ static/ # Static files
βββ tests/
β βββ __init__.py
β βββ conftest.py
β βββ test_api/
β βββ test_services/
βββ alembic/ # Database migrations
βββ .env # Environment variables
βββ .env.example # Example env vars
βββ requirements.txt
βββ requirements-dev.txt
βββ Dockerfile
βββ docker-compose.yml
βββ README.md
1.5 FastAPI Request Lifecycle
Understanding how FastAPI processes a request is crucial for debugging and optimization:
Complete Request Flow:
- Client Request β HTTP request sent to server
- ASGI Server (Uvicorn) β Receives request, creates ASGI scope
- ASGI Application (FastAPI) β Receives scope, receive, send
- Middleware Stack (TopβBottom) β Each middleware processes request
- Route Matching β FastAPI matches path to path operation
- Dependency Resolution β All dependencies resolved (may include sub-dependencies)
- Parameter Extraction β Extract path, query, body, headers
- Validation β Validate data against Pydantic models
- Path Operation Function β Execute endpoint logic
- Response Preparation β Convert return value to response
- Response Validation β Validate response against response_model
- Middleware Stack (BottomβTop) β Each middleware processes response
- ASGI Response β Send response back to client
1.6 Dependency Injection System (Depends Deep Dive)
FastAPI's dependency injection system is one of its most powerful features:
What is Dependency Injection?
Design pattern where objects receive their dependencies from an external source rather than creating them internally.
Basic Dependency:
from fastapi import Depends, FastAPI, Query
app = FastAPI()
# Dependency function
def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
# Using the dependency
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
Class-based Dependencies:
from fastapi import Depends
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends()):
return commons
Nested Dependencies:
from fastapi import Depends, HTTPException, status
from typing import Annotated
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
user = fake_decode_token(token)
if not user:
raise HTTPException(status_code=401)
return user
async def get_current_active_user(
current_user: Annotated[User, Depends(get_current_user)]
):
if current_user.disabled:
raise HTTPException(status_code=400)
return current_user
@app.get("/users/me")
async def read_users_me(
current_user: Annotated[User, Depends(get_current_active_user)]
):
return current_user
1.7 Installing FastAPI (pip, uvicorn, poetry)
Using pip (Traditional):
# Core installation
pip install fastapi
# ASGI server
pip install "uvicorn[standard]"
# Optional dependencies
pip install python-multipart # For form data
pip install jinja2 # For templates
pip install python-jose[cryptography] # For JWT
pip install passlib[bcrypt] # For password hashing
pip install aiofiles # For async file operations
# Development dependencies
pip install pytest # Testing
pip install httpx # Async HTTP client for testing
pip install black # Code formatting
pip install ruff # Linting
Using requirements.txt:
# requirements.txt
fastapi==0.104.1
uvicorn[standard]==0.24.0
python-multipart==0.0.6
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
pydantic-settings==2.0.3
python-dotenv==1.0.0
# Install with: pip install -r requirements.txt
Using Poetry (Modern):
# Install poetry
curl -sSL https://install.python-poetry.org | python3
# Create new project
poetry new my-fastapi-project
cd my-fastapi-project
# Add dependencies
poetry add fastapi uvicorn[standard] python-multipart
poetry add --dev pytest pytest-asyncio httpx
# Activate environment
poetry shell
Using pipenv:
pip install pipenv
pipenv install fastapi uvicorn[standard]
pipenv install --dev pytest
pipenv shell
1.8 Environment Configuration (.env, pydantic-settings)
FastAPI uses Pydantic Settings for type-safe environment configuration:
.env file:
# .env (never commit to git)
APP_NAME="My FastAPI App"
APP_VERSION="1.0.0"
DEBUG=True
SECRET_KEY="your-secret-key-here"
DATABASE_URL="postgresql://user:pass@localhost/dbname"
REDIS_URL="redis://localhost:6379/0"
JWT_SECRET_KEY="jwt-secret-key"
JWT_ALGORITHM="HS256"
JWT_EXPIRATION_MINUTES=30
CORS_ORIGINS=["http://localhost:3000", "https://example.com"]
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT=587
EMAIL_USER="user@gmail.com"
EMAIL_PASSWORD="app-password"
Pydantic Settings (config.py):
from pydantic_settings import BaseSettings
from pydantic import ConfigDict, Field
from typing import List
class Settings(BaseSettings):
# App settings
app_name: str = "FastAPI App"
app_version: str = "1.0.0"
debug: bool = False
secret_key: str
# Database
database_url: str
# Redis
redis_url: str = "redis://localhost:6379/0"
# JWT
jwt_secret_key: str
jwt_algorithm: str = "HS256"
jwt_expiration_minutes: int = 30
# CORS
cors_origins: List[str] = ["http://localhost:3000"]
# Email
email_host: str | None = None
email_port: int = 587
email_user: str | None = None
email_password: str | None = None
model_config = ConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False
)
settings = Settings() # Automatically loads from .env
Using settings in main.py:
from fastapi import FastAPI
from app.core.config import settings
app = FastAPI(
title=settings.app_name,
version=settings.app_version,
debug=settings.debug
)
@app.get("/info")
async def info():
return {
"app_name": settings.app_name,
"version": settings.app_version,
"debug": settings.debug
}
1.9 Uvicorn, Gunicorn & Server Concepts
Uvicorn (ASGI Server):
A lightning-fast ASGI server implementation, using uvloop and httptools.
# Basic usage
uvicorn main:app
# With hot reload (development)
uvicorn main:app --reload
# Custom host and port
uvicorn main:app --host 0.0.0.0 --port 8000
# With SSL
uvicorn main:app --ssl-keyfile=./key.pem --ssl-certfile=./cert.pem
# With log level
uvicorn main:app --log-level debug
# Production settings
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4 --limit-max-requests 1000
Gunicorn + Uvicorn (Production):
Gunicorn acts as a process manager with Uvicorn workers:
# Install
pip install gunicorn uvicorn
# Run with Uvicorn workers
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
# With more options
gunicorn main:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
--timeout 120 \
--max-requests 1000 \
--max-requests-jitter 100 \
--access-logfile - \
--error-logfile -
Comparison of ASGI Servers:
| Server | Best For | Features |
|---|---|---|
| Uvicorn | Development, simple production | Fast, lightweight, HTTP/1.1 and WebSocket |
| Hypercorn | HTTP/2, HTTP/3 support | HTTP/2, HTTP/3, Trio support |
| Daphne | Django Channels | HTTP/1.1, WebSocket support |
1.10 Starlette Internals (FastAPI Base)
FastAPI is built on top of Starlette, inheriting its performance and features:
What FastAPI inherits from Starlette:
- π WebSocket support
- π‘ GraphQL support
- π Background tasks
- π£οΈ Routing system
- π§© Middleware framework
- π Static files serving
- π§ͺ Test client
- π§ Request/Response objects
What FastAPI adds:
- π Data validation (Pydantic)
- π Dependency injection system
- π Automatic API docs (Swagger, ReDoc)
- π― Type hints integration
- β Request/response validation
# Starlette example
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
async def homepage(request):
return JSONResponse({'hello': 'world'})
routes = [
Route('/', homepage),
]
app = Starlette(routes=routes)
# FastAPI equivalent (with validation)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/")
async def create_item(item: Item):
return {"item": item}
1.11 ASGI Scope, Receive & Send
ASGI applications are async callables that receive scope, receive, and send:
ASGI Specification:
async def app(scope, receive, send):
# scope: Connection information (type, path, headers)
# receive: Async function to receive messages
# send: Async function to send messages
pass
HTTP Scope Example:
{
"type": "http",
"http_version": "1.1",
"method": "GET",
"path": "/items/1",
"query_string": b"",
"headers": [
(b"host", b"localhost:8000"),
(b"user-agent", b"curl/7.68.0"),
(b"accept", b"*/*")
]
}
WebSocket Scope:
{
"type": "websocket",
"path": "/ws/chat",
"headers": [...],
"subprotocols": ["chat"]
}
Simple ASGI App:
async def simple_app(scope, receive, send):
if scope["type"] == "http":
await send({
"type": "http.response.start",
"status": 200,
"headers": [
[b"content-type", b"text/plain"],
]
})
await send({
"type": "http.response.body",
"body": b"Hello, ASGI!",
})
1.12 Middleware Internals (Custom Middleware)
Middleware in FastAPI processes requests before they reach endpoints and responses before they're sent:
Base Middleware Pattern:
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
import time
class TimingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# Pre-processing
start_time = time.time()
# Call next middleware/endpoint
response = await call_next(request)
# Post-processing
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
# Add middleware to app
app = FastAPI()
app.add_middleware(TimingMiddleware)
Request ID Middleware:
import uuid
from starlette.middleware.base import BaseHTTPMiddleware
class RequestIDMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
request_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
request.state.request_id = request_id
response = await call_next(request)
response.headers["X-Request-ID"] = request_id
return response
Authentication Middleware:
from fastapi import HTTPException
import jwt
class AuthMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# Skip auth for public paths
if request.url.path in ["/", "/docs", "/openapi.json"]:
return await call_next(request)
# Check authorization header
auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
raise HTTPException(status_code=401)
try:
token = auth_header.split(" ")[1]
payload = jwt.decode(token, "secret", algorithms=["HS256"])
request.state.user = payload
except:
raise HTTPException(status_code=401)
return await call_next(request)
Middleware Order:
app.add_middleware(TimingMiddleware) # Executes first
app.add_middleware(RequestIDMiddleware) # Executes second
app.add_middleware(AuthMiddleware) # Executes third
# Request: Timing β RequestID β Auth β Endpoint
# Response: Endpoint β Auth β RequestID β Timing
1.13 FastAPI Full Setup (Dev β Production)
Development Setup:
# 1. Create project directory
mkdir my-fastapi-app && cd my-fastapi-app
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install fastapi uvicorn[standard] python-multipart
# 4. Create main.py
# (basic FastAPI app code)
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"message": "Working β
"}
# 5. Run development server
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000 # On Windows
OR
python -m uvicorn main:app --reload # On Windows
Production Setup:
# 1. Install production dependencies
pip install gunicorn httptools uvloop
# 2. Create .env file with production settings
# (database URLs, secrets, etc.)
# 3. Run with Gunicorn + Uvicorn workers
gunicorn main:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
--timeout 120 \
--access-logfile - \
--error-logfile -
# 4. Or use process manager like Supervisor
sudo apt-get install supervisor
# Configure /etc/supervisor/conf.d/fastapi.conf
Production Checklist:
- β Use environment variables for secrets
- β Enable HTTPS (SSL/TLS)
- β Set up proper logging
- β Configure CORS properly
- β Use connection pooling for databases
- β Set up monitoring (Prometheus, Grafana)
- β Implement rate limiting
- β Use CDN for static files
1.14 Virtual Environment & Dependency Management
Python venv:
# Create virtual environment
python -m venv venv
# Activate (Linux/Mac)
source venv/bin/activate
# Activate (Windows)
venv\Scripts\activate
# Deactivate
deactivate
# Export dependencies
pip freeze > requirements.txt
# Install from requirements
pip install -r requirements.txt
Pipenv:
# Install
pip install pipenv
# Create environment and install packages
pipenv install fastapi uvicorn[standard]
# Install dev dependencies
pipenv install --dev pytest black
# Activate environment
pipenv shell
# Generate requirements.txt
pipenv requirements > requirements.txt
Poetry:
# Create new project
poetry new myproject
cd myproject
# Add dependencies
poetry add fastapi uvicorn[standard]
poetry add --dev pytest pytest-asyncio httpx
# Activate environment
poetry shell
# Export requirements.txt
poetry export -f requirements.txt --output requirements.txt
1.15 Project Structure (Clean Architecture Setup)
Clean Architecture separates concerns into layers:
clean_fastapi_project/
βββ src/
β βββ domain/ # Enterprise-wide business rules
β β βββ entities/ # Business objects
β β β βββ user.py
β β β βββ product.py
β β βββ value_objects/ # Immutable objects
β β βββ interfaces/ # Repository interfaces
β βββ application/ # Application business rules
β β βββ use_cases/ # Business use cases
β β β βββ create_user.py
β β β βββ get_product.py
β β βββ dto/ # Data Transfer Objects
β β βββ services/ # Application services
β βββ infrastructure/ # Frameworks & drivers
β β βββ database/
β β β βββ models/ # SQLAlchemy models
β β β βββ repositories/ # Repository implementations
β β β βββ migrations/
β β βββ external_apis/ # Third-party API clients
β β βββ cache/ # Redis clients
β βββ api/ # Interface adapters
β β βββ routes/ # FastAPI routes
β β βββ middlewares/ # Custom middleware
β β βββ dependencies/ # Dependency injection
β β βββ schemas/ # Pydantic schemas
β βββ core/ # Core configuration
β βββ config.py
β βββ security.py
β βββ exceptions.py
βββ tests/ # Test modules
βββ .env
βββ pyproject.toml
βββ README.md
1.16 Running FastAPI (Uvicorn & Dev Server)
Basic Commands:
# Run with default settings
uvicorn main:app
# With hot reload (development)
uvicorn main:app --reload
# Custom host and port
uvicorn main:app --host 0.0.0.0 --port 8080
# With SSL
uvicorn main:app --ssl-keyfile=./key.pem --ssl-certfile=./cert.pem
# With log level
uvicorn main:app --log-level debug --reload
# With factory pattern
uvicorn main:create_app --factory --reload
# With environment variables
uvicorn main:app --env-file .env.local
Python Script Method:
# run.py
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info",
workers=1
)
Using with Docker:
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
1.17 Environment Variables & Config Management
Multiple Environment Support:
# config.py
from pydantic_settings import BaseSettings
from functools import lru_cache
class Settings(BaseSettings):
environment: str = "development"
database_url: str
redis_url: str
secret_key: str
class Config:
env_file = ".env"
class DevelopmentSettings(Settings):
debug: bool = True
reload: bool = True
class ProductionSettings(Settings):
debug: bool = False
reload: bool = False
@lru_cache()
def get_settings():
env = os.getenv("ENVIRONMENT", "development")
if env == "production":
return ProductionSettings()
return DevelopmentSettings()
settings = get_settings()
.env files structure:
# .env.development
DATABASE_URL=postgresql://localhost/dev_db
REDIS_URL=redis://localhost:6379/0
DEBUG=True
SECRET_KEY=dev-secret-key
# .env.production
DATABASE_URL=postgresql://prod:pass@prod-db/prod_db
REDIS_URL=redis://redis-cluster:6379/0
DEBUG=False
SECRET_KEY=${PROD_SECRET_KEY}
1.18 Production Setup (Gunicorn + Uvicorn Workers)
Gunicorn Configuration File:
# gunicorn.conf.py
import multiprocessing
bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "uvicorn.workers.UvicornWorker"
timeout = 120
keepalive = 5
max_requests = 1000
max_requests_jitter = 100
# Logging
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
loglevel = "info"
# SSL (if terminating at Gunicorn)
# keyfile = "/etc/ssl/private/key.pem"
# certfile = "/etc/ssl/certs/cert.pem"
# Preload app
preload_app = True
def on_starting(server):
"""Log when server starts"""
server.log.info("Starting FastAPI application")
def on_exit(server):
"""Log when server exits"""
server.log.info("Stopping FastAPI application")
Running with configuration:
# Using config file
gunicorn -c gunicorn.conf.py main:app
# Or command line
gunicorn main:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind unix:/tmp/gunicorn.sock \
--daemon \
--pid /var/run/gunicorn.pid
1.19 Dockerizing FastAPI Application
Multi-stage Dockerfile:
# Dockerfile
# Build stage
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Runtime stage
FROM python:3.11-slim
WORKDIR /app
# Create non-root user
RUN useradd -m -u 1000 fastapi && \
chown -R fastapi:fastapi /app
# Copy Python dependencies
COPY --from=builder /root/.local /home/fastapi/.local
ENV PATH=/home/fastapi/.local/bin:$PATH
# Copy application
COPY --chown=fastapi:fastapi . .
USER fastapi
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Docker Compose:
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/fastapi
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
volumes:
- ./:/app
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
db:
image: postgres:15
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=fastapi
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Build and run:
# Build image
docker build -t fastapi-app .
# Run container
docker run -p 8000:8000 fastapi-app
# With docker-compose
docker-compose up -d
# Scale workers
docker-compose up -d --scale api=3
1.20 Nginx Reverse Proxy Setup
Nginx Configuration:
# /etc/nginx/sites-available/fastapi
upstream fastapi_backend {
least_conn; # Load balancing strategy
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}
server {
listen 80;
server_name api.example.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL certificates
ssl_certificate /etc/ssl/certs/api.example.com.crt;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
# Security headers
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Logs
access_log /var/log/nginx/fastapi_access.log;
error_log /var/log/nginx/fastapi_error.log;
# Large file uploads
client_max_body_size 100M;
location / {
proxy_pass http://fastapi_backend;
proxy_http_version 1.1;
# Headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Static files (if any)
location /static {
alias /var/www/fastapi/static;
expires 30d;
}
}
Enable and test:
# Enable site
ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
# Test configuration
nginx -t
# Reload Nginx
systemctl reload nginx
# Check logs
tail -f /var/log/nginx/fastapi_error.log
1.21 Deployment (AWS / VPS / Cloud Platforms)
AWS EC2 Deployment:
# 1. Launch EC2 instance (Ubuntu 22.04)
# 2. SSH into instance
ssh -i key.pem ubuntu@ec2-xx-xx-xx-xx.compute-1.amazonaws.com
# 3. Install dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-venv nginx -y
# 4. Clone repository
git clone https://github.com/yourusername/fastapi-app.git
cd fastapi-app
# 5. Setup environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# 6. Create .env file
nano .env
# 7. Setup systemd service
sudo nano /etc/systemd/system/fastapi.service
Systemd Service File:
[Unit]
Description=FastAPI Application
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/fastapi-app
Environment="PATH=/home/ubuntu/fastapi-app/venv/bin"
ExecStart=/home/ubuntu/fastapi-app/venv/bin/gunicorn -c gunicorn.conf.py main:app
Restart=always
[Install]
WantedBy=multi-user.target
Deploy with GitHub Actions:
# .github/workflows/deploy.yml
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to EC2
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/fastapi-app
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart fastapi
sudo systemctl status fastapi
Alternative Platforms:
- Heroku: Procfile with "web: uvicorn main:app --host 0.0.0.0 --port $PORT"
- DigitalOcean App Platform: Connect GitHub repo, auto-deploy
- Railway: Automatic deployments with GitHub integration
- Fly.io: Global deployment with fly.toml configuration
- Google Cloud Run: Container-based serverless deployment
- Azure App Service: Configure startup command
π Module 01 : Python & FastAPI Foundations (Deep) Successfully Completed
You have successfully completed this module of FastAPI Framework Development.
Keep building your expertise step by step β Learn Next Module β
Project Deployment - AWS, GCP, Azure & More
Complete deployment guide for hosting FastAPI applications on major cloud platforms. This comprehensive module covers everything from basic VPS setup to advanced serverless and Kubernetes deployments with production-ready configurations for EduHack-Lab and similar FastAPI projects.
17.1 AWS Deployment (EC2, ECS, Lambda, Elastic Beanstalk)
π What You'll Learn in This Section
- β Deploy any FastAPI project to AWS EC2 (Free Tier eligible)
- β Configure production-ready environment with Nginx + Gunicorn
- β Set up automatic service restart on server reboot
- β Alternative deployment methods (Elastic Beanstalk, Lambda, ECS)
π° Understanding AWS Free Tier
- π₯οΈ 750 hours/month of t2.micro EC2 instance (enough for 24/7 operation)
- πΎ 30 GB of EBS storage
- π 1 million API requests via API Gateway
- ποΈ 20 GB of RDS database storage (optional)
- β° Valid for 12 months from account creation
π Prerequisites - What You Need Before Starting
β Account & Access
- AWS account (signup: aws.amazon.com)
- Credit card for verification (no charges for free tier)
- Phone number for verification
β Your FastAPI Project
- Working FastAPI project on local machine
- requirements.txt file with all dependencies
- GitHub repository (recommended for easy transfer)
- Basic knowledge of terminal/command line
π Step-by-Step Deployment Guide for Any FastAPI Project
Step 1: Create an AWS Account (If you don't have one)
1. Go to https://aws.amazon.com
2. Click "Create an AWS Account"
3. Enter your email address and account name
4. Choose "Personal" account type
5. Enter payment information (no charges for free tier usage)
6. Verify your phone number
7. Choose "Basic" support plan (free)
8. Wait for account activation (usually 5-10 minutes)
Step 2: Launch Your EC2 Instance (Virtual Server)
π Step-by-Step Console Instructions:
1. Login to AWS Console (console.aws.amazon.com)
2. Search for "EC2" in top search bar and click
3. Click the orange "Launch Instance" button
4. Fill in these settings:
πΉ NAME YOUR INSTANCE:
- Name: "my-fastapi-app" (or any name you prefer)
πΉ CHOOSE OS IMAGE:
- Click "Ubuntu"
- Select "Ubuntu 22.04 LTS (HVM)" - Free tier eligible
πΉ CHOOSE INSTANCE TYPE:
- Select "t2.micro" (free tier eligible)
πΉ KEY PAIR (LOGIN):
- Click "Create new key pair"
- Key pair name: "fastapi-key"
- Key pair type: "RSA"
- Private key format: ".pem"
- Click "Create key pair" (file downloads automatically)
- β οΈ SAVE THIS FILE SAFELY! You'll need it to connect
πΉ NETWORK SETTINGS (Security Group - Firewall):
- Click "Edit"
- Add these rules one by one:
Rule 1 (SSH - to connect to server):
- Type: SSH
- Source: My IP (auto-detects your IP)
- This allows YOU to connect securely
Rule 2 (HTTP - for web access):
- Click "Add security group rule"
- Type: HTTP
- Source: Anywhere-IPv4 (0.0.0.0/0)
- This allows everyone to visit your website
Rule 3 (Custom for FastAPI testing):
- Click "Add security group rule"
- Type: Custom TCP
- Port: 8000
- Source: Anywhere-IPv4 (0.0.0.0/0)
- This allows testing on port 8000
πΉ STORAGE:
- Keep default: 20 GB gp2 (free tier includes 30 GB)
6. Click "Launch Instance" button
7. Wait 1-2 minutes for instance to start
8. Note down the "Public IPv4 address" (e.g., 54.123.45.67)
Step 3: Connect to Your EC2 Instance
π For Windows Users:
Option A: Using PowerShell (Recommended)
1. Open PowerShell (Search in Start Menu)
2. Navigate to where you saved your .pem file:
cd C:\Users\YourName\Downloads
3. Connect using this command:
ssh -i "fastapi-key.pem" ubuntu@YOUR_SERVER_IP
(Replace YOUR_SERVER_IP with actual IP from Step 2)
Option B: Using Git Bash
1. Install Git for Windows (git-scm.com)
2. Open Git Bash
3. Navigate to .pem folder:
cd /c/Users/YourName/Downloads
4. Run:
ssh -i "fastapi-key.pem" ubuntu@YOUR_SERVER_IP
π For Mac/Linux Users:
1. Open Terminal
2. Navigate to .pem file location:
cd ~/Downloads
3. Fix permissions (required):
chmod 400 fastapi-key.pem
4. Connect:
ssh -i "fastapi-key.pem" ubuntu@YOUR_SERVER_IP
β
Success! You should see: ubuntu@ip-xxx-xxx:~$
Step 4: Install Required Software on Server
Once connected to your server, run these commands one by one:
# 1. Update system packages (always do this first)
sudo apt update && sudo apt upgrade -y
# 2. Install Python and essential tools
sudo apt install -y python3-pip python3-venv git nginx curl
# 3. Verify installations
python3 --version # Should show Python 3.10+
pip3 --version # Should show pip version
git --version # Should show git version
nginx -v # Should show nginx version
# 4. Install production server (Gunicorn)
pip3 install gunicorn
Step 5: Upload Your FastAPI Code to Server
π€ On YOUR Local Machine (First Time Setup):
# Navigate to your FastAPI project
cd your-fastapi-project
# Initialize Git repository
git init
# Add all files
git add .
git add .gitignore # If you have one
# Commit the files
git commit -m "Initial FastAPI application commit"
# Add remote repository (replace with your GitHub URL)
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git
# Push to GitHub
git push -u origin main
# OR if using master branch:
git push -u origin master
π₯ On Your EC2 Server (Clone the Repository):
# Clone public repository
git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO
# For private repository (using token):
git clone https://YOUR_USERNAME:YOUR_GITHUB_TOKEN@github.com/YOUR_USERNAME/YOUR_REPO.git
# For private repository (using SSH):
git clone git@github.com:YOUR_USERNAME/YOUR_REPO.git
π Update Existing Code (After Changes):
# On your local machine:
git add .
git commit -m "Describe your changes"
git push
# On EC2 server:
git pull
# On YOUR LOCAL machine (open a new terminal):
# Upload entire project folder
scp -i "fastapi-key.pem" -r ./your-fastapi-project ubuntu@YOUR_SERVER_IP:~/
# Example:
scp -i "fastapi-key.pem" -r ./my-fastapi-app ubuntu@54.123.45.67:~/
# Upload specific files only
scp -i "fastapi-key.pem" main.py requirements.txt ubuntu@YOUR_SERVER_IP:~/my-fastapi-app/
# Upload with compression (faster for large files)
scp -i "fastapi-key.pem" -C -r ./your-fastapi-project ubuntu@YOUR_SERVER_IP:~/
# On your EC2 server, navigate to the project:
cd ~/your-fastapi-project
# On YOUR LOCAL machine:
# Sync entire project (only uploads changed files)
rsync -avz -e "ssh -i fastapi-key.pem" ./your-fastapi-project/ ubuntu@YOUR_SERVER_IP:~/your-fastapi-project/
# Exclude specific folders (like venv, __pycache__, .git)
rsync -avz --exclude 'venv' --exclude '__pycache__' --exclude '.git' \
-e "ssh -i fastapi-key.pem" ./your-fastapi-project/ ubuntu@YOUR_SERVER_IP:~/your-fastapi-project/
# Dry run (see what would be transferred without actually doing it)
rsync -avz --dry-run -e "ssh -i fastapi-key.pem" ./your-fastapi-project/ ubuntu@YOUR_SERVER_IP:~/your-fastapi-project/
π FileZilla Setup:
- Download and install FileZilla
- Open FileZilla β File β Site Manager
- Create New Site β Protocol: SFTP (SSH File Transfer Protocol)
- Host:
YOUR_SERVER_IP - Port:
22 - Logon Type: Key File
- User:
ubuntu(orec2-userfor Amazon Linux) - Key File: Browse and select your
fastapi-key.pem - Click "Connect"
π WinSCP Setup:
- Download and install WinSCP
- Open WinSCP β New Session
- File Protocol: SFTP
- Host name:
YOUR_SERVER_IP - Port number:
22 - User name:
ubuntu - Private key file: Browse and select your
fastapi-key.pem(WinSCP will convert it to .ppk) - Click "Login"
# Step 1: Upload to S3 from your local machine
aws s3 cp ./your-fastapi-project s3://your-bucket-name/your-fastapi-project --recursive
# Step 2: On EC2 server, download from S3
aws s3 cp s3://your-bucket-name/your-fastapi-project ./your-fastapi-project --recursive
# Step 3: If you don't have AWS CLI on EC2, install it:
sudo apt update
sudo apt install awscli -y
aws configure # Add your access keys
π³ Create a Dockerfile:
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
π€ Build and Push to Docker Hub:
# On your local machine:
docker build -t yourusername/fastapi-app:latest .
docker push yourusername/fastapi-app:latest
# On EC2 server:
docker pull yourusername/fastapi-app:latest
docker run -d -p 8000:8000 yourusername/fastapi-app:latest
# On YOUR LOCAL machine (where your code is):
cd your-fastapi-project
python3 -m http.server 8001
# On EC2 server (in a new terminal):
wget http://YOUR_LOCAL_IP:8001/main.py
wget http://YOUR_LOCAL_IP:8001/requirements.txt
# Download each file individually
# Note: Your local machine must be accessible from the internet
# (Use ngrok if behind NAT: https://ngrok.com/)
π Method Comparison
| Method | Best For | Speed | Ease of Use | Version Control |
|---|---|---|---|---|
| Git | Ongoing development, team collaboration | ββββ | ββββ | β Yes |
| SCP | Single file transfer, quick uploads | βββ | βββββ | β No |
| Rsync | Large projects, incremental updates | βββββ | βββ | β No |
| FileZilla/WinSCP | GUI lovers, drag-and-drop | βββ | βββββ | β No |
| AWS S3 | Multiple servers, large files | ββββ | βββ | β No |
| Docker | Containerized deployment, consistency | ββββ | βββ | β Yes |
.env file or any files containing secrets to GitHub! Add them to .gitignore.
Step 6: Set Up Python Virtual Environment & Install Dependencies
# 1. Create virtual environment (isolates your project dependencies)
cd ~/YOUR_PROJECT_NAME
python3 -m venv venv
# 2. Activate virtual environment
source venv/bin/activate
# Your prompt should now show (venv) at the beginning
# 3. Install your project dependencies
pip install -r requirements.txt
# 4. If you don't have requirements.txt, create it:
pip freeze > requirements.txt
# Or install common FastAPI packages directly:
pip install fastapi uvicorn sqlalchemy python-multipart
# 5. Verify installation
pip list # Shows all installed packages
# 6. Test your application (temporary)
uvicorn main:app --host 0.0.0.0 --port 8000
# In your browser, visit: http://YOUR_SERVER_IP:8000
# You should see your API response!
# Press Ctrl+C to stop the test
Step 7: Configure Environment Variables (.env file)
# 1. Create .env file for production settings
nano .env
# 2. Add your configuration (modify as needed):
DATABASE_URL=sqlite:///./production.db
SECRET_KEY=your-super-secret-key-change-this
DEBUG=False
ALLOWED_HOSTS=YOUR_SERVER_IP,yourdomain.com
# 3. Save file: Ctrl+X, then Y, then Enter
# 4. Verify .env file is ignored by git (should be in .gitignore)
echo ".env" >> .gitignore
# 5. Test that your app reads environment variables
python3 -c "import os; from dotenv import load_dotenv; load_dotenv(); print(os.getenv('DEBUG'))"
Step 8: Create Systemd Service (Auto-start on reboot)
This ensures your app starts automatically when the server restarts.
# 1. Create service file
sudo nano /etc/systemd/system/fastapi-app.service
# 2. Paste this configuration (UPDATE paths to match your project):
[Unit]
Description=My FastAPI Application
After=network.target
[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/YOUR_PROJECT_NAME
Environment="PATH=/home/ubuntu/YOUR_PROJECT_NAME/venv/bin"
EnvironmentFile=/home/ubuntu/YOUR_PROJECT_NAME/.env
ExecStart=/home/ubuntu/YOUR_PROJECT_NAME/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
# 3. Save file: Ctrl+X, then Y, then Enter
# 4. Reload systemd to recognize new service
sudo systemctl daemon-reload
# 5. Enable service to start on boot
sudo systemctl enable fastapi-app
# 6. Start the service now
sudo systemctl start fastapi-app
# 7. Check if it's running
sudo systemctl status fastapi-app
# You should see "active (running)" in green
# 8. View logs if needed
sudo journalctl -u fastapi-app -f
Step 9: Set Up Nginx as Reverse Proxy (RECOMMENDED)
Nginx handles web traffic efficiently and adds security.
# 1. Create Nginx configuration
sudo nano /etc/nginx/sites-available/fastapi-app
# 2. Paste this configuration:
server {
listen 80;
server_name YOUR_SERVER_IP;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static {
alias /home/ubuntu/YOUR_PROJECT_NAME/static;
expires 30d;
}
}
# 3. Save file: Ctrl+X, then Y, then Enter
# 4. Enable the site
sudo ln -s /etc/nginx/sites-available/fastapi-app /etc/nginx/sites-enabled/
# 5. Remove default site (optional)
sudo rm /etc/nginx/sites-enabled/default
# 6. Test Nginx configuration
sudo nginx -t
# 7. Restart Nginx
sudo systemctl restart nginx
# 8. Your app is now available at: http://YOUR_SERVER_IP (no :8000 needed!)
Step 10: Set Up SSL/HTTPS (Free with Let's Encrypt)
β οΈ You need a domain name for this step (e.g., yourdomain.com)
# 1. Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# 2. Get SSL certificate (replace with your domain)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 3. Follow the prompts:
# - Enter your email
# - Agree to terms
# - Choose redirect option (recommended)
# 4. Test auto-renewal
sudo certbot renew --dry-run
# 5. Your site is now available at: https://yourdomain.com
π§ Troubleshooting Common Issues
- Check Security Group: Ensure SSH (port 22) has your IP
- Verify instance is running (not stopped)
- Check you're using correct IP address
- Try: ping YOUR_SERVER_IP
- Check service status:
sudo systemctl status fastapi-app - Check Nginx:
sudo systemctl status nginx - Verify Security Group has HTTP (80) and 8000 open
- Check logs:
sudo journalctl -u fastapi-app -f
- On Mac/Linux:
chmod 400 fastapi-key.pem - Ensure you're using the correct username:
ubuntu@ - Verify key pair name matches
- Activate virtual env:
source venv/bin/activate - Install missing package:
pip install package_name - Update requirements.txt:
pip freeze > requirements.txt - Check your main.py has proper app variable named "app"
π Quick Reference - Daily Maintenance Commands
| What to do | Command |
|---|---|
| View app status | sudo systemctl status fastapi-app |
| Restart app | sudo systemctl restart fastapi-app |
| Stop app | sudo systemctl stop fastapi-app |
| View app logs | sudo journalctl -u fastapi-app -f |
| Restart Nginx | sudo systemctl restart nginx |
| Update code from GitHub | git pull origin main && sudo systemctl restart fastapi-app |
| Install new Python package | source venv/bin/activate && pip install package && sudo systemctl restart fastapi-app |
| View server resources | htop (install: sudo apt install htop) |
| Check disk space | df -h |
| Check memory usage | free -h |
π Alternative AWS Deployment Methods
π³ AWS ECS (Docker)
Best for containerized applications. Requires Docker knowledge.
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
π¦ AWS Elastic Beanstalk
Platform as a Service - AWS manages the infrastructure.
# Install EB CLI
pip install awsebcli
# Initialize and deploy
eb init -p python-3.11
eb create my-fastapi-env
eb deploy
β‘ AWS Lambda (Serverless)
Pay-per-request, auto-scaling to zero.
# Install Mangum
pip install mangum
# In main.py
from mangum import Mangum
handler = Mangum(app)
π‘ Cost Saving Tips for Free Tier
- π Stop instances when not in use - EC2 charges continue only for storage
- ποΈ Delete unused EBS volumes - Old volumes cost money
- πΈ Delete old AMIs and snapshots - They accumulate quickly
- π Use CloudFront CDN - Free tier includes 1TB/month data transfer
- π Set up billing alerts - Get notified before exceeding free tier
β Deployment Checklist
- β EC2 instance running and accessible via SSH
- β Security group allows HTTP (80) and HTTPS (443)
- β Python virtual environment created and activated
- β All dependencies installed via pip
- β Environment variables configured (.env file)
- β Systemd service created and enabled
- β Nginx configured as reverse proxy
- β SSL certificate installed (if using domain)
- β Application accessible via browser
- β Logs checked for any errors
AWS Elastic Beanstalk Deployment (Simplified)
# Even easier than EC2 - AWS manages everything for you
# 1. Install EB CLI
pip install awsebcli
# 2. Initialize your project
cd your-fastapi-project
eb init -p python-3.11 my-fastapi-app --region us-east-1
# 3. Create environment and deploy
eb create my-fastapi-env --scale 1 --instance-type t2.micro
# 4. Open in browser
eb open
# 5. Update your code
git add .
git commit -m "update"
eb deploy
# 6. View logs
eb logs
AWS Lambda Serverless Deployment (Mangum)
# Perfect for APIs with variable traffic
# 1. Install Mangum
pip install mangum
# 2. Modify your main.py
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
# Your routes here...
# Lambda handler
handler = Mangum(app)
# 3. Deploy using Serverless Framework
npm install -g serverless
# Create serverless.yml
service: fastapi-lambda
provider:
name: aws
runtime: python3.11
region: us-east-1
functions:
api:
handler: main.handler
events:
- httpApi: '*'
# Deploy
serverless deploy
http://YOUR_SERVER_IP
17.2 Google Cloud Platform (GCP) Deployment
Google Cloud Run - Best for Containerized FastAPI Apps
Cloud Run is a fully managed serverless platform that automatically scales your containerized applications.
Prerequisites
- Google Cloud account with billing enabled (free tier includes 2 million requests/month)
- Google Cloud SDK installed
- Docker installed locally
Deployment Steps
# Install and initialize Google Cloud SDK
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init
# Enable required services
gcloud services enable run.googleapis.com cloudbuild.googleapis.com
# Create Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
EOF
# Build and deploy
PROJECT_ID=$(gcloud config get-value project)
gcloud builds submit --tag gcr.io/$PROJECT_ID/eduhack-lab
# Deploy to Cloud Run
gcloud run deploy eduhack-lab \
--image gcr.io/$PROJECT_ID/eduhack-lab \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--memory 512Mi \
--cpu 1 \
--min-instances 0 \
--max-instances 10
Google Compute Engine (VM) Deployment
Similar to AWS EC2, GCE provides virtual machines with free tier eligibility (e2-micro instance).
# Create VM instance
gcloud compute instances create eduhack-vm \
--zone=us-central1-a \
--machine-type=e2-micro \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--tags=http-server,https-server
# Create firewall rules
gcloud compute firewall-rules create allow-http --allow tcp:80 --source-ranges 0.0.0.0/0
gcloud compute firewall-rules create allow-https --allow tcp:443 --source-ranges 0.0.0.0/0
# SSH into VM
gcloud compute ssh eduhack-vm --zone=us-central1-a
# Follow same setup steps as AWS EC2
Cloud SQL (Managed PostgreSQL)
# Create PostgreSQL instance
gcloud sql instances create eduhack-db \
--database-version=POSTGRES_15 \
--tier=db-f1-micro \
--region=us-central1 \
--storage-size=10GB
# Set password
gcloud sql users set-password postgres --instance=eduhack-db --password=YourPassword123
# Create database
gcloud sql databases create eduhack --instance=eduhack-db
17.3 Microsoft Azure Deployment
Azure App Service - PaaS for FastAPI
Azure App Service provides a fully managed platform for hosting web applications with built-in scaling and load balancing.
Prerequisites
- Azure account with free tier (F1 plan offers 1 hour/day free compute)
- Azure CLI installed
Deployment Steps
# Login to Azure
az login
# Create resource group
az group create --name eduhack-rg --location eastus
# Create App Service plan (Linux)
az appservice plan create \
--name eduhack-plan \
--resource-group eduhack-rg \
--sku F1 \
--is-linux
# Create web app
az webapp create \
--resource-group eduhack-rg \
--plan eduhack-plan \
--name eduhack-lab-app \
--runtime "PYTHON:3.11"
# Configure startup command
az webapp config set \
--resource-group eduhack-rg \
--name eduhack-lab-app \
--startup-file "gunicorn -w 2 -k uvicorn.workers.UvicornWorker app.main:app"
# Deploy from GitHub
az webapp deployment source config \
--name eduhack-lab-app \
--resource-group eduhack-rg \
--repo-url https://github.com/yourusername/EduHack-Lab \
--branch main \
--manual-integration
# Set environment variables
az webapp config appsettings set \
--resource-group eduhack-rg \
--name eduhack-lab-app \
--settings DATABASE_URL="sqlite:///./test.db" DEBUG="False"
Azure Container Instances
# Deploy container directly
az container create \
--resource-group eduhack-rg \
--name eduhack-container \
--image yourdockerhub/eduhack-lab:latest \
--dns-name-label eduhack-lab \
--ports 8000 \
--cpu 1 \
--memory 1.5
17.4 DigitalOcean Deployment (Droplets & App Platform)
DigitalOcean Droplet - Simple VPS Hosting
DigitalOcean offers simple, predictable pricing starting at $4/month for basic droplets.
Quick Deployment with One-Click Apps
# Install doctl CLI
snap install doctl
doctl auth init
# Create droplet
doctl compute droplet create eduhack-droplet \
--region nyc3 \
--image ubuntu-22-04-x64 \
--size s-1vcpu-1gb \
--ssh-keys
# SSH into droplet
ssh root@droplet-ip
# Use the same setup script as AWS EC2
DigitalOcean App Platform (PaaS)
# app.yaml
name: eduhack-lab
region: nyc
services:
- name: api
github:
repo: yourusername/EduHack-Lab
branch: main
build_command: pip install -r requirements.txt
run_command: gunicorn -w 2 -k uvicorn.workers.UvicornWorker app.main:app
http_port: 8000
instance_count: 1
instance_size_slug: basic-xxs
# Deploy
doctl apps create --spec app.yaml
17.5 Heroku Deployment (Legacy & Alternatives)
Modern Heroku Alternatives
Railway.app - Best Free Tier Alternative
# Install Railway CLI
npm install -g @railway/cli
# Login and deploy
railway login
railway init
railway up
# Add PostgreSQL database
railway add -p postgresql
Render.com - Excellent Free Tier
# render.yaml
services:
- type: web
name: eduhack-lab
runtime: python
repo: https://github.com/yourusername/EduHack-Lab
plan: free
buildCommand: pip install -r requirements.txt
startCommand: gunicorn app.main:app -w 2 -k uvicorn.workers.UvicornWorker
envVars:
- key: PYTHON_VERSION
value: 3.11.0
databases:
- name: eduhack-db
databaseName: eduhack
user: eduhack
plan: free
17.6 Railway.app & Render.com Deployment
Railway.app Complete Setup
# Project structure for Railway
EduHack-Lab/
βββ app/
β βββ main.py
βββ requirements.txt
βββ runtime.txt (python-3.11.0)
βββ railway.json
# railway.json
{
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"startCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000",
"healthcheckPath": "/health"
}
}
Render.com Complete Setup
# .render/Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "app.main:app", "-w", "2", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
17.7 PythonAnywhere & Shared Hosting
Better Budget Alternatives (Under $5/month)
Hetzner Cloud - Best Performance for Price
# CX11 instance: β¬4.15/month
# 1 vCPU, 2GB RAM, 20GB SSD
# Quick deploy with Docker
curl -fsSL https://get.docker.com | sh
docker run -d -p 80:8000 yourusername/eduhack-lab:latest
Oracle Cloud Free Tier - Best Free Option
# Always free: 4 ARM cores, 24GB RAM, 200GB storage
# Create VM.Standard.A1.Fire instance
# Follow standard Ubuntu setup
Vultr Cloud Compute - Cheapest Option
# $2.50/month for IPv6-only
# $5/month for IPv4
# Use same setup as AWS EC2
17.8 VPS Deployment (Linode, Vultr, UpCloud)
Universal VPS Setup Script
#!/bin/bash
# deploy.sh - Run on fresh Ubuntu 22.04 VPS
set -e
echo "π Starting EduHack-Lab deployment..."
# Update system
sudo apt update && sudo apt upgrade -y
# Install dependencies
sudo apt install -y python3-pip python3-venv nginx git
# Clone application
git clone https://github.com/yourusername/EduHack-Lab.git /var/www/eduhack
cd /var/www/eduhack
# Setup Python environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Create .env file
cat > .env << EOF
DATABASE_URL=sqlite:///./test.db
SECRET_KEY=$(openssl rand -hex 32)
DEBUG=False
EOF
# Setup systemd service
sudo tee /etc/systemd/system/eduhack.service << 'EOF'
[Unit]
Description=EduHack-Lab FastAPI App
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/eduhack
Environment="PATH=/var/www/eduhack/venv/bin"
ExecStart=/var/www/eduhack/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# Setup Nginx
sudo tee /etc/nginx/sites-available/eduhack << 'EOF'
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
# Enable services
sudo systemctl daemon-reload
sudo systemctl enable eduhack
sudo systemctl start eduhack
sudo ln -s /etc/nginx/sites-available/eduhack /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx
echo "β
Deployment complete!"
echo "π Visit: http://$(curl -s ifconfig.me)"
Linode Specific Setup
# Using Linode CLI
linode-cli linodes create \
--label eduhack-lab \
--region us-east \
--type g6-nanode-1 \
--image linode/ubuntu22.04 \
--root_pass YourPassword123
17.9 Serverless Deployment (AWS Lambda + Mangum)
Complete Serverless Setup for FastAPI
Installation and Configuration
# Install required packages
pip install mangum
# Modify app/main.py
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI(title="EduHack-Lab API")
@app.get("/")
async def root():
return {"message": "Hello from Serverless FastAPI!"}
# Lambda handler
handler = Mangum(app)
Serverless Framework Configuration
# serverless.yml
service: eduhack-lab-serverless
provider:
name: aws
runtime: python3.11
region: us-east-1
memorySize: 512
timeout: 30
environment:
DATABASE_URL: ${env:DATABASE_URL}
functions:
api:
handler: app.main.handler
events:
- httpApi:
method: ANY
path: /{proxy+}
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
layer: true
# Deploy
npm install -g serverless
serverless plugin install -n serverless-python-requirements
serverless deploy --stage production
Limitations and Considerations
- β Cold starts (5-10 seconds for Python)
- β 15-minute maximum execution time
- β 250MB deployment package limit
- β Limited WebSocket support
- β Pay-per-request (can be cheaper for low traffic)
- β Automatic scaling to zero
17.10 Kubernetes Deployment (EKS, GKE, AKS)
Complete Kubernetes Configuration
Deployment YAML
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: eduhack-lab
spec:
replicas: 3
selector:
matchLabels:
app: eduhack
template:
metadata:
labels:
app: eduhack
spec:
containers:
- name: fastapi
image: yourregistry/eduhack-lab:latest
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: DATABASE_URL
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: eduhack-service
spec:
selector:
app: eduhack
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: eduhack-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: eduhack-lab
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Deploy Commands
# Apply configurations
kubectl apply -f deployment.yaml
# Check status
kubectl get pods
kubectl get services
# Get external IP
kubectl get service eduhack-service --watch
17.11 Platform Comparison & Cost Analysis
Cloud Platform Comparison Table
| Platform | Free Tier | Starting Price | Best For | Difficulty |
|---|---|---|---|---|
| AWS EC2 | 750 hrs/month (12 months) | $0.0116/hr (t4g.nano) | Full control, complex apps | Advanced |
| AWS Lambda | 1M requests/month | $0.20/1M requests | Sporadic traffic, APIs | Intermediate |
| Google Cloud Run | 2M requests/month | $0.10/100K requests | Containerized apps | Intermediate |
| Azure App Service | 1 hour/day (F1 tier) | $0.10/hr (B1 tier) | .NET integration | Intermediate |
| DigitalOcean | $200 credit (60 days) | $4/month | Simple VPS needs | Beginner |
| Railway.app | $5 credit or 500 hrs | $5/month | Ease of use | Beginner |
| Render.com | 750 hrs/month | $7/month | Free SSL, easy deploy | Beginner |
| Hetzner | No free tier | β¬4.15/month | Budget VPS | Intermediate |
Cost Optimization Strategies
- β Use ARM instances (AWS Graviton, Hetzner ARM) - 20% cheaper
- β Right-size instances based on actual usage
- β Use spot/preemptible instances for non-critical workloads
- β Implement auto-scaling to reduce idle resources
- β Consider serverless for variable traffic patterns
- β Use CDN (CloudFront, Cloudflare) to reduce origin traffic
17.12 CI/CD Pipeline Setup for Each Platform
GitHub Actions for AWS EC2
# .github/workflows/deploy-aws.yml
name: Deploy to AWS EC2
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to EC2
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /var/www/EduHack-Lab
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart eduhack
GitLab CI/CD for Any Platform
# .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
test:
stage: test
script:
- pip install pytest
- pytest tests/
build:
stage: build
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
deploy:
stage: deploy
script:
- ssh user@server "docker pull $DOCKER_IMAGE && docker-compose up -d"
only:
- main
17.13 Environment Variables & Secrets Management
Best Practices for Managing Secrets
Using AWS Secrets Manager
# Store secret
aws secretsmanager create-secret \
--name eduhack-secrets \
--secret-string '{"DATABASE_URL":"postgresql://...","SECRET_KEY":"..."}'
# Retrieve in code
import boto3
session = boto3.session.Session()
client = session.client('secretsmanager')
response = client.get_secret_value(SecretId='eduhack-secrets')
Using .env Files (Development Only)
# .env.example (commit to git)
DATABASE_URL=postgresql://user:password@localhost/db
SECRET_KEY=your-secret-key-here
DEBUG=True
# .env (never commit - add to .gitignore)
DATABASE_URL=postgresql://prod_user:prod_pass@prod-db/prod_db
SECRET_KEY=actual-production-secret-key
DEBUG=False
Using GitHub Secrets
# Store secrets in GitHub
# Settings β Secrets and variables β Actions
# Use in workflows
- name: Deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
run: python deploy.py
17.14 Database Hosting Options (RDS, Cloud SQL, Cosmos DB)
Managed Database Services Comparison
| Provider | Service | Free Tier | Starting Price |
|---|---|---|---|
| AWS | RDS PostgreSQL | 750 hrs/month (db.t3.micro) | $0.017/hr |
| GCP | Cloud SQL | No free tier | $0.015/hr (db-f1-micro) |
| Azure | Cosmos DB | 25 GB storage | $0.008/hr |
| DigitalOcean | Managed Database | $15 credit | $15/month |
Connecting to Managed Databases
# AWS RDS Connection
DATABASE_URL=postgresql://username:password@database-1.xxxxxx.us-east-1.rds.amazonaws.com:5432/eduhack
# GCP Cloud SQL Connection
DATABASE_URL=postgresql://username:password@/eduhack?host=/cloudsql/INSTANCE_CONNECTION_NAME
# Azure Cosmos DB (PostgreSQL)
DATABASE_URL=postgresql://username:password@server.postgres.database.azure.com:5432/eduhack
17.15 Domain & SSL Configuration
Setting Up Custom Domain
DNS Configuration Examples
# A Record (for IP-based hosting)
Type: A
Name: @ or api
Value: 123.123.123.123 (your server IP)
TTL: 3600
# CNAME Record (for platform hosting)
Type: CNAME
Name: api
Value: your-app.railway.app or your-service.onrender.com
TTL: 3600
SSL with Let's Encrypt (Certbot)
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y
# Get SSL certificate
sudo certbot --nginx -d api.yourdomain.com -d www.api.yourdomain.com
# Auto-renewal
sudo certbot renew --dry-run
# Manual renewal
sudo certbot renew
SSL for Cloud Platforms
# AWS (via Load Balancer or CloudFront)
# GCP (Managed SSL via Cloud Run)
gcloud run services update eduhack-lab --ingress=all
# Azure (Automatic SSL with App Service)
az webapp config ssl bind --certificate-thumbprint
# DigitalOcean (App Platform auto SSL)
# Automatic with custom domain
17.16 Monitoring & Logging on Cloud Platforms
Setting Up Application Monitoring
AWS CloudWatch Setup
# Install CloudWatch agent
sudo wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
# Configure CloudWatch agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
# Start CloudWatch agent
sudo systemctl start amazon-cloudwatch-agent
Structured Logging in FastAPI
# app/core/logging.py
import logging
import json
from datetime import datetime
class JSONFormatter(logging.Formatter):
def format(self, record):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"level": record.levelname,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName
}
return json.dumps(log_entry)
# Configure logger
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
Prometheus Metrics for FastAPI
# Install prometheus-fastapi-instrumentator
pip install prometheus-fastapi-instrumentator
# app/main.py
from prometheus_fastapi_instrumentator import Instrumentator
app = FastAPI()
Instrumentator().instrument(app).expose(app)
# Access metrics at: http://your-app/metrics
17.17 Auto-scaling & Load Balancing
Implementing Auto-scaling
AWS Auto Scaling Group
# Create launch template
aws ec2 create-launch-template \
--launch-template-name eduhack-template \
--image-id ami-0c55b159cbfafe1f0 \
--instance-type t3.micro
# Create auto scaling group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name eduhack-asg \
--launch-template LaunchTemplateName=eduhack-template \
--min-size 2 \
--max-size 5 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-xxx,subnet-yyy"
# Create scaling policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name eduhack-asg \
--policy-name cpu-scale-out \
--policy-type TargetTrackingScaling \
--target-tracking-configuration file://config.json
Load Balancer Configuration
# AWS Application Load Balancer
# 1. Create target group
# 2. Register EC2 instances
# 3. Create listener on port 80/443
# 4. Forward to target group
# Nginx as Load Balancer
upstream eduhack_backend {
least_conn;
server 10.0.1.1:8000;
server 10.0.1.2:8000;
server 10.0.1.3:8000;
}
server {
listen 80;
location / {
proxy_pass http://eduhack_backend;
proxy_set_header Host $host;
}
}
17.18 Cost Optimization Strategies
Reduce Cloud Costs Without Sacrificing Performance
Compute Optimization
- Use Spot/Preemptible Instances: Save 60-90% on non-critical workloads
- Right-size Instances: Monitor CPU/memory usage and scale down
- Use ARM Architecture: AWS Graviton, Hetzner ARM (20-30% cheaper)
- Auto-scaling to Zero: Use serverless for development/staging environments
Storage Optimization
- Use S3 Glacier for backups and logs
- Delete unattached EBS volumes
- Use EBS gp3 instead of gp2 (lower cost per GB)
- Implement data lifecycle policies
Database Optimization
- Use reserved instances for production databases
- Implement read replicas only when needed
- Use SQLite for development, managed DB for production
- Clean up old database snapshots
Network Optimization
- Use CloudFlare free tier as CDN
- Implement caching to reduce origin traffic
- Use internal load balancers instead of public
- Monitor data transfer costs between regions
Free Tier Strategies for Learning
# Best free tier combination for learning:
1. AWS Free Tier: 750 hrs EC2 + RDS (12 months)
2. Google Cloud: 2 million requests on Cloud Run
3. Railway.app: $5 credit (good for testing)
4. Render.com: 750 hrs free web service
5. GitHub Actions: 2000 mins/month for CI/CD
6. CloudFlare: Free CDN + SSL + DDoS protection
# Multi-cloud strategy for maximum free tier:
- Frontend: Vercel/Netlify (free)
- Backend: Render.com (free tier)
- Database: Supabase (free PostgreSQL)
- Storage: CloudFlare R2 (10GB free)
- CI/CD: GitHub Actions (free)
π Module: Project Deployment Successfully Completed
You have successfully completed the deployment module of FastAPI Framework Development Course.
Your application is now ready for production deployment on any major cloud platform!
Important Interview Questions - FastAPI Framework
Comprehensive interview preparation guide covering 100+ frequently asked FastAPI questions for beginners, intermediate, and advanced developers. These questions are commonly asked in technical interviews for Python backend developer positions at companies like Microsoft, Amazon, Google, and startups.
Topic 1: FastAPI Fundamentals (10 Questions)
Q1. What is FastAPI and what makes it unique?
Answer: FastAPI is a modern, high-performance web framework for building APIs with Python 3.7+.
- High Performance: On par with Node.js and Go
- Fast to Code: Increase development speed by 200-300%
- Fewer Bugs: Reduce human-induced errors by about 40%
- Intuitive: Great editor support with autocomplete
- Standards-based: Based on OpenAPI and JSON Schema
Q2. Who created FastAPI and when?
Answer: SebastiΓ‘n RamΓrez created FastAPI in 2018. He was inspired by Flask, Django, and previous work on API frameworks.
Q3. What are the main features of FastAPI?
- Automatic interactive API documentation (Swagger UI and ReDoc)
- Data validation using Pydantic
- Dependency injection system
- Security and authentication built-in
- WebSocket support
- Background tasks
- GraphQL support via additional libraries
Q4. What companies use FastAPI in production?
Answer: Microsoft (Azure services), Uber, Netflix, Discord, and thousands of startups use FastAPI for high-performance microservices.
Q5. What are the disadvantages of FastAPI?
- Relatively new (less community resources than Django/Flask)
- Async can be complex for beginners
- Smaller ecosystem of third-party packages
- May be overkill for simple APIs
Q6. How does FastAPI compare to Flask?
| Feature | FastAPI | Flask |
|---|---|---|
| Performance | ~70,000 req/sec | ~8,000 req/sec |
| Async Support | Native | Limited |
| Data Validation | Built-in (Pydantic) | Third-party |
| API Docs | Automatic | Manual |
| Dependency Injection | Built-in | Manual |
Q7. How does FastAPI compare to Django?
- Django: Full-featured framework (ORM, admin, templates, auth) - better for monolithic applications
- FastAPI: Microframework focused on APIs - better for microservices and high-performance APIs
Q8. What Python versions support FastAPI?
Answer: FastAPI requires Python 3.7+ and works with Python 3.8, 3.9, 3.10, 3.11, and 3.12.
Q9. What are the core libraries FastAPI is built on?
- Starlette: For web routing and ASGI functionality
- Pydantic: For data validation and serialization
- Uvicorn: For ASGI server (production)
Q10. How do you install FastAPI?
pip install fastapi
pip install "uvicorn[standard]" # ASGI server
# Or with all dependencies
pip install fastapi[all]
Topic 2: ASGI vs WSGI & Performance (8 Questions)
Q1. What is WSGI and what are its limitations?
Answer: WSGI (Web Server Gateway Interface) is a specification for synchronous Python web applications.
- Limitations: Cannot handle WebSockets, long-polling, or HTTP/2
- Concurrency: One request per worker at a time
- Examples: Flask, Django (traditional), Pyramid
Q2. What is ASGI and how is it different from WSGI?
Answer: ASGI (Asynchronous Server Gateway Interface) is the spiritual successor to WSGI supporting async operations.
- Supports: HTTP/1.1, HTTP/2, WebSockets, gRPC
- Concurrency: Multiple requests per worker using async/await
- Examples: FastAPI, Starlette, Django (ASGI mode)
Q3. Why does FastAPI use ASGI instead of WSGI?
- Better performance with async I/O operations
- WebSocket support for real-time features
- HTTP/2 support for improved efficiency
- Can handle thousands of concurrent connections
Q4. How does FastAPI achieve 70,000+ requests per second?
- Starlette (high-performance ASGI framework)
- Pydantic (Rust-based validation)
- Uvicorn with uvloop (asyncio event loop)
- Minimal overhead in request processing
Q5. What is Uvicorn and why is it recommended for FastAPI?
Answer: Uvicorn is a lightning-fast ASGI server implementation using uvloop and httptools.
# Run with Uvicorn
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
Q6. What is the difference between Uvicorn, Hypercorn, and Daphne?
| Server | Best For | Features |
|---|---|---|
| Uvicorn | FastAPI, Starlette | Fastest, HTTP/1.1, WebSocket |
| Hypercorn | HTTP/2, HTTP/3 | HTTP/2, HTTP/3, Trio support |
| Daphne | Django Channels | HTTP/1.1, WebSocket |
Q7. How do you run FastAPI in production with Gunicorn?
# Install
pip install gunicorn uvicorn
# Run with Uvicorn workers
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
# With custom options
gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Q8. What is the request lifecycle in FastAPI?
- Client sends HTTP request
- ASGI server (Uvicorn) receives request
- Middleware stack processes request
- Route matching and parameter extraction
- Dependency injection resolution
- Path operation function execution
- Response validation and serialization
- Middleware processes response (reverse order)
- Response sent back to client
Topic 3: Dependency Injection & Pydantic (12 Questions)
Q1. What is Dependency Injection in FastAPI?
Answer: A design pattern where objects receive their dependencies from an external source rather than creating them internally.
from fastapi import Depends
def get_db():
db = Database()
try:
yield db
finally:
db.close()
@app.get("/users")
def get_users(db = Depends(get_db)):
return db.query()
Q2. What are the benefits of Dependency Injection?
- Decoupling: Classes don't need to create dependencies
- Testability: Easy to mock dependencies in tests
- Reusability: Same dependency across multiple endpoints
- Automatic documentation: Dependencies appear in OpenAPI docs
Q3. How do you create nested dependencies?
async def get_current_user(token: str = Depends(oauth2_scheme)):
return verify_token(token)
async def get_current_active_user(
current_user = Depends(get_current_user)
):
if not current_user.is_active:
raise HTTPException(status_code=400)
return current_user
@app.get("/users/me")
async def get_me(user = Depends(get_current_active_user)):
return user
Q4. What is the difference between Depends() and using regular parameters?
Answer: Depends() tells FastAPI to use the dependency injection system, allowing for caching, sub-dependencies, and better testability.
Q5. Can you use classes as dependencies?
class CommonParams:
def __init__(self, q: str = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items")
def get_items(params: CommonParams = Depends()):
return {"q": params.q, "skip": params.skip}
Q6. What are Pydantic models?
Answer: Pydantic uses Python type hints for data validation and settings management.
from pydantic import BaseModel, Field
class User(BaseModel):
name: str = Field(..., min_length=2, max_length=50)
email: str
age: int = Field(ge=0, le=150)
Q7. How do you create custom validators in Pydantic?
from pydantic import BaseModel, validator
class User(BaseModel):
name: str
email: str
@validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Invalid email')
return v
Q8. What is the difference between Optional and default values?
from typing import Optional
class Item(BaseModel):
name: str # Required
description: str = None # Optional with default None
price: Optional[float] = None # Optional with default None
tax: float = 0.0 # Optional with default 0.0
Q9. What is ORM mode in Pydantic?
Answer: ORM mode allows Pydantic to read data from ORM objects (like SQLAlchemy models).
class UserSchema(BaseModel):
id: int
name: str
class Config:
from_attributes = True # orm_mode in older versions
Q10. How do you handle nested Pydantic models?
class Address(BaseModel):
street: str
city: str
class User(BaseModel):
name: str
address: Address # Nested model
class UserList(BaseModel):
users: List[User] # List of models
Q11. What is Pydantic Settings?
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "My API"
database_url: str
secret_key: str
class Config:
env_file = ".env"
settings = Settings()
Q12. How does FastAPI use Pydantic for request/response validation?
- Request body automatically validated against Pydantic model
- Response automatically validated against response_model
- Automatic 422 error responses for invalid data
- OpenAPI schema generated from Pydantic models
Topic 4: Authentication & Security (10 Questions)
Q1. What authentication methods does FastAPI support?
- OAuth2 with Password Flow (JWT tokens)
- HTTP Basic Authentication
- API Keys (header, query, or cookie)
- Custom authentication schemes
- OAuth2 with external providers (Google, GitHub)
Q2. How do you implement JWT authentication in FastAPI?
from jose import JWTError, jwt
from passlib.context import CryptContext
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def create_access_token(data: dict):
return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
Q3. What is OAuth2PasswordBearer and how does it work?
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
# Validate credentials and return token
return {"access_token": token, "token_type": "bearer"}
@app.get("/users/me")
async def get_user(token: str = Depends(oauth2_scheme)):
# Token automatically extracted from Authorization header
return decode_token(token)
Q4. How do you implement Role-Based Access Control (RBAC)?
def get_current_user(token: str = Depends(oauth2_scheme)):
user = decode_token(token)
if not user:
raise HTTPException(status_code=401)
return user
def require_role(role: str):
def role_checker(current_user = Depends(get_current_user)):
if current_user.role != role:
raise HTTPException(status_code=403)
return current_user
return role_checker
@app.get("/admin")
async def admin_only(user = Depends(require_role("admin"))):
return {"message": "Admin access granted"}
Q5. How do you hash passwords securely?
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# Hash password
hashed = pwd_context.hash("mypassword")
# Verify password
is_valid = pwd_context.verify("mypassword", hashed)
Q6. How do you implement CORS in FastAPI?
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Q7. What are common security headers you should set?
Strict-Transport-Security(HSTS) - Force HTTPSX-Frame-Options- Prevent clickjackingX-Content-Type-Options- Prevent MIME sniffingX-XSS-Protection- Cross-site scripting protectionContent-Security-Policy- Control resource loading
Q8. How do you implement rate limiting?
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
@app.get("/api")
@limiter.limit("5/minute")
async def api_endpoint(request: Request):
return {"message": "Rate limited to 5 requests per minute"}
Q9. How do you protect against SQL injection?
- Use ORM (SQLAlchemy) with parameterized queries
- Never concatenate user input directly into SQL strings
- Use Pydantic for input validation
- Escape special characters when necessary
Q10. How do you implement API key authentication?
from fastapi.security import APIKeyHeader
api_key_header = APIKeyHeader(name="X-API-Key")
def verify_api_key(api_key: str = Depends(api_key_header)):
if api_key not in valid_keys:
raise HTTPException(status_code=403)
return api_key
@app.get("/secure-data")
async def get_data(api_key: str = Depends(verify_api_key)):
return {"data": "sensitive information"}
Topic 5: Async/Await & Concurrency (8 Questions)
Q1. What is the difference between synchronous and asynchronous code?
- Synchronous: Code executes sequentially, blocking until each operation completes
- Asynchronous: Code can run concurrently, non-blocking I/O operations
Q2. When should you use async/await in FastAPI?
- β Use async for: Database calls, API requests, file I/O, network operations
- β Don't use async for: CPU-intensive calculations, image processing, complex algorithms
Q3. How do you call async functions from sync code?
import asyncio
def sync_function():
# Run async function synchronously
result = asyncio.run(async_function())
return result
Q4. How do you run blocking operations in async endpoints?
from fastapi.concurrency import run_in_threadpool
@app.get("/compute")
async def compute():
# Run CPU-bound function in thread pool
result = await run_in_threadpool(cpu_intensive_function, data)
return result
Q5. What is the Global Interpreter Lock (GIL) and how does it affect async?
Answer: The GIL allows only one thread to execute Python bytecode at a time. Async/await helps with I/O concurrency, not CPU parallelism.
Q6. How do you run multiple async tasks concurrently?
async def fetch_data():
# Run multiple API calls concurrently
results = await asyncio.gather(
fetch_user(),
fetch_orders(),
fetch_products()
)
return results
Q7. What is an event loop in asyncio?
Answer: The event loop manages and distributes the execution of different tasks, allowing for concurrent I/O operations.
Q8. Can you mix async and sync endpoints in FastAPI?
Answer: Yes, FastAPI handles both automatically. Sync endpoints run in a thread pool to avoid blocking the event loop.
@app.get("/async")
async def async_endpoint():
await asyncio.sleep(1)
return {"type": "async"}
@app.get("/sync")
def sync_endpoint():
time.sleep(1)
return {"type": "sync"}
Topic 6: Database Integration & SQLAlchemy (10 Questions)
Q1. How do you integrate SQLAlchemy with FastAPI?
# database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
SQLALCHEMY_DATABASE_URL = "postgresql://user:pass@localhost/db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Q2. How do you handle database sessions properly?
Answer: Use dependency injection to create and close sessions automatically.
@app.get("/users")
def get_users(db: Session = Depends(get_db)):
return db.query(User).all()
# Session automatically closed after request
Q3. How do you implement async database operations?
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
ASYNC_DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/db"
engine = create_async_engine(ASYNC_DATABASE_URL)
async def get_db():
async with AsyncSession(engine) as session:
yield session
@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User))
return result.scalars().all()
Q4. What is Alembic and how do you use it?
Answer: Alembic is a database migration tool for SQLAlchemy.
# Install
pip install alembic
# Initialize
alembic init alembic
# Create migration
alembic revision --autogenerate -m "create users table"
# Apply migration
alembic upgrade head
Q5. How do you handle the N+1 query problem?
- Use
joinedload()orselectinload()for eager loading - Use
subqueryload()for complex relationships - Denormalize data when appropriate
Q6. What is the difference between lazy and eager loading?
- Lazy Loading: Relationships loaded only when accessed (can cause N+1)
- Eager Loading: Relationships loaded upfront in same query
Q7. How do you implement database transactions?
@app.post("/transfer")
def transfer_money(db: Session = Depends(get_db)):
try:
db.add(withdrawal)
db.add(deposit)
db.commit() # Both operations succeed or fail together
except Exception:
db.rollback() # Revert both operations
raise
Q8. What is connection pooling and how do you configure it?
engine = create_engine(
DATABASE_URL,
pool_size=5, # Number of connections to maintain
max_overflow=10, # Extra connections when needed
pool_timeout=30, # Time to wait for connection
pool_recycle=1800 # Recycle connections after 30 minutes
)
Q9. How do you optimize database queries in FastAPI?
- Add indexes on frequently queried columns
- Use
selectinload()for collections - Limit columns with
with_entities() - Use pagination for large result sets
- Implement query caching with Redis
Q10. How do you set up database migrations in production?
# Docker entrypoint script
#!/bin/bash
alembic upgrade head
uvicorn main:app --host 0.0.0.0 --port 8000
# Or as a separate job in CI/CD
alembic upgrade head
Topic 7: Routing, Middleware & WebSockets (10 Questions)
Q1. What are path and query parameters in FastAPI?
# Path parameters (required, part of URL)
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
# Query parameters (optional, after ?)
@app.get("/search")
def search(q: str, page: int = 1, limit: int = 10):
return {"query": q, "page": page}
Q2. How do you use APIRouter for modular routing?
# routers/users.py
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/")
def get_users():
return [{"name": "John"}]
# main.py
from routers import users
app.include_router(users.router)
Q3. How do you create custom middleware?
from starlette.middleware.base import BaseHTTPMiddleware
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Before request
start_time = time.time()
response = await call_next(request)
# After request
response.headers["X-Process-Time"] = str(time.time() - start_time)
return response
app.add_middleware(CustomMiddleware)
Q4. What is the difference between middleware and dependencies?
- Middleware: Processes all requests globally, can modify request/response
- Dependencies: Can be applied per endpoint, more granular control
Q5. How do you implement WebSocket endpoints?
@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
except WebSocketDisconnect:
print(f"Client {client_id} disconnected")
Q6. How do you handle WebSocket disconnections?
@app.websocket("/ws")
async def ws_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await manager.broadcast(data)
except WebSocketDisconnect:
manager.remove_client(websocket)
Q7. How do you set custom response headers?
from fastapi import Response
@app.get("/custom-header")
def get_data(response: Response):
response.headers["X-Custom-Header"] = "Custom Value"
return {"message": "Success"}
Q8. How do you return different response types?
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse
@app.get("/html", response_class=HTMLResponse)
def get_html():
return "Hello World
"
@app.get("/json")
def get_json():
return {"message": "Hello"} # Auto-converted to JSON
@app.get("/text", response_class=PlainTextResponse)
def get_text():
return "Hello World"
Q9. How do you handle redirects?
from fastapi.responses import RedirectResponse
@app.get("/old-path")
def redirect():
return RedirectResponse(url="/new-path", status_code=301)
Q10. How do you customize Swagger UI?
app = FastAPI(
title="My API",
description="API documentation",
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc",
openapi_url="/openapi.json"
)
Topic 8: Testing, Deployment & DevOps (12 Questions)
Q1. How do you test FastAPI applications?
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello World"}
Q2. How do you test endpoints that require authentication?
def test_protected_endpoint():
# First get token
token_response = client.post("/token", data={
"username": "testuser",
"password": "testpass"
})
token = token_response.json()["access_token"]
# Use token
response = client.get(
"/protected",
headers={"Authorization": f"Bearer {token}"}
)
assert response.status_code == 200
Q3. How do you test database operations?
@pytest.fixture
def db_session():
engine = create_engine("sqlite:///:memory:")
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.create_all(bind=engine)
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
def test_create_user(db_session):
user = User(name="Test")
db_session.add(user)
db_session.commit()
assert user.id is not None
Q4. How do you run FastAPI in production?
# Using Gunicorn + Uvicorn (recommended)
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
# Using Uvicorn directly
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
Q5. How do you Dockerize a FastAPI application?
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
Q6. How do you set up CI/CD for FastAPI?
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to server
run: |
ssh user@server "cd /app && git pull && docker-compose up -d --build"
Q7. How do you configure environment variables?
# .env file
DATABASE_URL=postgresql://localhost/db
SECRET_KEY=your-secret-key
# config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
secret_key: str
class Config:
env_file = ".env"
Q8. How do you set up logging in production?
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
Q9. How do you monitor FastAPI applications?
- Prometheus + Grafana: For metrics and visualization
- ELK Stack: For log aggregation
- Sentry: For error tracking
- New Relic/DataDog: For APM monitoring
Q10. How do you implement health checks?
@app.get("/health")
async def health_check(db: Session = Depends(get_db)):
# Check database
db.execute("SELECT 1")
# Check Redis
redis_client.ping()
return {
"status": "healthy",
"timestamp": datetime.now().isoformat()
}
Q11. How do you scale FastAPI horizontally?
- Run multiple Uvicorn workers on a single server
- Use a load balancer (Nginx, AWS ALB) to distribute traffic
- Deploy multiple instances behind a load balancer
- Use container orchestration (Kubernetes, Docker Swarm)
Q12. What are common performance bottlenecks in FastAPI?
- Synchronous database calls blocking the event loop
- CPU-intensive operations in async endpoints
- N+1 query problems
- Missing database indexes
- Large file uploads without streaming
Topic 9: Advanced Concepts & Best Practices (10 Questions)
Q1. What is OpenAPI and how does FastAPI use it?
Answer: OpenAPI is a specification for describing REST APIs. FastAPI automatically generates OpenAPI schema from your code.
Q2. How do you add custom metadata to OpenAPI?
app = FastAPI(
title="My API",
description="Custom description",
version="2.0.0",
terms_of_service="http://example.com/terms/",
contact={
"name": "API Support",
"url": "http://example.com/support",
"email": "support@example.com",
},
license_info={
"name": "MIT",
"url": "https://opensource.org/licenses/MIT",
},
)
Q3. How do you implement background tasks?
from fastapi import BackgroundTasks
def send_email(email: str):
# Time-consuming operation
time.sleep(10)
print(f"Email sent to {email}")
@app.post("/notify")
async def notify(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(send_email, email)
return {"message": "Email will be sent in background"}
Q4. How do you handle file uploads?
from fastapi import File, UploadFile
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
contents = await file.read()
# Process file
return {"filename": file.filename, "size": len(contents)}
Q5. How do you stream large files?
from fastapi.responses import StreamingResponse
@app.get("/large-file")
def get_large_file():
def file_generator():
with open("large-file.zip", "rb") as f:
yield from f
return StreamingResponse(file_generator(), media_type="application/zip")
Q6. How do you implement caching in FastAPI?
from fastapi_cache import FastAPICache
from fastapi_cache.decorator import cache
@app.get("/expensive")
@cache(expire=60) # Cache for 60 seconds
async def expensive_operation():
# Expensive computation
return result
Q7. How do you version APIs in FastAPI?
# Option 1: URL versioning
app.include_router(v1_router, prefix="/api/v1")
app.include_router(v2_router, prefix="/api/v2")
# Option 2: Header versioning
@app.get("/users")
def get_users(version: str = Header("1.0")):
if version == "2.0":
return new_response
return old_response
Q8. How do you implement GraphQL with FastAPI?
from strawberry.fastapi import GraphQLRouter
import strawberry
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello World"
schema = strawberry.Schema(query=Query)
graphql_app = GraphQLRouter(schema)
app.include_router(graphql_app, prefix="/graphql")
Q9. What are FastAPI events (startup/shutdown)?
@app.on_event("startup")
async def startup_event():
# Initialize database connections
await database.connect()
print("Application starting up")
@app.on_event("shutdown")
async def shutdown_event():
# Clean up resources
await database.disconnect()
print("Application shutting down")
Q10. What are common security best practices in FastAPI?
- Use HTTPS in production
- Implement rate limiting
- Validate all user inputs with Pydantic
- Use environment variables for secrets
- Implement proper authentication and authorization
- Set secure HTTP headers (HSTS, CSP, X-Frame-Options)
- Keep dependencies updated
- Use parameterized queries to prevent SQL injection
Topic 10: Scenario-Based & Problem Solving (10 Questions)
Q1. How would you build a scalable e-commerce API with FastAPI?
- Use APIRouter for modular organization (products, orders, users, carts)
- Implement JWT authentication for users
- Use PostgreSQL with SQLAlchemy for data persistence
- Implement Redis caching for product catalog
- Use Celery for order processing and email notifications
- Implement rate limiting for API endpoints
- Deploy with Docker and Kubernetes for scaling
Q2. How do you debug a slow endpoint in production?
- Add timing middleware to log request duration
- Check database query performance (N+1 problem)
- Profile the endpoint using cProfile or py-spy
- Check if sync code is blocking the event loop
- Review database indexes and query plans
- Check external API call latencies
Q3. How do you handle database migrations without downtime?
- Use Alembic with backward-compatible migrations
- Add columns as nullable first, backfill data, then make non-nullable
- Use blue-green deployment strategy
- Keep old API version until all clients migrate
- Use feature flags to control rollout
Q4. How would you implement real-time notifications?
# Use WebSockets for real-time
@router.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
await manager.connect(user_id, websocket)
try:
while True:
data = await websocket.receive_text()
await manager.send_personal_message(f"Notification: {data}", user_id)
except WebSocketDisconnect:
manager.disconnect(user_id)
# Or use Server-Sent Events (SSE)
from sse_starlette.sse import EventSourceResponse
@app.get("/stream")
async def stream_notifications():
async def event_generator():
while True:
yield {"data": "Notification"}
await asyncio.sleep(1)
return EventSourceResponse(event_generator())
Q5. How do you handle third-party API rate limits?
- Implement request queuing with exponential backoff
- Use circuit breaker pattern to stop requests when API is down
- Cache responses when possible
- Implement retry logic with jitter
- Use message queue (RabbitMQ, Redis) for async processing
Q6. How would you implement search functionality?
@app.get("/search")
async def search(
q: str,
page: int = 1,
limit: int = 20,
sort: str = "relevance",
filters: dict = None
):
# Use PostgreSQL full-text search
# Or integrate Elasticsearch
# Or use vector search for semantic search
results = await search_service.search(q, page, limit, sort, filters)
return {"results": results, "total": len(results)}
Q7. How do you secure a FastAPI microservice?
- Implement JWT or OAuth2 authentication
- Use API gateway for external access
- Implement mutual TLS for service-to-service auth
- Validate all inputs and outputs
- Use environment variables for secrets
- Implement audit logging
- Regular security updates and dependency scanning
Q8. How do you handle large dataset exports?
@app.get("/export")
async def export_data():
def generate():
# Stream results to avoid memory issues
for batch in fetch_in_batches(1000):
yield json.dumps(batch) + "\n"
return StreamingResponse(
generate(),
media_type="application/x-ndjson",
headers={"Content-Disposition": "attachment; filename=export.ndjson"}
)
Q9. How do you implement A/B testing in FastAPI?
def ab_test_middleware(request: Request):
user_id = request.headers.get("X-User-ID")
variant = "A" if hash(user_id) % 2 == 0 else "B"
request.state.variant = variant
@app.get("/feature")
async def test_feature(request: Request):
variant = request.state.variant
if variant == "A":
return {"result": variant_a_logic()}
return {"result": variant_b_logic()}
Q10. How do you troubleshoot memory leaks in FastAPI?
- Use memory profiling tools (memory-profiler, tracemalloc)
- Check for global variables accumulating data
- Review database session management (ensure sessions are closed)
- Check for circular references in dependencies
- Monitor with Prometheus + Grafana
- Use object counting to identify leaking types
π Module: Important Interview Questions Successfully Completed
You have successfully completed 100+ interview questions covering all aspects of FastAPI development.
Practice these questions to ace your FastAPI developer interview!