- 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
request-response.md docs/
1# Request and Response Handling23FastAPI provides comprehensive request and response handling through Starlette's Request and Response objects, along with FastAPI-specific enhancements like UploadFile for file handling and various response classes for different content types.45## Capabilities67### Request Object89HTTP request object providing access to all request data including headers, cookies, query parameters, form data, and JSON body.1011```python { .api }12class Request:13"""14Starlette Request object with all HTTP request functionality.1516Key attributes and methods for accessing request data:17"""1819# Request metadata20method: str # HTTP method (GET, POST, etc.)21url: URL # Complete URL object22headers: Headers # HTTP headers23query_params: QueryParams # Query string parameters24path_params: dict # Path parameters from URL25cookies: dict # HTTP cookies26client: Address # Client connection info2728# Request body access29async def body(self) -> bytes:30"""Get raw request body as bytes."""31pass3233async def json(self) -> Any:34"""Parse request body as JSON."""35pass3637async def form(self) -> FormData:38"""Parse request body as form data."""39pass4041# State and context42state: State # Request-scoped state storage43scope: dict # ASGI scope dictionary4445# Utility methods46def url_for(self, name: str, **path_params) -> str:47"""Generate URL for named route."""48pass49```5051### Response Classes5253Base response class and specialized response classes for different content types and use cases.5455```python { .api }56class Response:57def __init__(58self,59content: Any = None,60status_code: int = 200,61headers: dict = None,62media_type: str = None,63background: BackgroundTask = None,64) -> None:65"""66Base HTTP response class.6768Parameters:69- content: Response content (string, bytes, or None)70- status_code: HTTP status code71- headers: Additional HTTP headers72- media_type: Content-Type header value73- background: Background task to run after response74"""7576# Response properties77status_code: int # HTTP status code78headers: Headers # Response headers79media_type: str # Content-Type80body: bytes # Response body81background: BackgroundTask # Background task8283class JSONResponse(Response):84def __init__(85self,86content: Any = None,87status_code: int = 200,88headers: dict = None,89media_type: str = "application/json",90background: BackgroundTask = None,91) -> None:92"""93JSON response with automatic serialization.9495Parameters:96- content: Python object to serialize as JSON97- Other parameters same as Response98"""99100class HTMLResponse(Response):101def __init__(102self,103content: str = None,104status_code: int = 200,105headers: dict = None,106media_type: str = "text/html",107background: BackgroundTask = None,108) -> None:109"""HTML response for returning HTML content."""110111class PlainTextResponse(Response):112def __init__(113self,114content: str = None,115status_code: int = 200,116headers: dict = None,117media_type: str = "text/plain",118background: BackgroundTask = None,119) -> None:120"""Plain text response."""121122class RedirectResponse(Response):123def __init__(124self,125url: str,126status_code: int = 307,127headers: dict = None,128background: BackgroundTask = None,129) -> None:130"""131HTTP redirect response.132133Parameters:134- url: Target URL for redirection135- status_code: Redirect status code (307, 302, 301, etc.)136"""137138class FileResponse(Response):139def __init__(140self,141path: str = None,142status_code: int = 200,143headers: dict = None,144media_type: str = None,145background: BackgroundTask = None,146filename: str = None,147stat_result: os.stat_result = None,148method: str = None,149) -> None:150"""151File download response.152153Parameters:154- path: File system path to serve155- filename: Filename for Content-Disposition header156- stat_result: Cached file stat result for performance157- method: HTTP method for conditional logic158"""159160class StreamingResponse(Response):161def __init__(162self,163content: Any,164status_code: int = 200,165headers: dict = None,166media_type: str = None,167background: BackgroundTask = None,168) -> None:169"""170Streaming response for large data or real-time content.171172Parameters:173- content: Iterable or async iterable of bytes/strings174- Other parameters same as Response175"""176```177178### FastAPI-Specific Response Classes179180Enhanced JSON response classes using high-performance JSON libraries.181182```python { .api }183class UJSONResponse(JSONResponse):184def render(self, content: Any) -> bytes:185"""186Ultra-fast JSON response using ujson library.187188Requires: pip install ujson189Provides faster JSON serialization than standard library.190"""191192class ORJSONResponse(JSONResponse):193def render(self, content: Any) -> bytes:194"""195Fast JSON response using orjson library.196197Requires: pip install orjson198Fastest JSON serialization with additional features.199"""200```201202### File Upload Handling203204UploadFile class for handling multipart file uploads with async file operations.205206```python { .api }207class UploadFile:208def __init__(209self,210file: BinaryIO,211*,212size: int = None,213filename: str = None,214headers: Headers = None,215) -> None: ...216217# File metadata218filename: Optional[str] # Original filename219content_type: Optional[str] # MIME content type220headers: Headers # File-specific headers221size: Optional[int] # File size in bytes222file: BinaryIO # Underlying file object223224# Async file operations225async def read(self, size: int = -1) -> bytes:226"""Read data from uploaded file."""227228async def readline(self, size: int = -1) -> bytes:229"""Read a line from uploaded file."""230231async def readlines(self) -> List[bytes]:232"""Read all lines from uploaded file."""233234async def write(self, data: bytes) -> None:235"""Write data to uploaded file."""236237async def seek(self, offset: int) -> None:238"""Seek to position in uploaded file."""239240async def close(self) -> None:241"""Close the uploaded file."""242```243244## Usage Examples245246### Accessing Request Data247248```python249from fastapi import FastAPI, Request250251app = FastAPI()252253@app.post("/analyze-request")254async def analyze_request(request: Request):255return {256"method": request.method,257"url": str(request.url),258"headers": dict(request.headers),259"query_params": dict(request.query_params),260"path_params": request.path_params,261"cookies": request.cookies,262"client": f"{request.client.host}:{request.client.port}",263"body": (await request.body()).decode()264}265266@app.get("/items/{item_id}")267async def get_item(item_id: int, request: Request):268# Access path parameters269path_params = request.path_params270271# Access query parameters272query_params = request.query_params273274# Access headers275user_agent = request.headers.get("user-agent")276277return {278"item_id": item_id,279"path_params": path_params,280"query_params": dict(query_params),281"user_agent": user_agent282}283```284285### Custom Response Types286287```python288from fastapi import FastAPI289from fastapi.responses import HTMLResponse, PlainTextResponse, RedirectResponse290291app = FastAPI()292293@app.get("/html", response_class=HTMLResponse)294def get_html():295html_content = """296<html>297<head><title>FastAPI HTML</title></head>298<body><h1>Hello, HTML!</h1></body>299</html>300"""301return html_content302303@app.get("/text", response_class=PlainTextResponse)304def get_text():305return "Hello, plain text!"306307@app.get("/redirect")308def redirect_to_docs():309return RedirectResponse(url="/docs")310311@app.get("/permanent-redirect")312def permanent_redirect():313return RedirectResponse(url="/new-location", status_code=301)314```315316### File Downloads317318```python319from fastapi import FastAPI320from fastapi.responses import FileResponse321import tempfile322import os323324app = FastAPI()325326@app.get("/download-file")327def download_file():328# Create a temporary file329with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as f:330f.write("This is a downloadable file content.")331temp_file_path = f.name332333return FileResponse(334path=temp_file_path,335filename="download.txt",336media_type="text/plain"337)338339@app.get("/download-image")340def download_image():341# Serve an existing file342file_path = "/path/to/image.jpg"343return FileResponse(344path=file_path,345filename="image.jpg",346media_type="image/jpeg"347)348```349350### Streaming Responses351352```python353from fastapi import FastAPI354from fastapi.responses import StreamingResponse355import io356import json357358app = FastAPI()359360@app.get("/stream-data")361def stream_data():362def generate_data():363for i in range(1000):364data = {"item": i, "value": f"data_{i}"}365yield f"data: {json.dumps(data)}\n"366367return StreamingResponse(368generate_data(),369media_type="text/plain"370)371372@app.get("/stream-csv")373def stream_csv():374def generate_csv():375yield "id,name,email\n"376for i in range(1000):377yield f"{i},user_{i},user_{i}@example.com\n"378379return StreamingResponse(380generate_csv(),381media_type="text/csv",382headers={"Content-Disposition": "attachment; filename=users.csv"}383)384385@app.get("/stream-file")386def stream_large_file():387def iterfile(file_path: str):388with open(file_path, mode="rb") as file_like:389while True:390chunk = file_like.read(1024)391if not chunk:392break393yield chunk394395return StreamingResponse(396iterfile("/path/to/large/file.bin"),397media_type="application/octet-stream"398)399```400401### File Upload Handling402403```python404from fastapi import FastAPI, File, UploadFile, HTTPException405from typing import List406import aiofiles407import os408409app = FastAPI()410411@app.post("/upload-file/")412async def upload_file(file: UploadFile = File(...)):413# Validate file type414if not file.content_type.startswith("image/"):415raise HTTPException(400, "File must be an image")416417# Read file content418content = await file.read()419420# Save file421file_path = f"uploads/{file.filename}"422async with aiofiles.open(file_path, "wb") as f:423await f.write(content)424425return {426"filename": file.filename,427"content_type": file.content_type,428"size": len(content),429"saved_to": file_path430}431432@app.post("/upload-multiple/")433async def upload_multiple_files(files: List[UploadFile] = File(...)):434uploaded_files = []435436for file in files:437content = await file.read()438file_info = {439"filename": file.filename,440"content_type": file.content_type,441"size": len(content)442}443uploaded_files.append(file_info)444445# Reset file pointer if you need to read again446await file.seek(0)447448return {"uploaded_files": uploaded_files}449450@app.post("/process-file/")451async def process_file(file: UploadFile = File(...)):452# Process file line by line for large files453processed_lines = []454455# Read file line by line456content = await file.read()457lines = content.decode().split('\n')458459for i, line in enumerate(lines):460if line.strip(): # Skip empty lines461processed_lines.append(f"Line {i+1}: {line.strip()}")462463await file.close()464465return {466"filename": file.filename,467"total_lines": len(processed_lines),468"processed_lines": processed_lines[:10] # Return first 10 lines469}470```471472### Custom Response with Headers473474```python475from fastapi import FastAPI, Response476from fastapi.responses import JSONResponse477478app = FastAPI()479480@app.get("/custom-headers")481def custom_headers():482content = {"message": "Custom headers response"}483headers = {484"X-Custom-Header": "Custom Value",485"X-Processing-Time": "0.123",486"Cache-Control": "no-cache"487}488return JSONResponse(content=content, headers=headers)489490@app.get("/set-cookie")491def set_cookie(response: Response):492content = {"message": "Cookie set"}493response.set_cookie(494key="session_id",495value="abc123",496max_age=3600,497httponly=True,498secure=True,499samesite="lax"500)501return content502503@app.get("/custom-status")504def custom_status():505return JSONResponse(506content={"message": "Created successfully"},507status_code=201,508headers={"Location": "/items/123"}509)510```511512### Response Model with Custom Response Class513514```python515from fastapi import FastAPI516from fastapi.responses import ORJSONResponse517from pydantic import BaseModel518from typing import List519520app = FastAPI(default_response_class=ORJSONResponse)521522class Item(BaseModel):523id: int524name: str525price: float526527@app.get("/items", response_model=List[Item])528def get_items():529# FastAPI will use ORJSONResponse for serialization530return [531{"id": 1, "name": "Item 1", "price": 10.5},532{"id": 2, "name": "Item 2", "price": 20.0}533]534535@app.get("/custom-json", response_class=ORJSONResponse)536def get_custom_json():537# Explicitly use ORJSONResponse538return {"message": "Fast JSON response"}539```