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 theitem
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 atfile_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 asJSONResponse
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.