fast_middleware
HTTP middleware for FastAPI / Starlette in the FastMVC monorepo. The installable package is fastmiddleware (import from fastmiddleware import …); PyPI name is fast-middleware. It ships 90+ ASGI middlewares—request correlation IDs (via fast_platform), security headers, rate limiting, sessions, caching, i18n, routing helpers, build/version headers, immutable static asset caching, DNS prefetch control, and more. This package is not the same as fast_tenancy (tenant resolution) or fast_platform (configuration DTOs); it focuses on cross-cutting ASGI behavior you mount on your FastAPI app.
The tests/ directory also contains legacy suites that target an optional fastmiddleware package (not installed by default). The default pytest configuration only runs the lightweight fast_middleware tests—see python_files in pyproject.toml.
Layout
Source lives under src/, mapped to the fastmiddleware package (see package-dir in pyproject.toml):
| Section | Path | Role |
|---|---|---|
| mw_core | src/mw_core/ |
Factory helpers, CORS, logging, timing, body limits, client IP, request ID, compression |
| sec | src/sec/ |
Security headers, CSRF, auth backends, JWT bearer, webhooks, trusted hosts, etc. |
| operations | src/operations/ |
Rate limits, metrics, health, sessions, caching, i18n, routing, build/version, immutable static cache, DNS prefetch, etc. |
See src/taxonomy.py for the section map.
Install
From the monorepo (if your project vendors this tree):
pip install -e ./fast_middleware
Usage
from fastapi import FastAPI
from fastmiddleware import (
RequestIDMiddleware,
SecurityHeadersConfig,
SecurityHeadersMiddleware,
ResponseTimingMiddleware,
)
app = FastAPI()
app.add_middleware(RequestIDMiddleware)
app.add_middleware(
SecurityHeadersMiddleware,
config=SecurityHeadersConfig(
hsts_max_age=31536000,
hsts_include_subdomains=True,
csp_frame_ancestors="'self'",
),
)
app.add_middleware(ResponseTimingMiddleware) # X-Response-Time (seconds by default)
CORS preset (SPA)
from starlette.middleware.cors import CORSMiddleware
from fastmiddleware import CORSPreset
preset = CORSPreset(allow_origins=["https://app.example.com"], allow_credentials=True)
app.add_middleware(CORSMiddleware, **preset.starlette_kwargs())
Body size limit (DoS guard)
Checks Content-Length before the handler runs; use a reverse-proxy limit for chunked uploads without Content-Length.
from fastmiddleware import BodySizeLimitMiddleware
app.add_middleware(BodySizeLimitMiddleware, max_bytes=512_000)
Client IP (proxies)
from fastmiddleware import ClientIPMiddleware, get_client_ip, read_client_ip
app.add_middleware(ClientIPMiddleware, trusted_proxy_depth=1)
@app.get("/who")
async def who(request):
return {"ip": read_client_ip(request) or get_client_ip(request)}
Set trusted_proxy_depth=0 to ignore X-Forwarded-For when the app is not behind a trusted proxy.
Compression (gzip)
Starlette ships GZipMiddleware only (no brotli). Use a CDN or server-level brotli if needed.
from fastmiddleware import CompressionPreset
CompressionPreset(minimum_size=500).add_to_app(app)
Build / version headers (support & deploys)
Expose release metadata on every response (APP_VERSION and GIT_SHA by default):
from fastmiddleware import BuildVersionMiddleware, BuildVersionConfig
app.add_middleware(
BuildVersionMiddleware,
config=BuildVersionConfig(
version_header="X-App-Version",
git_sha_header="X-Git-SHA",
),
)
Immutable cache for static assets
Use with fingerprinted filenames (app.[hash].js). Adds Cache-Control: public, max-age=…, immutable for matching path prefixes.
from fastmiddleware import ImmutableStaticCacheMiddleware, ImmutableStaticCacheConfig
app.add_middleware(
ImmutableStaticCacheMiddleware,
config=ImmutableStaticCacheConfig(
path_prefixes=("/static/", "/assets/"),
max_age_seconds=31_536_000,
),
)
DNS prefetch control (privacy)
from fastmiddleware import DNSPrefetchControlMiddleware
app.add_middleware(DNSPrefetchControlMiddleware) # X-DNS-Prefetch-Control: off
Edge performance tiers (CDN-class cache semantics)
Preset Cache-Control shapes for apps behind Cloudflare / Fastly / CloudFront—analogous to feed (Instagram-class), creator (subscription / mixed public–private), and live (Twitch-class low-latency) products. Sets s-maxage, stale-while-revalidate, optional CDN-Cache-Control and Surrogate-Control, plus Vary. Does not replace Cache-Control your handlers already set when only_if_missing=True (default).
from fastmiddleware import (
EdgePerformanceTier,
EdgeTierCacheHeadersConfig,
EdgeTierCacheHeadersMiddleware,
)
app.add_middleware(
EdgeTierCacheHeadersMiddleware,
config=EdgeTierCacheHeadersConfig(tier=EdgePerformanceTier.FEED),
)
# Use EdgePerformanceTier.CREATOR for mixed public catalog + private APIs,
# EdgePerformanceTier.LIVE for short-TTL / no-store live paths, or
# EdgePerformanceTier.VOD for Netflix-class catalogue + playback split (long
# edge SWR on metadata, private playback/license APIs, immutable posters).
Pair with CompressionPreset, ImmutableStaticCacheMiddleware, and ResponseCacheMiddleware for origin shielding.
Factory helpers
from fastmiddleware import create_middleware, middleware, MiddlewareBuilder, quick_middleware
Use these when you need a small custom middleware without a new module file.
Related packages
fast_tenancy—TenantMiddlewareand tenant context (different concern).fast_platform— app config; not HTTP middleware.- Monorepo: ../README.md.
Tooling
If this folder includes CONTRIBUTING.md, Makefile, and PUBLISHING.md (synced from tooling scripts), use them for tests and lint.
Documentation
| Document | Purpose |
|---|---|
| CONTRIBUTING.md | Dev setup, tests, monorepo sync |
| PUBLISHING.md | PyPI and releases |
| SECURITY.md | Reporting vulnerabilities |
| CHANGELOG.md | Version history |
Monorepo: ../README.md · Coverage: ../docs/COVERAGE.md
Metadata
Release files for fast-middleware 1.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fast_middleware-1.6.0.tar.gz | 171.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fast_middleware-1.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 380.4 kB
Release files / fast_middleware-1.6.0.tar.gz
| Download URL | fast_middleware-1.6.0.tar.gz |
|---|---|
| Size | 171.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ceefbf75cbd444a458018fe872889675e6674d4ef755b54e736d744f56d6a471
|
|
BLAKE2b-256 checksum How to use checksums |
4234d8a35543e596035ee5cb2626d1ff0c54f123bb4646deb5c4a65ed0176760
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / fast_middleware-1.6.0-py3-none-any.whl
| Download URL | fast_middleware-1.6.0-py3-none-any.whl |
|---|---|
| Size | 209.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ecd3f12bfe5e987cce038791e25c134c9e0e36135bef0c4b84f7d2f96f197e9c
|
|
BLAKE2b-256 checksum How to use checksums |
ea7068d8ef534836dba93ac6eba815f21cf9b4bddaf4b377f5da97ed6b095374
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|