Framework Integrations¶
pyresilience provides built-in integrations for the most popular Python web frameworks.
FastAPI¶
Dependency Injection (Recommended)¶
Use ResilientDependency with FastAPI's Depends() for per-route resilience:
from fastapi import Depends, FastAPI
from pyresilience import ResilienceConfig, RetryConfig, CircuitBreakerConfig
from pyresilience.contrib.fastapi import ResilientDependency
app = FastAPI()
# Create a resilience dependency for the payment service
payment_resilience = ResilientDependency(ResilienceConfig(
retry=RetryConfig(max_attempts=3),
circuit_breaker=CircuitBreakerConfig(failure_threshold=5),
))
@app.post("/charge")
async def charge(
amount: float,
resilience: ResilientDependency = Depends(payment_resilience),
):
return await resilience.call(payment_service.charge, amount)
@app.post("/refund")
async def refund(
amount: float,
resilience: ResilientDependency = Depends(payment_resilience),
):
return await resilience.call(payment_service.refund, amount)
ASGI Middleware¶
Apply resilience to the entire request pipeline:
from fastapi import FastAPI
from pyresilience import ResilienceConfig, TimeoutConfig, CircuitBreakerConfig
from pyresilience.contrib.fastapi import ResilientMiddleware
app = FastAPI()
app.add_middleware(
ResilientMiddleware,
config=ResilienceConfig(
timeout=TimeoutConfig(seconds=30),
circuit_breaker=CircuitBreakerConfig(failure_threshold=10),
),
)
Factory Function¶
For convenience:
from pyresilience.contrib.fastapi import resilient_dependency
payment_dep = resilient_dependency(ResilienceConfig(
retry=RetryConfig(max_attempts=3),
))
@app.post("/charge")
async def charge(resilience=Depends(payment_dep)):
return await resilience.call(charge_service, amount=100)
Django¶
Middleware¶
Apply resilience to all Django views:
# settings.py
MIDDLEWARE = [
# ... other middleware
'pyresilience.contrib.django.ResilientMiddleware',
]
PYRESILIENCE_CONFIG = {
'timeout_seconds': 30,
'circuit_failure_threshold': 10,
'circuit_recovery_seconds': 60,
'max_attempts': 3,
'retry_delay': 1.0,
}
Per-View Decorator¶
Apply resilience to specific views:
from pyresilience.contrib.django import resilient_view
from pyresilience import RetryConfig, TimeoutConfig, CircuitBreakerConfig
@resilient_view(
retry=RetryConfig(max_attempts=3),
timeout=TimeoutConfig(seconds=10),
circuit_breaker=CircuitBreakerConfig(failure_threshold=5),
)
def payment_view(request):
result = payment_service.charge(request.POST['amount'])
return JsonResponse(result)
Flask¶
Extension¶
Apply resilience to your entire Flask app:
from flask import Flask
from pyresilience import ResilienceConfig, TimeoutConfig, CircuitBreakerConfig
from pyresilience.contrib.flask import Resilience
app = Flask(__name__)
resilience = Resilience(app, config=ResilienceConfig(
timeout=TimeoutConfig(seconds=30),
circuit_breaker=CircuitBreakerConfig(failure_threshold=10),
))
# Use directly in views:
@app.route("/data")
def get_data():
return resilience.call(external_api.get_data)
Factory Pattern¶
resilience = Resilience()
def create_app():
app = Flask(__name__)
resilience.init_app(app, config=ResilienceConfig(...))
return app
Per-Route Decorator¶
from pyresilience.contrib.flask import resilient_route
from pyresilience import RetryConfig, TimeoutConfig
@app.route("/data")
@resilient_route(
retry=RetryConfig(max_attempts=3),
timeout=TimeoutConfig(seconds=10),
)
def get_data():
return external_api.get_data()
Using Without Integrations¶
You can always use pyresilience directly with any framework:
from pyresilience import resilient, RetryConfig
@resilient(retry=RetryConfig(max_attempts=3))
async def my_service_call():
return await http_client.get("/api/data")
The framework integrations are convenience wrappers — the core @resilient() decorator works everywhere.
Async Fallback Handlers
When using async frameworks (FastAPI, async Django), your FallbackConfig.handler can be an async function. pyresilience detects this automatically and awaits the handler: