Browse Source

docs: warn about BackgroundTasks + Response background interaction

Add a warning to the "Return a Response Directly" docs page explaining
that returning a Response with a background parameter silently overrides
any BackgroundTasks added via dependency injection.

Closes #11215
pull/15217/head
Cayman Roden 2 months ago
parent
commit
487362fd31
  1. 14
      docs/en/docs/advanced/response-directly.md
  2. 26
      docs_src/response_directly/tutorial003.py

14
docs/en/docs/advanced/response-directly.md

@ -74,6 +74,20 @@ When using a `response_model` or return type, FastAPI won't use the `jsonable_en
Instead it takes the JSON bytes generated with Pydantic using the response model (or return type) and returns a `Response` with the right media type for JSON directly (`application/json`).
## Background Tasks and Custom Responses { #background-tasks-and-custom-responses }
/// warning
If you return a `Response` with a `background` parameter **and** also use the `BackgroundTasks` dependency injection, the injected background tasks will be **silently ignored**.
FastAPI only assigns injected background tasks to the response when `response.background is None`. If your `Response` already has a background task attached, the injected tasks are dropped without any error or warning.
Use one mechanism or the other, not both in the same endpoint:
{* ../../docs_src/response_directly/tutorial003.py hl[18,25] *}
///
## Notes { #notes }
When you return a `Response` directly its data is not validated, converted (serialized), or documented automatically.

26
docs_src/response_directly/tutorial003.py

@ -0,0 +1,26 @@
from fastapi import BackgroundTasks, FastAPI
from starlette.responses import JSONResponse
app = FastAPI()
def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)
# Correct: use only BackgroundTasks (no background= on Response)
@app.get("/correct")
async def send_notification(background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, "Notification sent")
return JSONResponse(content={"message": "done"})
# Wrong: background= on Response silently overrides BackgroundTasks
@app.get("/wrong")
async def send_notification_wrong(background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, "This task will NOT run")
return JSONResponse(
content={"message": "done"},
background=None, # If this were a BackgroundTask, it would override the line above
)
Loading…
Cancel
Save