0
0
FastapiHow-ToBeginner · 3 min read

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/plain or application/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 async in async generators: Use async def and await when 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 StreamingResponse with a generator yielding bytes.
  • Set media_type to 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.