FastAPI

Mastering FastAPI Responses: From JSON to Streaming Like a Pro

FastAPI provides several types of responses that you can use depending on your use case. These responses are part of the framework’s built-in tools and are designed to make your APIs more flexible and efficient.

Here’s a detailed explanation of the different types of responses in FastAPI with real-world examples and guidance on when to use each one.

1. JSON Response (JSONResponse)

  • Use Case: You use this when you need to return data in JSON format, which is the most common format for APIs, especially when communicating with frontend applications or other services.
  • When to Use: When your API returns structured data such as lists, dictionaries, or objects.

Example

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str

@app.get("/items/{item_id}", response_class=JSONResponse)
async def read_item(item_id: int):
    item = {"item_id": item_id, "name": "example", "description": "A sample item"}
    return JSONResponse(content=item)

Explanation:

  • In this example, when a request is made to /items/{item_id}, FastAPI returns the item dictionary as a JSON object.
{
  "item_id": 1,
  "name": "example",
  "description": "A sample item"
}

 

2. HTML Response (HTMLResponse)

  • Use Case: This is used when your API returns an HTML page. It's often used for web applications where you return HTML templates rendered on the server side.
  • When to Use: When your API needs to render or return static HTML content (e.g., HTML files for a website).

Example

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def read_html():
    html_content = "<html><body><h1>Welcome to FastAPI</h1></body></html>"
    return HTMLResponse(content=html_content)

Explanation:

  • In this example, the / endpoint returns an HTML page with the message "Welcome to FastAPI".

 

3. Plain Text Response (PlainTextResponse)

  • Use Case: You use this when you want to return raw text without any formatting. This is often used for logs, error messages, or simple text responses.
  • When to Use: When your API returns plain, unformatted text, such as plain text files or log outputs.

Example:

from fastapi import FastAPI
from fastapi.responses import PlainTextResponse

app = FastAPI()

@app.get("/text", response_class=PlainTextResponse)
async def get_text():
    return "This is plain text response"

Explanation:

  • When a request is made to /text, a plain text message is returned without any HTML or JSON formatting.

4. Redirect Response (RedirectResponse)

  • Use Case: This response is used to redirect users to a different URL. It's useful when you want to redirect traffic, for example, after a form submission or when a resource has been moved.
  • When to Use: When you need to direct the user to another page (HTTP status code 302).

Example:

from fastapi import FastAPI
from fastapi.responses import RedirectResponse

app = FastAPI()

@app.get("/old-url")
async def old_url():
    return RedirectResponse(url="/new-url")

@app.get("/new-url")
async def new_url():
    return {"message": "This is the new URL"}

Explanation:

  • When a user accesses /old-url, they will be automatically redirected to /new-url, where they will see the message "This is the new URL".

 

5. File Response (FileResponse)

  • Use Case: You use this response when you need to return a file, such as images, PDFs, or any other type of binary data.
  • When to Use: When you need to serve files for download or display, like serving PDFs, images, or other static files.

Example:

from fastapi import FastAPI
from fastapi.responses import FileResponse
import os

app = FastAPI()

@app.get("/file")
async def get_file():
    file_path = "path/to/your/file.txt"
    return FileResponse(file_path)
     ## return FileResponse(path=file_path, media_type="application/pdf", filename="sample.pdf")
     ## return FileResponse(path=file_path, media_type="image/png", filename="sample.png")
     ## return FileResponse(path=file_path, media_type="video/mp4", filename="cat.mp4")

Explanation:

  • The FileResponse serves the file located at file_path as an HTTP response. If the file exists, it will be sent to the client for download.

6. Streaming Response (StreamingResponse)

  • Use Case: This is used when you need to send a large amount of data in chunks (streaming data). It’s commonly used for videos, large files, or API responses that take a long time to compute.
  • When to Use: When dealing with large files or streams of data that would be inefficient or impractical to send all at once (e.g., video files or logs).

Example:

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import io

app = FastAPI()

@app.get("/stream")
async def stream_data():
    # Let's pretend this is a large file or data stream
    content = io.BytesIO(b"Hello, this is a stream of data!")
    return StreamingResponse(content, media_type="application/octet-stream")

Explanation:

  • This example demonstrates a stream of data that can be sent as a response. In real applications, you would typically stream large files or chunks of data.

7. UJSON Response (UJSONResponse)

  • Use Case: UJSON (Ultra JSON) is a faster JSON parser and serializer compared to Python’s built-in json library. Use this when performance is a concern, especially for applications with high load or when you need to handle large amounts of JSON data quickly.
  • When to Use: When you're working with large JSON payloads or require high-performance JSON serialization/deserialization.

Example:

from fastapi import FastAPI
from fastapi.responses import UJSONResponse

app = FastAPI()

@app.get("/ujson")
async def get_ujson():
    item = {"message": "This is a fast UJSON response"}
    return UJSONResponse(content=item)

Explanation:

  • The UJSONResponse returns the same JSON as JSONResponse but uses a faster implementation.

8. Custom Responses

  • Use Case: If you need to customize the HTTP response for specific requirements (e.g., adding custom headers, status codes, or other behavior), you can create custom responses by extending the base Response class.
  • When to Use: When you need to modify or customize the response behavior beyond what’s available in the predefined response classes.

Example:

from fastapi import FastAPI
from fastapi.responses import Response

app = FastAPI()

@app.get("/custom-response")
async def custom_response():
    headers = {"X-Custom-Header": "This is a custom header"}
    return Response(content="Custom response body", headers=headers, media_type="text/plain")

Explanation:

  • This example shows how to send a custom response with a custom header and body. The Response class allows for fine-grained control over the response content.

 

 


About author

author image

Amrit panta

Fullstack developer, content creator



Scroll to Top