Browse Source
When an endpoint injects BackgroundTasks and also returns a Response with its own background task, the injected tasks were silently discarded. Now both sets of tasks are merged so all background work executes as expected. Closes #11215pull/15010/head
2 changed files with 85 additions and 0 deletions
@ -0,0 +1,71 @@ |
|||||
|
from fastapi import BackgroundTasks, FastAPI |
||||
|
from fastapi.testclient import TestClient |
||||
|
from starlette.background import BackgroundTask |
||||
|
from starlette.responses import JSONResponse |
||||
|
|
||||
|
|
||||
|
results: list[str] = [] |
||||
|
|
||||
|
|
||||
|
def task_from_injection(): |
||||
|
results.append("injected") |
||||
|
|
||||
|
|
||||
|
def task_from_response(): |
||||
|
results.append("response") |
||||
|
|
||||
|
|
||||
|
def test_merge_injected_and_response_background_tasks(): |
||||
|
"""Both injected BackgroundTasks and Response background tasks should run.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/") |
||||
|
async def endpoint(background_tasks: BackgroundTasks): |
||||
|
background_tasks.add_task(task_from_injection) |
||||
|
return JSONResponse( |
||||
|
{"status": "ok"}, |
||||
|
background=BackgroundTask(task_from_response), |
||||
|
) |
||||
|
|
||||
|
results.clear() |
||||
|
client = TestClient(app) |
||||
|
response = client.get("/") |
||||
|
assert response.status_code == 200 |
||||
|
assert "injected" in results |
||||
|
assert "response" in results |
||||
|
|
||||
|
|
||||
|
def test_only_injected_background_tasks(): |
||||
|
"""When Response has no background, injected tasks still run.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/") |
||||
|
async def endpoint(background_tasks: BackgroundTasks): |
||||
|
background_tasks.add_task(task_from_injection) |
||||
|
return JSONResponse({"status": "ok"}) |
||||
|
|
||||
|
results.clear() |
||||
|
client = TestClient(app) |
||||
|
response = client.get("/") |
||||
|
assert response.status_code == 200 |
||||
|
assert "injected" in results |
||||
|
assert "response" not in results |
||||
|
|
||||
|
|
||||
|
def test_only_response_background_task(): |
||||
|
"""When no BackgroundTasks are injected, response background task runs.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/") |
||||
|
async def endpoint(): |
||||
|
return JSONResponse( |
||||
|
{"status": "ok"}, |
||||
|
background=BackgroundTask(task_from_response), |
||||
|
) |
||||
|
|
||||
|
results.clear() |
||||
|
client = TestClient(app) |
||||
|
response = client.get("/") |
||||
|
assert response.status_code == 200 |
||||
|
assert "response" in results |
||||
|
assert "injected" not in results |
||||
Loading…
Reference in new issue