A composable request processing pipeline for FastAPI
Project description
fastapi-request-pipeline
A composable, type-safe request processing pipeline for FastAPI. Build clean, maintainable APIs with reusable components for authentication, permissions, rate limiting, and more.
Features
- Composable Architecture - Build complex request flows from simple, reusable FlowComponent instances
- Type-Safe - Full type hints with strict mypy checking
- Built-in Components - Authentication (JWT, API Key, Cookie), permissions, rate limiting, pagination, filters
- Flow Composition - Layer and merge flows at app, router, and route levels
- OpenAPI Integration - Automatic OpenAPI schema enrichment with security requirements
- Debug Mode - Detailed execution traces for development
- Extensible - Easy to create custom FlowComponent subclasses
- Production Ready - Comprehensive test suite and production usage
Quick Start
pip install fastapi-request-pipeline
from fastapi import FastAPI, Depends
from fastapi_request_pipeline import (
Flow,
JWTAuthentication,
HasRole,
RateLimit,
RequestContext,
flow_dependency,
enrich_openapi,
)
app = FastAPI()
# Define your flow
async def decode_jwt(token: str) -> dict:
# Your JWT decoding logic
return {"sub": "user123", "roles": ["admin"]}
admin_flow = Flow(
JWTAuthentication(decode=decode_jwt),
HasRole("admin"),
RateLimit(rate=100, window_seconds=60),
)
# Use as dependency
@app.get("/admin/dashboard")
async def admin_dashboard(
ctx: RequestContext = Depends(flow_dependency(admin_flow))
):
return {"user": ctx.user, "message": "Welcome, admin!"}
# Enrich OpenAPI schema
enrich_openapi(app)
Core Concepts
Flow
A Flow is an ordered container of FlowComponent instances that process requests sequentially. FlowComponent instances are automatically sorted by ComponentCategory to ensure proper execution order (authentication → permissions → feature flags → throttling → filters → pagination → custom).
flow = Flow(
JWTAuthentication(decode=decode_jwt),
HasPermission("posts:write"),
RateLimit(rate=100, window_seconds=60),
)
Built-in FlowComponent Classes
Built-in FlowComponent classes:
Authentication
JWTAuthentication- Bearer token authenticationAPIKeyAuthentication- API key in headersCookieAuthentication- Session cookiesAllowAnonymous- Skip authentication
Permissions
Authenticated- Require authenticated userHasRole- Role-based access controlHasPermission- Permission-based access control
Rate Limiting
RateLimit- Configurable rate limiting with pluggable backendsInMemoryThrottleBackend- Default in-memory backend- Custom backends (e.g., Redis) via
ThrottleBackendprotocol
Filters & Pagination
QueryFilter- Extract selected query parameters into RequestContext.stateLimitOffset- Offset-based pagination
Flow Composition
Compose flows at different levels with merge_flows():
from fastapi_request_pipeline import merge_flows, OverrideFlow, DisableFlow
# Application-wide defaults
app_flow = Flow(
JWTAuthentication(decode=decode_jwt),
RateLimit(rate=1000, window_seconds=3600)
)
# Router-specific additions
admin_flow = Flow(HasRole("admin"))
# Route-specific overrides
public_flow = Flow(OverrideFlow(AllowAnonymous()))
# Merge with last-writer-wins per category
final_flow = merge_flows(app_flow, admin_flow, public_flow)
Custom FlowComponent Subclasses
Create custom FlowComponent subclasses by extending the base class:
from fastapi_request_pipeline import FlowComponent, ComponentCategory
class AuditLog(FlowComponent):
category = ComponentCategory.CUSTOM
async def resolve(self, ctx: RequestContext) -> None:
await log_request(ctx.user, ctx.request.url.path)
Documentation
- User Guide - Comprehensive guide with examples
- API Reference - Complete API documentation
- CI/CD and Release Guide - Versioning rules, GitHub Releases, TestPyPI/PyPI publish pipeline
- Examples - Working code examples
Requirements
- Python 3.11+
- FastAPI 0.100+
Development
# Install with dev dependencies
uv sync --extra dev
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov
# Lint
uv run ruff check .
# Format
uv run ruff format .
# Type check
uv run mypy --strict src/
Why Use This Library?
Instead of this:
@app.get("/posts")
async def get_posts(request: Request):
# Authentication
token = request.headers.get("Authorization")
if not token or not token.startswith("Bearer "):
raise HTTPException(401)
user = decode_jwt(token[7:])
# Permission check
if "posts:read" not in user.permissions:
raise HTTPException(403)
# Rate limiting
if not check_rate_limit(user.id):
raise HTTPException(429)
# Pagination
limit = int(request.query_params.get("limit", 20))
offset = int(request.query_params.get("offset", 0))
# Business logic
return get_posts_from_db(limit, offset)
Write this:
posts_flow = Flow(
JWTAuthentication(decode=decode_jwt),
HasPermission("posts:read"),
RateLimit(rate=100, window_seconds=60),
LimitOffset(default_limit=20),
)
@app.get("/posts")
async def get_posts(ctx: RequestContext = Depends(flow_dependency(posts_flow))):
pagination = ctx.state["pagination"]
return get_posts_from_db(pagination["limit"], pagination["offset"])
Benefits:
- Separation of concerns - Security logic separated from business logic
- Reusability - Define flows once, use across multiple endpoints
- Composability - Mix and match FlowComponent instances, override at any level
- Maintainability - Changes to auth/permissions in one place
- Type safety - Full type hints and IDE support
- Testability - FlowComponent instances are easy to unit test
- Documentation - OpenAPI schema automatically reflects security requirements
License
MIT
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_request_pipeline-0.1.3.tar.gz.
File metadata
- Download URL: fastapi_request_pipeline-0.1.3.tar.gz
- Upload date:
- Size: 102.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7434088f085c5358c85ec06aac6310095375ff480b451bbe97f2d1c58fa4c99
|
|
| MD5 |
1a409c41954ee1a603dea69c582eab06
|
|
| BLAKE2b-256 |
910fdd961b749d50d4cff04767a4527ef204021e89b40e18f23eb441ca08a3ad
|
Provenance
The following attestation bundles were made for fastapi_request_pipeline-0.1.3.tar.gz:
Publisher:
release.yml on MaksimShevtsov/fastapi-request-pipeline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_request_pipeline-0.1.3.tar.gz -
Subject digest:
a7434088f085c5358c85ec06aac6310095375ff480b451bbe97f2d1c58fa4c99 - Sigstore transparency entry: 976353713
- Sigstore integration time:
-
Permalink:
MaksimShevtsov/fastapi-request-pipeline@aa910199f29742f7bca4fb53242f405f53847de1 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/MaksimShevtsov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@aa910199f29742f7bca4fb53242f405f53847de1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file fastapi_request_pipeline-0.1.3-py3-none-any.whl.
File metadata
- Download URL: fastapi_request_pipeline-0.1.3-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f21cdd93dd27c33eaafd0497307a0eed440263d0cc948be1e356ee045aaa7f0a
|
|
| MD5 |
6fc5a8766f22738cb8c368a3e991f963
|
|
| BLAKE2b-256 |
3a40bff850368bb37f78e930c70db203dcf437e1b72deea339e51bae84e17cd7
|
Provenance
The following attestation bundles were made for fastapi_request_pipeline-0.1.3-py3-none-any.whl:
Publisher:
release.yml on MaksimShevtsov/fastapi-request-pipeline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_request_pipeline-0.1.3-py3-none-any.whl -
Subject digest:
f21cdd93dd27c33eaafd0497307a0eed440263d0cc948be1e356ee045aaa7f0a - Sigstore transparency entry: 976353714
- Sigstore integration time:
-
Permalink:
MaksimShevtsov/fastapi-request-pipeline@aa910199f29742f7bca4fb53242f405f53847de1 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/MaksimShevtsov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@aa910199f29742f7bca4fb53242f405f53847de1 -
Trigger Event:
release
-
Statement type: