Technical Tutorials & Implementation Guides
Master modern development practices with our hands-on technical tutorials. From API development to deployment strategies, these guides provide production-ready solutions and best practices.
🚀 API Development & Deployment
Building Production FastAPI Applications: Complete 2026 Guide
TL;DR: Build production-ready FastAPI applications with proper structure, authentication, database integration, and deployment. From local development to production deployment in 2 hours.
Tutorial Covers:
- Project Structure: Scalable FastAPI application layout
- Database Integration: SQLAlchemy with async support
- Authentication & Security: JWT tokens, rate limiting, CORS
- API Documentation: OpenAPI/Swagger customization
- Testing Suite: Unit and integration testing
- Deployment: Docker, Railway, and production optimization
Code Examples:
# Production-ready FastAPI structure
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer
from sqlalchemy.ext.asyncio import AsyncSession
app = FastAPI(
title="Production API",
description="Production-ready FastAPI application",
version="1.0.0"
)
security = HTTPBearer()
@app.get("/api/v1/users/me")
async def get_current_user(
token: str = Depends(security),
db: AsyncSession = Depends(get_db)
):
# Authenticated user endpoint
user = await get_user_from_token(token.credentials, db)
return user
Secure API Key Management: Best Practices & Implementation
TL;DR: Implement secure API key storage and management using Doppler, environment variables, and proper encryption. Protect your secrets from accidental exposure and unauthorized access.
Security Framework:
- Secrets Management: Doppler integration
- Environment Variables: Production best practices
- Key Rotation: Automated and manual processes
- Access Control: Role-based API key management
- Monitoring: Audit logs and breach detection
Implementation Example:
# Secure API key loading
import os
from typing import Optional
from cryptography.fernet import Fernet
class SecureConfig:
def __init__(self):
self.doppler_token = os.getenv("DOPPLER_TOKEN")
self.encryption_key = os.getenv("ENCRYPTION_KEY")
def get_api_key(self, service: str) -> Optional[str]:
"""Retrieve and decrypt API key"""
encrypted_key = self._fetch_from_doppler(f"{service}_API_KEY")
if encrypted_key:
return self._decrypt(encrypted_key)
return None
def _decrypt(self, encrypted_data: str) -> str:
f = Fernet(self.encryption_key)
return f.decrypt(encrypted_data.encode()).decode()
🏗️ Infrastructure & DevOps
Docker Optimization Strategies
Multi-Stage Builds:
# Stage 1: Build dependencies
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Stage 2: Runtime
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Layer Caching Optimization:
# Order operations from least to most frequently changing
COPY requirements.txt .
RUN pip install -r requirements.txt # Changes rarely
COPY . .
RUN python manage.py collectstatic # Changes occasionally
# This layer only rebuilds when source code changes
CI/CD Pipeline Implementation
GitHub Actions Workflow:
name: Deploy to Railway
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest
- name: Run tests
run: pytest tests/ -v
- name: Run security scan
run: |
pip install bandit
bandit -r app/
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Railway
uses: railway-app/railway-action@v1
with:
api-token: ${{ secrets.RAILWAY_TOKEN }}
🔐 Security Best Practices
API Security Checklist
Authentication & Authorization:
- Implement JWT token authentication
- Use secure token storage (HttpOnly cookies)
- Set reasonable token expiration times
- Implement refresh token rotation
- Role-based access control (RBAC)
Data Protection:
- HTTPS enforcement (redirect HTTP to HTTPS)
- Input validation and sanitization
- SQL injection prevention
- XSS protection headers
- Sensitive data encryption at rest
API Security:
- Rate limiting per user/IP
- API key management
- CORS configuration
- Security headers (CSP, HSTS)
- Request size limits
Implementation Examples
Rate Limiting with FastAPI:
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
@app.post("/api/v1/analyze")
@limiter.limit("10/minute")
async def analyze_content(request: Request):
# Limited to 10 requests per minute per IP
pass
Input Validation with Pydantic:
from pydantic import BaseModel, validator
import re
class ContentRequest(BaseModel):
url: str
keywords: list[str]
max_length: int = 5000
@validator('url')
def validate_url(cls, v):
if not re.match(r'^https?://', v):
raise ValueError('URL must start with http:// or https://')
return v
@validator('keywords')
def validate_keywords(cls, v):
if len(v) == 0:
raise ValueError('At least one keyword required')
return v[:10] # Limit to 10 keywords
📊 Monitoring & Observability
Application Performance Monitoring
Logging Setup:
import logging
import structlog
from pythonjsonlogger import jsonlogger
# Structured logging
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.processors.JSONRenderer()
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
logger = structlog.get_logger()
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
logger.info(
"request_processed",
method=request.method,
url=str(request.url),
status_code=response.status_code,
process_time=process_time
)
return response
Health Checks:
from fastapi import HTTPException
import asyncio
import redis
import asyncpg
@app.get("/health")
async def health_check():
health_status = {
"status": "healthy",
"timestamp": datetime.utcnow().isoformat(),
"checks": {}
}
# Check database connection
try:
await database.execute("SELECT 1")
health_status["checks"]["database"] = "healthy"
except Exception as e:
health_status["checks"]["database"] = f"unhealthy: {str(e)}"
health_status["status"] = "degraded"
# Check Redis connection
try:
redis_client.ping()
health_status["checks"]["redis"] = "healthy"
except Exception as e:
health_status["checks"]["redis"] = f"unhealthy: {str(e)}"
health_status["status"] = "degraded"
# Check external API
try:
response = httpx.get("https://api.openai.com/v1/models", timeout=5)
health_status["checks"]["external_api"] = "healthy" if response.status_code == 200 else "unhealthy"
except Exception as e:
health_status["checks"]["external_api"] = f"unhealthy: {str(e)}"
health_status["status"] = "degraded"
status_code = 200 if health_status["status"] == "healthy" else 503
return JSONResponse(content=health_status, status_code=status_code)
🛠️ Development Workflows
Local Development Setup
Docker Compose for Development:
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/app
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=app
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
pgadmin:
image: dpage/pgadmin4
environment:
- PGADMIN_DEFAULT_EMAIL=admin@example.com
- PGADMIN_DEFAULT_PASSWORD=admin
ports:
- "5050:80"
volumes:
postgres_data:
Development Scripts:
#!/bin/bash
# scripts/dev.sh
echo "Starting development environment..."
# Start services
docker-compose up -d db redis
# Wait for database
echo "Waiting for database..."
sleep 5
# Run migrations
echo "Running database migrations..."
alembic upgrade head
# Start application with hot reload
echo "Starting FastAPI with hot reload..."
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Testing Strategies
Unit Testing with Pytest:
# tests/test_api.py
import pytest
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
class TestContentAnalysis:
def test_analyze_content_success(self):
response = client.post(
"/api/v1/analyze",
json={
"url": "https://example.com/article",
"keywords": ["SEO", "content"],
"max_length": 5000
},
headers={"Authorization": "Bearer test_token"}
)
assert response.status_code == 200
data = response.json()
assert "analysis" in data
assert "score" in data
assert data["score"] >= 0
assert data["score"] <= 100
def test_analyze_content_invalid_url(self):
response = client.post(
"/api/v1/analyze",
json={
"url": "invalid-url",
"keywords": ["SEO"],
"max_length": 5000
},
headers={"Authorization": "Bearer test_token"}
)
assert response.status_code == 422
errors = response.json()["detail"]
assert any("url" in error["loc"] for error in errors)
Integration Testing:
# tests/test_integration.py
import pytest
from httpx import AsyncClient
from app.main import app
@pytest.mark.asyncio
async def test_full_workflow():
async with AsyncClient(app=app, base_url="http://test") as client:
# 1. Create user
user_response = await client.post(
"/api/v1/users",
json={
"email": "test@example.com",
"password": "securepassword"
}
)
assert user_response.status_code == 201
user_data = user_response.json()
# 2. Login and get token
login_response = await client.post(
"/api/v1/auth/login",
json={
"email": "test@example.com",
"password": "securepassword"
}
)
assert login_response.status_code == 200
token = login_response.json()["access_token"]
# 3. Analyze content
analysis_response = await client.post(
"/api/v1/analyze",
json={
"url": "https://example.com/article",
"keywords": ["SEO"]
},
headers={"Authorization": f"Bearer {token}"}
)
assert analysis_response.status_code == 200
🚀 Performance Optimization
Database Optimization
Query Optimization:
# Use specific columns instead of SELECT *
async def get_user_analysis_history(user_id: int, limit: int = 50):
query = """
SELECT
a.id,
a.url,
a.score,
a.created_at,
COUNT(ac.id) as content_count
FROM analyses a
LEFT JOIN analysis_content ac ON a.id = ac.analysis_id
WHERE a.user_id = :user_id
GROUP BY a.id, a.url, a.score, a.created_at
ORDER BY a.created_at DESC
LIMIT :limit
"""
result = await database.execute(
query,
{"user_id": user_id, "limit": limit}
)
return result.fetchall()
Connection Pooling:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
# Optimize connection pool for production
engine = create_async_engine(
DATABASE_URL,
pool_size=20, # Number of connections to maintain
max_overflow=30, # Additional connections when pool is full
pool_pre_ping=True, # Validate connections before use
pool_recycle=3600, # Recycle connections after 1 hour
echo=False # Disable SQL logging in production
)
async_session = sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)
Caching Strategies
Redis Caching:
import redis
import json
from functools import wraps
redis_client = redis.Redis(
host='localhost',
port=6379,
decode_responses=True
)
def cache_result(expiration: int = 3600):
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
# Create cache key
cache_key = f"{func.__name__}:{hash(str(args) + str(kwargs))}"
# Try to get from cache
cached_result = redis_client.get(cache_key)
if cached_result:
return json.loads(cached_result)
# Execute function and cache result
result = await func(*args, **kwargs)
redis_client.setex(
cache_key,
expiration,
json.dumps(result, default=str)
)
return result
return wrapper
return decorator
@cache_result(expiration=1800) # 30 minutes
async def analyze_serp(keyword: str):
# Expensive SERP analysis
return serp_analyzer.analyze(keyword)
🛡️ Security Implementation
SQL Injection Prevention:
# ❌ Vulnerable - Never use string formatting
query = f"SELECT * FROM users WHERE email = '{email}'"
# ✅ Safe - Use parameterized queries
query = "SELECT * FROM users WHERE email = :email"
result = await database.execute(query, {"email": email})
XSS Protection:
from fastapi import FastAPI, Request
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
# Security middlewares
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["yourdomain.com"])
app.add_middleware(HTTPSRedirectMiddleware)
# Content Security Policy
@app.middleware("http")
async def add_security_headers(request: Request, call_next):
response = await call_next(request)
response.headers["Content-Security-Policy"] = (
"default-src 'self'; "
"script-src 'self' 'unsafe-inline'; "
"style-src 'self' 'unsafe-inline'; "
"img-src 'self' data: https:; "
"font-src 'self';"
)
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-Content-Type-Options"] = "nosniff"
return response
📊 Resources & Tools
Essential Development Tools
Local Development:
- Docker & Docker Compose - Containerization
- VS Code + Extensions - IDE with Python, Docker, GitLens
- Postman/Insomnia - API testing
- DBeaver - Database management
Testing & Quality:
- Pytest - Testing framework
- Black + isort - Code formatting
- MyPy - Type checking
- Bandit - Security scanning
- Coverage.py - Test coverage
Deployment & Monitoring:
- Railway - Application hosting
- GitHub Actions - CI/CD
- Sentry - Error tracking
- DataDog/New Relic - APM
Learning Resources
Documentation:
Best Practices:
🎯 Quick Start Tutorial
1. Project Setup (15 minutes)
# Create project structure
mkdir fastapi-project
cd fastapi-project
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install fastapi uvicorn sqlalchemy asyncpg
pip install alembic pytest httpx
2. Basic Application (30 minutes)
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="My API", version="1.0.0")
class Item(BaseModel):
name: str
description: str
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.post("/items/")
async def create_item(item: Item):
return {"item": item}
3. Run Locally (5 minutes)
uvicorn main:app --reload
# Visit http://localhost:8000/docs for API documentation
📬 Get Help & Updates
Developer Community:
- Join our Slack for technical discussions
- GitHub issues for bug reports and feature requests
- Weekly office hours for live Q&A
Tutorial Updates:
- Subscribe to our developer newsletter
- Follow on GitHub for new tutorials
- YouTube channel for video walkthroughs
Last updated: January 15, 2026
Total tutorials: 2 published, 6 planned
Average completion time: 45 minutes
Developer satisfaction: 4.8/5
Build production-ready applications with confidence and best practices.