How to Stream Response in FastAPI: Simple Guide
In FastAPI, you can stream responses by returning a
StreamingResponse object that takes an iterable or async generator as input. This allows sending data chunks to the client as they are generated, improving performance for large or slow data sources.Syntax
The basic syntax to stream a response in FastAPI uses the StreamingResponse class from starlette.responses. You provide it with a generator or iterable that yields bytes, and optionally set the media_type to specify the content type.
content: An iterable or async generator yielding bytes to send.media_type: The MIME type of the response, e.g.,text/plainorapplication/json.
python
from fastapi import FastAPI from starlette.responses import StreamingResponse app = FastAPI() def generate_data(): yield b"chunk 1\n" yield b"chunk 2\n" @app.get("/stream") def stream(): return StreamingResponse(generate_data(), media_type="text/plain")
Example
This example demonstrates streaming a simple text response in chunks. The generate_data function yields byte strings one by one. FastAPI sends each chunk immediately to the client without waiting for the entire response to be ready.
python
from fastapi import FastAPI from starlette.responses import StreamingResponse import asyncio app = FastAPI() async def async_generate_data(): for i in range(5): yield f"chunk {i}\n".encode("utf-8") await asyncio.sleep(1) # simulate delay @app.get("/async-stream") async def async_stream(): return StreamingResponse(async_generate_data(), media_type="text/plain")
Output
chunk 0
chunk 1
chunk 2
chunk 3
chunk 4
Common Pitfalls
- Not yielding bytes: The generator must yield bytes, not strings. Use
.encode()to convert strings to bytes. - Forgetting
asyncin async generators: Useasync defandawaitwhen simulating delays or async operations. - Setting wrong
media_type: Always specify the correct MIME type for proper client handling. - Returning a list or string directly instead of a generator: This defeats streaming and sends the whole response at once.
python
from fastapi import FastAPI from starlette.responses import StreamingResponse app = FastAPI() # Wrong: yields strings instead of bytes def wrong_generator(): yield "chunk 1\n" yield "chunk 2\n" @app.get("/wrong-stream") def wrong_stream(): return StreamingResponse(wrong_generator(), media_type="text/plain") # Right: yields bytes def right_generator(): yield b"chunk 1\n" yield b"chunk 2\n" @app.get("/right-stream") def right_stream(): return StreamingResponse(right_generator(), media_type="text/plain")
Quick Reference
Remember these tips when streaming responses in FastAPI:
- Use
StreamingResponsewith a generator yielding bytes. - Set
media_typeto match your content. - Use async generators for asynchronous data sources.
- Test streaming with tools like curl or browser DevTools network tab.
Key Takeaways
Use StreamingResponse with a bytes-yielding generator to stream data in FastAPI.
Always specify the correct media_type for your streamed content.
Async generators enable streaming with delays or async data sources.
Do not yield strings directly; convert them to bytes first.
Test streaming endpoints with curl or browser network tools to verify chunked delivery.