Using BackgroundTasks blocks StreamingResponse? #11022
-
First Check
Commit to Help
Example Codeimport asyncio
import logging
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from starlette.background import BackgroundTask
app = FastAPI()
async def stream_data():
for i in range(10): # Simulating a stream of data
yield f"data: {i}\n"
await asyncio.sleep(0.1)
logging.info(f"Sent data chunk: {i}")
logging.info("Streaming finished")
async def post_streaming_cleanup():
logging.info("Cleanup started")
await asyncio.sleep(100)
logging.info("Cleanup finished")
@app.get("/stream")
async def get_stream():
response = StreamingResponse(
stream_data(), background=BackgroundTask(post_streaming_cleanup)
)
return response DescriptionIf you call the endpoint above (e.g. via Any way to make the task NOT block the response from completion? Operating SystemmacOS Operating System DetailsNo response FastAPI Version0.104.1 Pydantic Version2.5.2 Python VersionPython 3.11.6 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Answered by
binbjz
Jan 24, 2024
Replies: 1 comment 2 replies
-
Version info# Name Version Build Channel
python 3.11.7 hb885b13_0
fastapi 0.109.0 pypi_0 pypi
pydantic 2.5.3 pypi_0 pypi
pydantic-core 2.14.6 pypi_0 pypi
ProductName: macOS
ProductVersion: 14.2.1
BuildVersion: 23C71 Please try the following code snippet.import time
import asyncio
import logging
from fastapi import FastAPI, BackgroundTasks
from fastapi.responses import StreamingResponse
app = FastAPI()
logging.basicConfig(level=logging.INFO)
async def stream_data():
for i in range(10):
yield f"data: {i}\n"
await asyncio.sleep(0.1)
logging.info(f"Sent data chunk: {i}")
logging.info("Streaming finished")
def background_cleanup():
logging.info("Cleanup started")
time.sleep(19)
logging.info("Cleanup finished")
async def start_background_task():
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, background_cleanup)
@app.get("/stream")
async def get_stream(background_tasks: BackgroundTasks):
response = StreamingResponse(stream_data())
background_tasks.add_task(start_background_task)
return response Or update the following two functions to use async?async def background_cleanup():
logging.info("Cleanup started")
await asyncio.sleep(19)
logging.info("Cleanup finished")
async def start_background_task():
task = asyncio.create_task(background_cleanup())
await task $ uvicorn async_data_streamer:app --reload
INFO: Will watch for changes in these directories: ['/private/tmp']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [77874] using WatchFiles
INFO: Started server process [77876]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:55875 - "GET /stream HTTP/1.1" 200 OK
INFO:root:Sent data chunk: 0
INFO:root:Sent data chunk: 1
INFO:root:Sent data chunk: 2
INFO:root:Sent data chunk: 3
INFO:root:Sent data chunk: 4
INFO:root:Sent data chunk: 5
INFO:root:Sent data chunk: 6
INFO:root:Sent data chunk: 7
INFO:root:Sent data chunk: 8
INFO:root:Sent data chunk: 9
INFO:root:Streaming finished
INFO:root:Cleanup started
INFO:root:Cleanup finished
^CINFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [77876]
INFO: Stopping reloader process [77874] $ curl -v http://127.0.0.1:8000/stream
* Trying 127.0.0.1:8000...
* Connected to 127.0.0.1 (127.0.0.1) port 8000
> GET /stream HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Wed, 24 Jan 2024 12:07:40 GMT
< server: uvicorn
< transfer-encoding: chunked
<
data: 0
data: 1
data: 2
data: 3
data: 4
data: 5
data: 6
data: 7
data: 8
data: 9
* Connection #0 to host 127.0.0.1 left intact |
Beta Was this translation helpful? Give feedback.
2 replies
Answer selected by
rohan-mehta
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Version info
# Name Version Build Channel python 3.11.7 hb885b13_0 fastapi 0.109.0 pypi_0 pypi pydantic 2.5.3 pypi_0 pypi pydantic-core 2.14.6 pypi_0 pypi ProductName: macOS ProductVersion: 14.2.1 BuildVersion: 23C71
Please try the following code snippet.