593 lines
13 KiB
Markdown
593 lines
13 KiB
Markdown
# Python Backend Technology Stack Recommendations
|
|
|
|
This document provides curated recommendations for common technology choices in Python backend development.
|
|
|
|
## Web Frameworks
|
|
|
|
### FastAPI (Recommended for Modern APIs)
|
|
**Best for:** Microservices, RESTful APIs, async-first applications
|
|
|
|
**Pros:**
|
|
- Automatic OpenAPI/Swagger documentation
|
|
- Built-in request/response validation with Pydantic
|
|
- High performance (comparable to Node.js/Go)
|
|
- Native async/await support
|
|
- Type hints and IDE support
|
|
- Modern Python features
|
|
|
|
**Cons:**
|
|
- Smaller ecosystem compared to Django
|
|
- Less built-in features (need to integrate more libraries)
|
|
- Newer framework (less mature)
|
|
|
|
**When to use:**
|
|
- Building new REST or GraphQL APIs
|
|
- High-performance requirements
|
|
- Microservices architecture
|
|
- Team comfortable with modern Python
|
|
|
|
### Django (Recommended for Full-Featured Applications)
|
|
**Best for:** Monolithic applications, admin-heavy apps, rapid development
|
|
|
|
**Pros:**
|
|
- Batteries-included (ORM, admin, auth, forms, etc.)
|
|
- Massive ecosystem and community
|
|
- Battle-tested and mature
|
|
- Excellent documentation
|
|
- Built-in admin interface
|
|
- Strong security defaults
|
|
|
|
**Cons:**
|
|
- Heavier framework
|
|
- Less suitable for microservices
|
|
- Async support is newer and limited
|
|
- More opinionated structure
|
|
|
|
**When to use:**
|
|
- Building full-featured web applications
|
|
- Need admin interface out of the box
|
|
- Rapid prototyping
|
|
- Team prefers convention over configuration
|
|
|
|
### Flask (Recommended for Simple APIs)
|
|
**Best for:** Small to medium applications, prototypes, simple APIs
|
|
|
|
**Pros:**
|
|
- Lightweight and flexible
|
|
- Easy to learn
|
|
- Large ecosystem of extensions
|
|
- Minimal boilerplate
|
|
- Great for prototypes
|
|
|
|
**Cons:**
|
|
- Requires more setup for production
|
|
- No built-in async support (requires extensions)
|
|
- Need to choose and integrate many components
|
|
- Less structure by default
|
|
|
|
**When to use:**
|
|
- Small to medium applications
|
|
- Prototypes and MVPs
|
|
- Learning Python web development
|
|
- Need maximum flexibility
|
|
|
|
## Async Frameworks
|
|
|
|
### Comparison
|
|
| Feature | FastAPI | Starlette | Quart | aiohttp |
|
|
|---------|---------|-----------|-------|---------|
|
|
| Performance | Excellent | Excellent | Good | Excellent |
|
|
| Documentation | Excellent | Good | Good | Good |
|
|
| Ease of Use | Excellent | Good | Excellent | Moderate |
|
|
| Community | Growing | Moderate | Small | Moderate |
|
|
| Best For | APIs | Custom apps | Flask users | Low-level control |
|
|
|
|
## Database Solutions
|
|
|
|
### PostgreSQL (Recommended for Most Cases)
|
|
**Best for:** Production applications requiring ACID compliance
|
|
|
|
**Pros:**
|
|
- ACID compliant
|
|
- Rich feature set (JSONB, full-text search, etc.)
|
|
- Excellent performance
|
|
- Strong community
|
|
- Great for complex queries
|
|
|
|
**Libraries:**
|
|
- `asyncpg` - Fastest async driver
|
|
- `psycopg2` - Traditional sync driver
|
|
- `psycopg3` - Modern sync/async driver
|
|
|
|
### MySQL/MariaDB
|
|
**Best for:** Applications with heavy read operations
|
|
|
|
**Pros:**
|
|
- Fast read performance
|
|
- Wide hosting support
|
|
- Good replication
|
|
- Mature ecosystem
|
|
|
|
**Libraries:**
|
|
- `aiomysql` - Async driver
|
|
- `mysqlclient` - Sync driver (fastest)
|
|
- `PyMySQL` - Pure Python sync driver
|
|
|
|
### MongoDB
|
|
**Best for:** Flexible schema, document-oriented data
|
|
|
|
**Pros:**
|
|
- Schema flexibility
|
|
- Horizontal scaling
|
|
- Good for rapid development
|
|
- Rich query language
|
|
|
|
**Libraries:**
|
|
- `motor` - Async driver (recommended)
|
|
- `pymongo` - Sync driver
|
|
|
|
### Redis
|
|
**Best for:** Caching, sessions, real-time features
|
|
|
|
**Pros:**
|
|
- Extremely fast
|
|
- Rich data structures
|
|
- Pub/sub support
|
|
- Good for caching and sessions
|
|
|
|
**Libraries:**
|
|
- `redis-py` - Official client with async support
|
|
- `aioredis` - Async-first client (now merged into redis-py)
|
|
|
|
## ORM Solutions
|
|
|
|
### SQLAlchemy (Recommended)
|
|
**Best for:** Complex queries, database agnostic code
|
|
|
|
**Pros:**
|
|
- Most mature Python ORM
|
|
- Powerful query API
|
|
- Database agnostic
|
|
- Great documentation
|
|
- Good async support (2.0+)
|
|
|
|
**Cons:**
|
|
- Steeper learning curve
|
|
- More verbose than alternatives
|
|
|
|
```python
|
|
# Async SQLAlchemy 2.0
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import declarative_base, sessionmaker
|
|
|
|
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
|
|
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
```
|
|
|
|
### Tortoise ORM
|
|
**Best for:** Async-first applications, Django-like syntax
|
|
|
|
**Pros:**
|
|
- Built for async from the ground up
|
|
- Django-like API
|
|
- Easy to learn
|
|
- Good documentation
|
|
|
|
**Cons:**
|
|
- Smaller community
|
|
- Fewer features than SQLAlchemy
|
|
- Limited database support
|
|
|
|
```python
|
|
from tortoise import fields, models
|
|
from tortoise.contrib.fastapi import register_tortoise
|
|
|
|
class User(models.Model):
|
|
id = fields.IntField(pk=True)
|
|
email = fields.CharField(max_length=255, unique=True)
|
|
name = fields.CharField(max_length=255)
|
|
```
|
|
|
|
### Django ORM
|
|
**Best for:** Django projects
|
|
|
|
**Pros:**
|
|
- Integrated with Django
|
|
- Simple and intuitive
|
|
- Excellent documentation
|
|
- Good async support (3.1+)
|
|
|
|
**Cons:**
|
|
- Tied to Django
|
|
- Less powerful than SQLAlchemy for complex queries
|
|
|
|
## API Documentation
|
|
|
|
### OpenAPI/Swagger (FastAPI Built-in)
|
|
**Recommended for:** REST APIs
|
|
|
|
**Libraries:**
|
|
- FastAPI includes automatic generation
|
|
- `flasgger` for Flask
|
|
- `drf-spectacular` for Django REST Framework
|
|
|
|
### GraphQL
|
|
|
|
**Strawberry (Recommended for FastAPI)**
|
|
```python
|
|
import strawberry
|
|
from fastapi import FastAPI
|
|
from strawberry.fastapi import GraphQLRouter
|
|
|
|
@strawberry.type
|
|
class Query:
|
|
@strawberry.field
|
|
def hello(self) -> str:
|
|
return "Hello World"
|
|
|
|
schema = strawberry.Schema(query=Query)
|
|
graphql_app = GraphQLRouter(schema)
|
|
```
|
|
|
|
**Other Options:**
|
|
- `Graphene` - Mature, works with Django
|
|
- `Ariadne` - Schema-first approach
|
|
|
|
## Authentication & Authorization
|
|
|
|
### JWT Authentication
|
|
**Libraries:**
|
|
- `python-jose[cryptography]` - Recommended for JWT
|
|
- `PyJWT` - Lightweight alternative
|
|
|
|
```python
|
|
from jose import JWTError, jwt
|
|
from datetime import datetime, timedelta
|
|
|
|
def create_access_token(data: dict):
|
|
to_encode = data.copy()
|
|
expire = datetime.utcnow() + timedelta(minutes=15)
|
|
to_encode.update({"exp": expire})
|
|
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
|
```
|
|
|
|
### OAuth2
|
|
**Libraries:**
|
|
- `authlib` - Comprehensive OAuth client/server
|
|
- `python-social-auth` - Social authentication
|
|
|
|
### Password Hashing
|
|
**Libraries:**
|
|
- `passlib[bcrypt]` - Recommended
|
|
- `argon2-cffi` - Most secure (memory-hard)
|
|
|
|
```python
|
|
from passlib.context import CryptContext
|
|
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
|
|
def hash_password(password: str) -> str:
|
|
return pwd_context.hash(password)
|
|
|
|
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
|
return pwd_context.verify(plain_password, hashed_password)
|
|
```
|
|
|
|
## Task Queues
|
|
|
|
### Celery (Recommended for Most Cases)
|
|
**Best for:** Complex workflows, scheduled tasks
|
|
|
|
**Pros:**
|
|
- Mature and battle-tested
|
|
- Rich feature set
|
|
- Good monitoring tools
|
|
- Supports multiple brokers
|
|
|
|
**Cons:**
|
|
- Complex configuration
|
|
- Heavy dependency
|
|
|
|
```python
|
|
from celery import Celery
|
|
|
|
app = Celery('tasks', broker='redis://localhost:6379/0')
|
|
|
|
@app.task
|
|
def process_data(data):
|
|
# Long-running task
|
|
pass
|
|
```
|
|
|
|
### RQ (Redis Queue)
|
|
**Best for:** Simple job queues
|
|
|
|
**Pros:**
|
|
- Simple to use
|
|
- Lightweight
|
|
- Good for simple tasks
|
|
|
|
**Cons:**
|
|
- Less features than Celery
|
|
- Only works with Redis
|
|
|
|
### Dramatiq
|
|
**Best for:** Alternatives to Celery
|
|
|
|
**Pros:**
|
|
- Simpler than Celery
|
|
- Good performance
|
|
- Type-safe
|
|
|
|
**Cons:**
|
|
- Smaller community
|
|
|
|
## Validation & Serialization
|
|
|
|
### Pydantic (Recommended)
|
|
**Best for:** Data validation, settings management
|
|
|
|
```python
|
|
from pydantic import BaseModel, EmailStr, validator
|
|
|
|
class User(BaseModel):
|
|
id: int
|
|
email: EmailStr
|
|
name: str
|
|
age: int
|
|
|
|
@validator('age')
|
|
def validate_age(cls, v):
|
|
if v < 0:
|
|
raise ValueError('Age must be positive')
|
|
return v
|
|
```
|
|
|
|
### Marshmallow
|
|
**Best for:** Flask applications, complex serialization
|
|
|
|
## HTTP Clients
|
|
|
|
### httpx (Recommended)
|
|
**Best for:** Modern async/sync HTTP client
|
|
|
|
```python
|
|
import httpx
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get('https://api.example.com')
|
|
```
|
|
|
|
### aiohttp
|
|
**Best for:** Async-only applications
|
|
|
|
### requests
|
|
**Best for:** Sync-only applications (legacy)
|
|
|
|
## Testing
|
|
|
|
### pytest (Recommended)
|
|
**Essential plugins:**
|
|
- `pytest-asyncio` - Async test support
|
|
- `pytest-cov` - Coverage reporting
|
|
- `pytest-mock` - Mocking utilities
|
|
- `pytest-xdist` - Parallel testing
|
|
|
|
```python
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_user(client: AsyncClient):
|
|
response = await client.post("/users", json={"email": "test@example.com"})
|
|
assert response.status_code == 201
|
|
```
|
|
|
|
### Other Tools
|
|
- `coverage` - Code coverage
|
|
- `faker` - Test data generation
|
|
- `factory_boy` - Test fixtures
|
|
- `responses` - Mock HTTP requests
|
|
|
|
## Observability
|
|
|
|
### Logging
|
|
**Recommended:**
|
|
- `structlog` - Structured logging
|
|
- `python-json-logger` - JSON logging
|
|
- Built-in `logging` module
|
|
|
|
### Metrics
|
|
**Recommended:**
|
|
- `prometheus-client` - Prometheus metrics
|
|
- `statsd` - StatsD client
|
|
|
|
### Tracing
|
|
**Recommended:**
|
|
- `opentelemetry-api` + `opentelemetry-sdk` - OpenTelemetry
|
|
- `ddtrace` - DataDog APM
|
|
- `sentry-sdk` - Error tracking
|
|
|
|
```python
|
|
from opentelemetry import trace
|
|
from opentelemetry.sdk.trace import TracerProvider
|
|
|
|
trace.set_tracer_provider(TracerProvider())
|
|
tracer = trace.get_tracer(__name__)
|
|
|
|
with tracer.start_as_current_span("process_data"):
|
|
# Your code here
|
|
pass
|
|
```
|
|
|
|
## Security
|
|
|
|
### Security Headers
|
|
```python
|
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["https://example.com"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
```
|
|
|
|
### Security Libraries
|
|
- `bandit` - Security linting
|
|
- `safety` - Dependency vulnerability scanning
|
|
- `python-dotenv` - Environment variable management
|
|
|
|
## Development Tools
|
|
|
|
### Code Quality
|
|
- `ruff` - Fast linter and formatter (recommended)
|
|
- `black` - Code formatter
|
|
- `isort` - Import sorting
|
|
- `mypy` - Static type checking
|
|
- `pylint` - Comprehensive linting
|
|
|
|
### Dependency Management
|
|
- `poetry` - Recommended for modern projects
|
|
- `pdm` - Fast alternative to poetry
|
|
- `pip-tools` - Minimal approach (pip-compile)
|
|
|
|
### Pre-commit Hooks
|
|
```yaml
|
|
# .pre-commit-config.yaml
|
|
repos:
|
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
rev: v0.1.6
|
|
hooks:
|
|
- id: ruff
|
|
args: [--fix]
|
|
- id: ruff-format
|
|
|
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
rev: v1.7.1
|
|
hooks:
|
|
- id: mypy
|
|
```
|
|
|
|
## Deployment
|
|
|
|
### ASGI Servers
|
|
- `uvicorn` - Recommended for FastAPI
|
|
- `hypercorn` - HTTP/2 support
|
|
- `daphne` - Django channels
|
|
|
|
### WSGI Servers
|
|
- `gunicorn` - Recommended for Django/Flask
|
|
- `uwsgi` - Alternative option
|
|
|
|
### Production Setup
|
|
```bash
|
|
# Uvicorn with Gunicorn (recommended for production)
|
|
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
|
|
```
|
|
|
|
## Configuration Management
|
|
|
|
### Pydantic Settings (Recommended)
|
|
```python
|
|
from pydantic_settings import BaseSettings
|
|
|
|
class Settings(BaseSettings):
|
|
database_url: str
|
|
redis_url: str
|
|
secret_key: str
|
|
|
|
class Config:
|
|
env_file = ".env"
|
|
```
|
|
|
|
### python-decouple
|
|
Simple alternative for basic configuration
|
|
|
|
## Message Brokers
|
|
|
|
### RabbitMQ
|
|
**Best for:** Complex routing, guaranteed delivery
|
|
|
|
**Libraries:**
|
|
- `aio-pika` - Async AMQP client
|
|
|
|
### Apache Kafka
|
|
**Best for:** Event streaming, high throughput
|
|
|
|
**Libraries:**
|
|
- `aiokafka` - Async Kafka client
|
|
- `confluent-kafka` - High-performance client
|
|
|
|
### Redis Pub/Sub
|
|
**Best for:** Simple pub/sub, low latency
|
|
|
|
**Libraries:**
|
|
- `redis-py` with pub/sub support
|
|
|
|
## Recommended Stack Combinations
|
|
|
|
### Modern Microservices Stack
|
|
- Framework: FastAPI
|
|
- Database: PostgreSQL (asyncpg)
|
|
- ORM: SQLAlchemy 2.0 (async)
|
|
- Cache: Redis
|
|
- Task Queue: Celery or Dramatiq
|
|
- Validation: Pydantic
|
|
- Testing: pytest + httpx
|
|
- Observability: OpenTelemetry + Sentry
|
|
- Deployment: Uvicorn + Docker + Kubernetes
|
|
|
|
### Traditional Monolith Stack
|
|
- Framework: Django
|
|
- Database: PostgreSQL (psycopg2)
|
|
- ORM: Django ORM
|
|
- Cache: Redis
|
|
- Task Queue: Celery
|
|
- API: Django REST Framework
|
|
- Testing: pytest-django
|
|
- Deployment: Gunicorn + Docker
|
|
|
|
### Lightweight API Stack
|
|
- Framework: Flask or FastAPI
|
|
- Database: PostgreSQL or MongoDB
|
|
- ORM: SQLAlchemy or Motor
|
|
- Testing: pytest
|
|
- Deployment: Uvicorn or Gunicorn
|
|
|
|
## Version Recommendations (as of 2025)
|
|
|
|
```toml
|
|
# pyproject.toml
|
|
[tool.poetry.dependencies]
|
|
python = "^3.11" # Python 3.11+ recommended for performance
|
|
fastapi = "^0.110.0"
|
|
uvicorn = {extras = ["standard"], version = "^0.27.0"}
|
|
sqlalchemy = "^2.0.25"
|
|
asyncpg = "^0.29.0"
|
|
pydantic = "^2.5.0"
|
|
pydantic-settings = "^2.1.0"
|
|
redis = "^5.0.1"
|
|
celery = "^5.3.4"
|
|
python-jose = {extras = ["cryptography"], version = "^3.3.0"}
|
|
passlib = {extras = ["bcrypt"], version = "^1.7.4"}
|
|
httpx = "^0.26.0"
|
|
structlog = "^24.1.0"
|
|
opentelemetry-api = "^1.22.0"
|
|
opentelemetry-sdk = "^1.22.0"
|
|
sentry-sdk = "^1.39.0"
|
|
|
|
[tool.poetry.group.dev.dependencies]
|
|
pytest = "^7.4.4"
|
|
pytest-asyncio = "^0.23.3"
|
|
pytest-cov = "^4.1.0"
|
|
ruff = "^0.1.9"
|
|
mypy = "^1.8.0"
|
|
```
|
|
|
|
This technology stack provides battle-tested, production-ready solutions for Python backend development in 2025.
|