- Spec files
pypi-fastapi
Describes: pkg:pypi/fastapi@0.116.x
- Description
- FastAPI framework, high performance, easy to learn, fast to code, ready for production
- Author
- tessl
- Last updated
advanced-responses.md docs/
1# Advanced Response Types23FastAPI provides a comprehensive set of response classes for different content types and use cases, including high-performance JSON responses, HTML responses, file serving, streaming, and redirects. These response types enable efficient content delivery optimized for specific scenarios and client requirements.45## Capabilities67### High-Performance JSON Responses89Ultra-fast JSON response classes using optimized JSON libraries for maximum performance.1011```python { .api }12class UJSONResponse(Response):13def __init__(14self,15content: Any = None,16status_code: int = 200,17headers: dict = None,18media_type: str = "application/json",19background: BackgroundTask = None,20) -> None:21"""22JSON response using ujson for high performance.2324Parameters:25- content: Data to serialize as JSON26- status_code: HTTP status code27- headers: Additional HTTP headers28- media_type: Content type header29- background: Background task to run after response30"""3132class ORJSONResponse(Response):33def __init__(34self,35content: Any = None,36status_code: int = 200,37headers: dict = None,38media_type: str = "application/json",39background: BackgroundTask = None,40) -> None:41"""42JSON response using orjson for maximum performance.4344Parameters:45- content: Data to serialize as JSON46- status_code: HTTP status code47- headers: Additional HTTP headers48- media_type: Content type header49- background: Background task to run after response50"""51```5253### HTML and Plain Text Responses5455Response classes for serving HTML content and plain text.5657```python { .api }58class HTMLResponse(Response):59def __init__(60self,61content: str = "",62status_code: int = 200,63headers: dict = None,64media_type: str = "text/html",65background: BackgroundTask = None,66) -> None:67"""68HTML response for serving HTML content.6970Parameters:71- content: HTML content string72- status_code: HTTP status code73- headers: Additional HTTP headers74- media_type: Content type header75- background: Background task to run after response76"""7778class PlainTextResponse(Response):79def __init__(80self,81content: str = "",82status_code: int = 200,83headers: dict = None,84media_type: str = "text/plain",85background: BackgroundTask = None,86) -> None:87"""88Plain text response.8990Parameters:91- content: Plain text content string92- status_code: HTTP status code93- headers: Additional HTTP headers94- media_type: Content type header95- background: Background task to run after response96"""97```9899### Redirect Responses100101Response class for HTTP redirects with configurable status codes.102103```python { .api }104class RedirectResponse(Response):105def __init__(106self,107url: str,108status_code: int = 307,109headers: dict = None,110background: BackgroundTask = None,111) -> None:112"""113HTTP redirect response.114115Parameters:116- url: Target URL for redirect117- status_code: HTTP redirect status code (301, 302, 307, 308)118- headers: Additional HTTP headers119- background: Background task to run after response120"""121```122123### File and Streaming Responses124125Response classes for serving files and streaming large content.126127```python { .api }128class FileResponse(Response):129def __init__(130self,131path: str,132status_code: int = 200,133headers: dict = None,134media_type: str = None,135filename: str = None,136background: BackgroundTask = None,137) -> None:138"""139File download response.140141Parameters:142- path: File system path to the file143- status_code: HTTP status code144- headers: Additional HTTP headers145- media_type: Content type (auto-detected if None)146- filename: Download filename (Content-Disposition header)147- background: Background task to run after response148"""149150class StreamingResponse(Response):151def __init__(152self,153content: Iterator[Any],154status_code: int = 200,155headers: dict = None,156media_type: str = None,157background: BackgroundTask = None,158) -> None:159"""160Streaming response for large content.161162Parameters:163- content: Iterator yielding content chunks164- status_code: HTTP status code165- headers: Additional HTTP headers166- media_type: Content type header167- background: Background task to run after response168"""169```170171## Usage Examples172173### High-Performance JSON Responses174175```python176from fastapi import FastAPI177from fastapi.responses import UJSONResponse, ORJSONResponse178import time179180app = FastAPI()181182# Large dataset for performance comparison183large_data = {184"users": [185{"id": i, "name": f"User {i}", "score": i * 1.5}186for i in range(10000)187],188"timestamp": time.time(),189"metadata": {"total": 10000, "version": "1.0"}190}191192@app.get("/data/ujson", response_class=UJSONResponse)193def get_data_ujson():194"""Return large dataset using ujson for faster serialization."""195return large_data196197@app.get("/data/orjson", response_class=ORJSONResponse)198def get_data_orjson():199"""Return large dataset using orjson for maximum performance."""200return large_data201202# Set as default response class for entire app203app_with_orjson = FastAPI(default_response_class=ORJSONResponse)204205@app_with_orjson.get("/fast")206def fast_endpoint():207return {"message": "This uses ORJSONResponse by default"}208```209210### HTML Responses211212```python213from fastapi import FastAPI, Request214from fastapi.responses import HTMLResponse215216app = FastAPI()217218@app.get("/", response_class=HTMLResponse)219def home():220html_content = """221<!DOCTYPE html>222<html>223<head>224<title>FastAPI HTML Response</title>225<style>226body { font-family: Arial, sans-serif; margin: 40px; }227.header { color: #2c3e50; }228</style>229</head>230<body>231<h1 class="header">Welcome to FastAPI</h1>232<p>This is a direct HTML response.</p>233<ul>234<li><a href="/api/users">API Users</a></li>235<li><a href="/api/docs">API Documentation</a></li>236</ul>237</body>238</html>239"""240return HTMLResponse(content=html_content, status_code=200)241242@app.get("/dynamic/{name}", response_class=HTMLResponse)243def dynamic_page(name: str):244html_content = f"""245<!DOCTYPE html>246<html>247<head>248<title>Hello {name}</title>249</head>250<body>251<h1>Hello, {name}!</h1>252<p>This page was generated dynamically.</p>253<a href="/">Back to Home</a>254</body>255</html>256"""257return HTMLResponse(content=html_content)258259@app.get("/error-page", response_class=HTMLResponse)260def error_page():261html_content = """262<html>263<body>264<h1>Something went wrong</h1>265<p>Please try again later.</p>266</body>267</html>268"""269return HTMLResponse(content=html_content, status_code=500)270```271272### Redirect Responses273274```python275from fastapi import FastAPI, Form276from fastapi.responses import RedirectResponse277278app = FastAPI()279280@app.get("/old-url")281def old_endpoint():282# Permanent redirect (301)283return RedirectResponse(url="/new-url", status_code=301)284285@app.get("/new-url")286def new_endpoint():287return {"message": "This is the new endpoint"}288289@app.post("/login")290def login(username: str = Form(...), password: str = Form(...)):291# Simulate authentication292if username == "admin" and password == "secret":293# Temporary redirect after successful login (307)294return RedirectResponse(url="/dashboard", status_code=307)295else:296# Redirect back to login with error297return RedirectResponse(url="/login?error=invalid", status_code=303)298299@app.get("/dashboard")300def dashboard():301return {"message": "Welcome to the dashboard"}302303@app.get("/external-redirect")304def external_redirect():305# Redirect to external URL306return RedirectResponse(url="https://fastapi.tiangolo.com/")307308# Conditional redirects309@app.get("/redirect/{target}")310def conditional_redirect(target: str):311redirect_map = {312"docs": "/docs",313"redoc": "/redoc",314"github": "https://github.com/tiangolo/fastapi",315"home": "/"316}317318if target in redirect_map:319return RedirectResponse(url=redirect_map[target])320else:321return RedirectResponse(url="/404")322```323324### File Responses325326```python327from fastapi import FastAPI, HTTPException328from fastapi.responses import FileResponse329import os330from pathlib import Path331332app = FastAPI()333334@app.get("/download/{filename}")335def download_file(filename: str):336file_path = Path("files") / filename337338if not file_path.exists():339raise HTTPException(status_code=404, detail="File not found")340341return FileResponse(342path=str(file_path),343filename=filename,344media_type='application/octet-stream'345)346347@app.get("/image/{filename}")348def serve_image(filename: str):349file_path = Path("images") / filename350351if not file_path.exists():352raise HTTPException(status_code=404, detail="Image not found")353354# Auto-detect media type based on file extension355return FileResponse(path=str(file_path))356357@app.get("/report/pdf")358def download_report():359return FileResponse(360path="reports/monthly_report.pdf",361filename="monthly_report.pdf",362media_type="application/pdf"363)364365@app.get("/export/csv")366def export_data():367# Assume CSV file is generated elsewhere368return FileResponse(369path="exports/data.csv",370filename="exported_data.csv",371media_type="text/csv",372headers={"Custom-Header": "Export-Data"}373)374```375376### Streaming Responses377378```python379from fastapi import FastAPI380from fastapi.responses import StreamingResponse381import json382import time383from typing import Iterator384385app = FastAPI()386387def generate_large_csv() -> Iterator[str]:388"""Generate large CSV data as iterator."""389yield "id,name,email,created_at\n"390for i in range(100000):391yield f"{i},User{i},user{i}@example.com,2024-01-{(i % 30) + 1:02d}\n"392393@app.get("/export/large-csv")394def export_large_csv():395return StreamingResponse(396generate_large_csv(),397media_type="text/csv",398headers={"Content-Disposition": "attachment; filename=large_data.csv"}399)400401def generate_json_stream() -> Iterator[bytes]:402"""Generate streaming JSON response."""403yield b'{"data": ['404for i in range(1000):405if i > 0:406yield b','407data = {"id": i, "value": f"item_{i}"}408yield json.dumps(data).encode("utf-8")409yield b']}'410411@app.get("/stream/json")412def stream_json():413return StreamingResponse(414generate_json_stream(),415media_type="application/json"416)417418def generate_server_sent_events() -> Iterator[str]:419"""Generate Server-Sent Events stream."""420for i in range(10):421yield f"data: Event {i} at {time.time()}\n\n"422time.sleep(1)423424@app.get("/events")425def server_sent_events():426return StreamingResponse(427generate_server_sent_events(),428media_type="text/plain",429headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}430)431432async def generate_async_stream() -> Iterator[bytes]:433"""Generate async streaming response."""434for chunk in range(100):435# Simulate async processing436await asyncio.sleep(0.01)437yield f"Chunk {chunk}\n".encode("utf-8")438439@app.get("/stream/async")440async def async_stream():441return StreamingResponse(442generate_async_stream(),443media_type="text/plain"444)445```446447### Response Headers and Background Tasks448449```python450from fastapi import FastAPI, BackgroundTasks451from fastapi.responses import JSONResponse, FileResponse452import logging453454app = FastAPI()455456def log_download(filename: str, user_ip: str):457"""Background task to log file downloads."""458logging.info(f"File {filename} downloaded by {user_ip}")459460@app.get("/secure-download/{filename}")461def secure_download(filename: str, background_tasks: BackgroundTasks, request: Request):462file_path = f"secure_files/{filename}"463464# Add logging as background task465background_tasks.add_task(log_download, filename, request.client.host)466467return FileResponse(468path=file_path,469filename=filename,470headers={471"X-Custom-Header": "Secure-Download",472"Cache-Control": "no-cache"473}474)475476@app.get("/api/data-with-headers")477def data_with_custom_headers():478return JSONResponse(479content={"data": "response"},480headers={481"X-API-Version": "1.0",482"X-Response-Time": str(time.time()),483"Access-Control-Allow-Origin": "*"484}485)486```487488## Types489490```python { .api }491from typing import Any, Dict, Iterator, Optional, Union492from starlette.responses import Response493from starlette.background import BackgroundTask494495# Response content types496ResponseContent = Union[str, bytes, Iterator[Any]]497498# Headers type499ResponseHeaders = Optional[Dict[str, str]]500501# Background task type502BackgroundTaskType = Optional[BackgroundTask]503504# HTTP status codes for redirects505RedirectStatusCode = Union[301, 302, 303, 307, 308]506```