patternpythonfastapiTip
FastAPI lifespan events — startup and shutdown with async context manager
Viewed 0 times
FastAPI 0.93+
lifespanstartupshutdownon_eventapp stateconnection pool
Error Messages
Problem
The old @app.on_event('startup') and @app.on_event('shutdown') decorators are deprecated. Initializing DB connection pools, loading ML models, or starting background services needs a clean async lifecycle.
Solution
Use the lifespan context manager parameter on FastAPI(). Everything before yield runs on startup; everything after yield runs on shutdown. Store shared resources in the app.state dict.
from contextlib import asynccontextmanager
from fastapi import FastAPI
import httpx
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
app.state.http_client = httpx.AsyncClient()
app.state.db_pool = await create_db_pool()
print('App started')
yield
# Shutdown
await app.state.http_client.aclose()
await app.state.db_pool.close()
print('App stopped')
app = FastAPI(lifespan=lifespan)
@app.get('/status')
async def status(request: Request):
# Access shared resource
client = request.app.state.http_client
resp = await client.get('https://api.example.com/health')
return resp.json()Why
The lifespan approach uses a single async context manager, making setup and teardown co-located and easier to reason about. It integrates cleanly with TestClient (the lifespan runs when used as a context manager in tests).
Gotchas
- @app.on_event is deprecated since FastAPI 0.93 — migrate to lifespan
- Exceptions in the startup section (before yield) prevent the app from starting
- app.state is not thread-safe without locks in multi-threaded contexts
- TestClient must be used as a context manager (with TestClient(app) as client:) to trigger lifespan
Context
FastAPI apps that need to initialize or tear down resources at startup/shutdown
Revisions (0)
No revisions yet.