fastapi
fastapi copied to clipboard
asyncio.wait_for doesn't time out as expected
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the FastAPI documentation, with the integrated search.
- [X] I already searched in Google "How to X in FastAPI" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to FastAPI but to Pydantic.
- [X] I already checked if it is not related to FastAPI but to Swagger UI.
- [X] I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
d
Description
d
Operating System
macOS
Operating System Details
d
FastAPI Version
fastapi==0.89.1
Python Version
3.9
Additional Context
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
# response.headers["X-Process-Time"] = str(process_time)
print("adfadsfasdf")
# response.headers["Test middleware"] = str(random.randint(1, 1000))
return response
REQUEST_TIMEOUT_ERROR = 1.0 # seconds to wait for
from fastapi.responses import JSONResponse
from starlette.status import HTTP_504_GATEWAY_TIMEOUT
#Adding a middleware returning a 504 error if the request processing time is above a certain threshold
@app.middleware("http")
async def timeout_middleware(request: Request, call_next):
try:
start_time = time.time()
return await asyncio.wait_for(call_next(request), timeout=REQUEST_TIMEOUT_ERROR)
except asyncio.TimeoutError:
process_time = time.time() - start_time
res = timeout_fallback(process_time)
return res
def timeout_fallback(process_time):
response = JSONResponse({'detail': 'Request processing time excedeed limit',
'processing_time': process_time},
status_code=HTTP_504_GATEWAY_TIMEOUT)
return response
Does anyone know why? It's super weird. Basically, you need to have two @app.middleware("http"). Otherwise, the timeout exception won't work.
Have you tried using ASGI Middlewares?
Quite peculiar!
app.middleware code is quite straightforward, however you're soon getting out of fastapi territory into starlette, IIRC.
aside: are you clear about the order that the middlewares are applied in?
Anyway, please dig deeper and figure it out. It's going to be fun! 🚀
Something to look forward to in the future: https://docs.python.org/3.12/library/asyncio-task.html#timeouts