Python logoPython INTERMEDIATE

FastAPI

Essential FastAPI reference covering routes, request validation, Pydantic models, dependencies, authentication, file uploads, middleware, database integration, and project structure.

10 min read
fastapipythonapiasyncrestweb

Installation & Setup

Install FastAPI and run your first application.

Quick Start

Install FastAPI with uvicorn and create a basic application.

python
💡 "fastapi[standard]" includes uvicorn, email-validator, and other essentials
⚡ Auto-generated docs at /docs (Swagger) and /redoc — no setup needed
📌 Use "fastapi dev" for development (auto-reload) and "fastapi run" for production
🟢 Both sync (def) and async (async def) route handlers are supported
installsetupquickstart

Path & Query Parameters

Define URL path parameters and query string parameters with validation.

Path Parameters

Extract values from the URL path with type validation.

python
💡 Path parameters are required — they're part of the URL itself
⚡ Use Path() for validation: gt, ge, lt, le for numbers; min_length, max_length for strings
📌 Enum parameters auto-generate a dropdown in the /docs UI
🟢 Use {param:path} to capture a full file path including slashes
pathparametersvalidation

Query Parameters

Accept query string parameters with defaults and validation.

python
💡 Any function parameter not in the URL path is automatically a query parameter
⚡ Use Query() for string validation: min_length, max_length, pattern (regex)
📌 Use list[str] with Query() to accept repeated query params (?tag=a&tag=b)
🟢 Set deprecated=True to mark a parameter as deprecated in the docs
queryparametersvalidation

Request Body & Pydantic Models

Define and validate request bodies using Pydantic models.

Pydantic Models

Define request and response schemas with automatic validation.

python
💡 Pydantic model parameters are automatically parsed from the JSON request body
⚡ Use Field() for validation: gt, ge, lt, le (numbers), min_length, max_length (strings)
📌 Nested models are fully validated — define Address as a model and use it inside User
🟢 FastAPI auto-detects: path params from URL, body from Pydantic models, rest as query
pydanticmodelsbodyvalidation

Response Models & Status Codes

Control response shape and HTTP status codes.

python
💡 response_model filters the output — use it to hide internal fields like passwords
⚡ You can use return type annotations (-> ItemOut) instead of response_model=
📌 status.HTTP_201_CREATED is clearer than the magic number 201
🟢 response_model_exclude_unset=True omits fields that weren't explicitly set
responsestatus-codesmodels

Form Data & File Uploads

Handle HTML form submissions and file uploads.

Form Data & File Uploads

Receive form fields and uploaded files in endpoints.

python
💡 Use Form() for form fields and File()/UploadFile for file uploads — not Pydantic models
⚡ UploadFile streams to disk — use it for large files; bytes = File() loads into memory
📌 You cannot mix JSON body (Pydantic) with form/file data in the same endpoint
🟢 Install python-multipart for form/file support: pip install python-multipart
formsfilesupload

Cookie & Header Parameters

Read cookies and HTTP headers from incoming requests.

Cookies & Headers

Extract cookie values and HTTP headers from requests.

python
💡 Header names are auto-converted: X-Request-Id becomes x_request_id in Python
⚡ Use Response.set_cookie() to send cookies back to the client
📌 Always set httponly=True on session cookies to prevent XSS access
🟢 Use list[str] for headers that can appear multiple times (e.g., X-Token)
cookiesheadersparameters

Dependencies

Dependency injection for shared logic, DB sessions, and auth.

Dependency Injection

Share logic across endpoints using Depends().

python
💡 Dependencies with yield run cleanup code after the response — perfect for DB sessions
⚡ Sub-dependencies chain automatically: get_admin_user → get_current_user → oauth2_scheme
📌 Use Depends() without arguments on a class to use it directly as a dependency
🟢 Global dependencies apply to every route — great for API key verification
dependenciesdependsinjection

Security & Authentication

Implement OAuth2 with JWT tokens and password hashing.

OAuth2 with JWT

Implement token-based authentication with password hashing.

python
💡 OAuth2PasswordBearer auto-adds a login button to the /docs UI
⚡ Install dependencies: pip install python-jose[cryptography] passlib[bcrypt]
📌 Never store plain-text passwords — always hash with bcrypt via passlib
🟢 Chain dependencies: protected routes just add user = Depends(get_current_user)
authjwtoauth2security

Error Handling

Raise HTTP errors and define custom exception handlers.

HTTPException & Custom Handlers

Return proper error responses and handle exceptions globally.

python
💡 HTTPException is the standard way to return error responses in FastAPI
⚡ Use @app.exception_handler() to catch custom exceptions globally
📌 Override RequestValidationError handler to customize 422 validation responses
🟢 You can add custom headers to HTTPException for debugging or auth flows
errorsexceptionshttp

Middleware & CORS

Add middleware for cross-cutting concerns and configure CORS.

CORS & Custom Middleware

Configure CORS and write custom middleware for logging, timing, etc.

python
💡 Middleware runs on every request/response — use for logging, timing, auth checks
⚡ Set allow_origins to specific domains in production — never use ["*"] with credentials
📌 Middleware order matters — they execute in reverse order of how they're added
🟢 Built-in middleware: CORSMiddleware, TrustedHostMiddleware, HTTPSRedirectMiddleware
corsmiddleware

Database Integration

Connect to databases with SQLAlchemy or SQLModel.

SQLAlchemy Setup

Configure SQLAlchemy with FastAPI using dependency injection.

python
💡 Use the yield dependency pattern to ensure DB sessions are always closed
⚡ For PostgreSQL, install: pip install psycopg2-binary
📌 check_same_thread is only needed for SQLite — remove it for other databases
🟢 Call Base.metadata.create_all() once at startup to create tables
databasesqlalchemysetup

CRUD Operations

Create, read, update, and delete records with SQLAlchemy.

python
💡 Use model_dump(exclude_unset=True) for PATCH-style partial updates
⚡ db.refresh() reloads the object from the DB — gets auto-generated fields like id
📌 Always check if the record exists before updating/deleting — raise 404 if not
🟢 Use sync def (not async def) for SQLAlchemy — it uses blocking I/O by default
cruddatabasesqlalchemy

Project Structure

Organize larger applications with APIRouter and multiple files.

APIRouter & Multiple Files

Split routes into separate files using APIRouter.

python
💡 APIRouter works exactly like FastAPI() — same decorators, same parameters
⚡ Use tags=["items"] to group endpoints under a section in the docs UI
📌 Set prefix on the router to avoid repeating "/items" on every route
🟢 Add dependencies at include_router() level to protect entire route groups
routerstructureorganization

Advanced Features

Background tasks, lifespan events, streaming, WebSockets, and testing.

Background Tasks & Lifespan

Run tasks after returning a response and manage app startup/shutdown.

python
💡 Background tasks run after the response — the client doesn't wait for them
⚡ Use lifespan for startup tasks: loading ML models, connecting to DBs, etc.
📌 For heavy background work, use Celery or ARQ instead of BackgroundTasks
🟢 Store shared resources on app.state inside the lifespan context
backgroundlifespanstartupshutdown

Streaming, WebSockets & Testing

Stream responses, use WebSockets, and test with TestClient.

python
💡 StreamingResponse with text/event-stream gives you Server-Sent Events (SSE)
⚡ TestClient uses requests-style API — no need to start a real server
📌 Use app.dependency_overrides to swap real DB for test DB in tests
🟢 WebSocket endpoints use await ws.receive_text() and ws.send_text() in a loop
streamingwebsockettestingsse