Essential middlewares for FastAPI
Project description
FastAPI Middlewares
Essential middlewares for FastAPI applications.
Features
- 🔍 Request ID Tracking - Unique IDs for request tracing
- ⏱️ Request Timing - Measure response times
- 🔒 Security Headers - OWASP-compliant security headers
- 📝 Structured Logging - JSON-formatted request/response logs
- 🚨 Error Handling - Graceful error responses with tracebacks
- ⚡ Easy Setup - One-line configuration with sensible defaults
Installation
pip install fastapi-middlewares
Or with uv:
uv add fastapi-middlewares
Quick Start
from fastapi import FastAPI
from middlewares import add_essentials
app = FastAPI()
# Add all essential middlewares in one line
add_essentials(app)
@app.get("/")
def root():
return {"message": "Hello World"}
That's it! Your app now has:
- ✅ Request ID tracking
- ✅ Request timing
- ✅ Security headers
- ✅ CORS support
- ✅ Error handling
- ✅ Logging
- ✅ GZip compression
Middlewares
1. Request ID Middleware
Adds a unique ID to each request for tracing.
from fastapi import FastAPI, Request
from middlewares import RequestIDMiddleware
app = FastAPI()
app.add_middleware(RequestIDMiddleware)
@app.get("/users/{user_id}")
def get_user(user_id: int, request: Request):
request_id = request.scope.get("request_id")
return {"user_id": user_id, "request_id": request_id}
Response Headers:
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
Options:
header_name: Custom header name (default: "X-Request-ID")
2. Request Timing Middleware
Tracks how long each request takes.
from middlewares import RequestTimingMiddleware
app.add_middleware(RequestTimingMiddleware)
Response Headers:
X-Process-Time: 0.0245
Options:
header_name: Custom header name (default: "X-Process-Time")
3. Security Headers Middleware
Adds OWASP-recommended security headers to protect against common attacks.
from middlewares import SecurityHeadersMiddleware
app.add_middleware(SecurityHeadersMiddleware)
Default Headers:
Cache-Control: no-store, max-age=0- Prevents caching of sensitive dataContent-Security-Policy: frame-ancestors 'none'- Prevents clickjackingX-Content-Type-Options: nosniff- Prevents MIME-sniffing attacksX-Frame-Options: DENY- Additional clickjacking protectionReferrer-Policy: no-referrer- Prevents URL leakagePermissions-Policy: geolocation=(), microphone=(), camera=()- Disables unnecessary browser featuresStrict-Transport-Security: max-age=31536000; includeSubDomains- HTTPS enforcement (added automatically for HTTPS connections)
The middleware also removes server identification headers (Server, X-Powered-By) to reduce information disclosure.
Custom Headers:
app.add_middleware(
SecurityHeadersMiddleware,
headers={
"Cache-Control": "no-cache",
"Content-Security-Policy": "default-src 'self'",
"Custom-Header": "custom-value"
},
hsts_max_age=63072000 # 2 years
)
Options:
headers: Dict of custom security headers (overrides defaults)hsts_max_age: HSTS max-age in seconds (default: 31536000 = 1 year)
Note: Default headers are compatible with FastAPI's Swagger UI and ReDoc. The middleware respects headers already set by your application routes.
4. Logging Middleware
Logs all requests and responses with structured output.
from middlewares import LoggingMiddleware
app.add_middleware(
LoggingMiddleware,
logger_name="my_app",
skip_paths=["/health", "/metrics"]
)
Log Output:
{
"request_id": "550e8400-...",
"method": "GET",
"path": "/users/123",
"status_code": 200,
"process_time": "0.0245s"
}
Options:
logger_name: Logger name (default: "fastapi_middlewares")skip_paths: Paths to skip logging (default: ["/health", "/metrics"])
5. Error Handling Middleware
Catches exceptions and returns formatted JSON errors.
from middlewares import ErrorHandlingMiddleware
app.add_middleware(
ErrorHandlingMiddleware,
include_traceback=False # Set True for development
)
Error Response:
{
"error": "ValueError",
"message": "Invalid user ID",
"request_id": "550e8400-..."
}
Custom Error Handlers:
from starlette.responses import JSONResponse
async def handle_value_error(scope, exc):
return JSONResponse(
status_code=400,
content={"error": "bad_request", "message": str(exc)}
)
app.add_middleware(
ErrorHandlingMiddleware,
custom_handlers={ValueError: handle_value_error}
)
Options:
include_traceback: Include full traceback (default: False)custom_handlers: Dict mapping exception types to handler functions
6. CORS Middleware
Wrapper around Starlette's CORSMiddleware.
from middlewares import add_cors
add_cors(
app,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
7. GZip Compression
Wrapper around Starlette's GZipMiddleware.
from middlewares import add_gzip
add_gzip(app, minimum_size=1000)
Middleware Ordering
Order matters! Middlewares execute in reverse order of addition.
Recommended Order:
from fastapi import FastAPI
from middlewares import (
ErrorHandlingMiddleware,
SecurityHeadersMiddleware,
RequestIDMiddleware,
RequestTimingMiddleware,
LoggingMiddleware,
add_cors,
add_gzip,
)
app = FastAPI()
# Last added = First executed
add_gzip(app) # 7. Compress response
app.add_middleware(LoggingMiddleware) # 6. Log request/response
app.add_middleware(RequestTimingMiddleware) # 5. Time request
app.add_middleware(RequestIDMiddleware) # 4. Add request ID
app.add_middleware(SecurityHeadersMiddleware) # 3. Add security headers
add_cors(app) # 2. Handle CORS
app.add_middleware(ErrorHandlingMiddleware) # 1. Catch errors (outermost)
Why This Order?
- Error handling first - Catches all exceptions from other middlewares
- CORS early - Handles preflight requests before processing
- Security headers - Added to all responses
- Request ID - Available for all downstream middlewares and logging
- Timing - Measures full request duration
- Logging - Logs complete request/response cycle
- Compression last - Compresses the final response body
Complete Example
from fastapi import FastAPI, HTTPException
from middlewares import add_essentials
app = FastAPI(title="My API")
# Add all middlewares with custom config
add_essentials(
app,
cors_origins=["http://localhost:3000"],
include_traceback=False, # Set True for development
logger_name="my_api"
)
@app.get("/")
def root():
return {"message": "Hello World"}
@app.get("/users/{user_id}")
def get_user(user_id: int):
if user_id < 1:
raise ValueError("Invalid user ID")
return {"user_id": user_id, "name": "John"}
@app.get("/error")
def error():
raise HTTPException(status_code=404, detail="Not found")
Run it:
uvicorn main:app --reload
Test it:
# Check headers
curl -I http://localhost:8000/
# Expected headers:
# X-Request-ID: 550e8400-...
# X-Process-Time: 0.0245
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY
# Cache-Control: no-store, max-age=0
# Content-Security-Policy: frame-ancestors 'none'
# Referrer-Policy: no-referrer
Development
# Clone the repo
git clone https://github.com/mahdijafaridev/fastapi-middlewares.git
cd fastapi-middlewares
# Install dependencies
uv sync
# Run tests
pytest -v
# Run with coverage
pytest --cov=middlewares --cov-report=html
# Run example app
python examples/example_app.py
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE file for details.
Credits
Built with ❤️ for the FastAPI community.
Changelog
See CHANGELOG.md for release history.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_middlewares-0.1.1.tar.gz.
File metadata
- Download URL: fastapi_middlewares-0.1.1.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
595586aeef02a5cee8829020eacd786db3c0353441e6544b497aef273ffd29fd
|
|
| MD5 |
54a8153d77cf5896df7dee7a9505999c
|
|
| BLAKE2b-256 |
2b5a93302c52f05836b9c303bb33001f6d3cdf1044d5045b6d6dc2f23bd87461
|
File details
Details for the file fastapi_middlewares-0.1.1-py3-none-any.whl.
File metadata
- Download URL: fastapi_middlewares-0.1.1-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95763960057e7103befa9978f02206a276edcc8dc4cab26699270c07a7620324
|
|
| MD5 |
f06d30b62989149b602d9c39079043e2
|
|
| BLAKE2b-256 |
27297a801aac427ec6fb832790427fa8659d5808bdd6023590d2a0ad0df65c48
|