Replies: 1 comment
|
There is no Option A — custom route class (opt-in per router)from fastapi import APIRouter, BackgroundTasks, Depends, Request
from fastapi.routing import APIRoute
def get_router_tasks(request: Request) -> BackgroundTasks:
return request.scope["router_bg"]
class RouterBackgroundRoute(APIRoute):
def get_route_handler(self):
original = super().get_route_handler()
async def handler(request: Request):
tasks = BackgroundTasks()
request.scope["router_bg"] = tasks
response = await original(request)
existing = response.background
response.background = tasks
if isinstance(existing, BackgroundTasks):
tasks.tasks.extend(existing.tasks) # keep the endpoint's own tasks
elif existing is not None:
tasks.add_task(existing)
return response
return handler
router = APIRouter(route_class=RouterBackgroundRoute)
@router.get("/items")
async def list_items(bg: BackgroundTasks = Depends(get_router_tasks)):
bg.add_task(clean_expired_cache) # your router-wide cleanup
return {"ok": True}
app.include_router(router)Option B — one middleware, applies to every routefrom starlette.middleware.base import BaseHTTPMiddleware
class RouterTasksMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
tasks = BackgroundTasks()
request.scope["router_bg"] = tasks
response = await call_next(request)
existing = response.background
response.background = tasks
if isinstance(existing, BackgroundTasks):
tasks.tasks.extend(existing.tasks)
elif existing is not None:
tasks.add_task(existing)
return responseEndpoints use the same Notes from actually running both against fastapi 0.133.1 / starlette 1.3.1 with
One caveat worth knowing: anything attached this way runs in the same process and after the response, so it is still not a substitute for a real queue if the work is long or must survive a restart. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Hi everyone,
I wonder if there's a work around for performing operation(s) for a whole APIRouter as Background Task(s) ?
e.g a cache cleanup task after returning response, applying to all routes in an router. as we do with Dependencies in APIRouter definitions.
All reactions