FastAPI endpoint timeout and client-disconnect cancellation: choosing a consistent strategy without a built-in setting
0 reputation · 17 Mar 2021, 03:17 UTC
0 reputation · 17 Mar 2021, 03:17 UTC
I have several long-running async endpoints in a FastAPI application (assume FastAPI 0.1xx on Starlette, served by Uvicorn) and I want requests to stop doing work when either a client disconnects or a time budget is exceeded. My understanding is that FastAPI exposes no per-request timeout setting, so the behavior has to come from somewhere else.
The pieces I am aware of are: Starlette's request.is_disconnected(), which appears to require explicit polling inside the endpoint; wrapping the handler logic in asyncio.wait_for, which raises asyncio.TimeoutError that I would need to catch and map to a response; and server- or proxy-level timeouts in Uvicorn or a reverse proxy. I am unsure how these interact, and whether cancellation actually propagates into awaited downstream coroutines (database calls, HTTP clients) in each case.
There is also a boundary I cannot resolve: BackgroundTasks seem to run after the response and are not tied to disconnects, so it is unclear whether they should be excluded from any cancellation policy entirely.
Which layer (endpoint wrapper, dependency, middleware, or ASGI server) is the appropriate place to enforce a per-route time budget? Does polling is_disconnected() reliably fire on Uvicorn while the coroutine is awaiting I/O, or only after it yields? And should background tasks be treated as outside the request lifecycle for cancellation purposes?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.