Background tasks don't work with middleware that subclasses `BaseHTTPMiddleware`
See original GitHub issueWhen using background tasks with middleware, requests are not processed until the background task has finished.
- Use the example below
- Make several requests in a row - works as expected
- Uncomment
app.add_middleware(TransparentMiddleware)
and re-run - Make several requests in a row - subsequent ones are not processed until the 10 second sleep has finished (the first request returns before then though).
The same behaviour occurs with asyncio.sleep
(async) and time.sleep
(sync, run in threadpool)
import asyncio
import uvicorn
from starlette.applications import Starlette
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.background import BackgroundTask
from starlette.responses import JSONResponse
class TransparentMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# simple middleware that does absolutely nothing
response = await call_next(request)
return response
app = Starlette(debug=True)
# uncomment to break
# app.add_middleware(TransparentMiddleware)
@app.route("/")
async def test(_):
task = BackgroundTask(asyncio.sleep, 10)
return JSONResponse("hello", background=task)
if __name__ == '__main__':
uvicorn.run(app)
Issue Analytics
- State:
- Created 3 years ago
- Reactions:43
- Comments:42 (17 by maintainers)
Top Results From Across the Web
Background tasks don't work with middleware that subclasses ...
When using background tasks with middleware, requests are not processed until the background task has finished. Use the example below ...
Read more >How to use background tasks with Starlette when there's no ...
Solved! Starlette Middleware: class BackgroundTaskMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, ...
Read more >Middleware - Starlette
An abstract class that allows you to write ASGI middleware against a request/response interface. Usage. To implement a middleware class using BaseHTTPMiddleware ......
Read more >Starlette Quick Manual - 0xBF
The above TemplateResponse and JSONResponse are subclass of the Response ... from starlette.background import BackgroundTasks async def ...
Read more >Middleware - FastAPI
If you have dependencies with yield , the exit code will run after the middleware. If there were any background tasks (documented later),...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Any updates on this issue ?
Hi all, I had a PR to fix this behavior (#1017 ) but it relied on forcing the response to remain unevaluated, which further confused those users who were relying on having a fully-evaluated response inside their middleware functions (#1022 ). In other words, there are contradictory goals here.
After looking at this
BaseHTTPMiddleware
class over the last week, I have come to the following conclusions:We should discourage the use of
BaseHTTPMiddleware
in favor of raw ASGI middleware which includes a methoddef __call__(self, scope, receive, send):
, andIf people still want to use this middleware class, it should never be used with
StreamingResponse
/FileResponse
endpoints.Unfortunately, while the
BaseHTTPMiddleware
class offers an easier interface because it provides arequest
argument and promises something like aresponse
, this middleware class also encourages users to think about the asgi app functionality in a “complete” or “finished” way. This means this class will either load the entirety of streaming requests into memory (#1012 ) and run the background before returning the response (this issue), or if we fix those problems, that it will then encourage users to leave resources in a pending or open state, an arguably worse result. In short, it’s problematic.Again, these problems should be absent if you avoid subclassing
BaseHTTPMiddleware
.Lastly, I think it’s worth leaving this issue open so that other users who have the same problem can see it and see that it remains an open issue.