Run server
fastapi dev
Dev server with reload (auto-detects app)
fastapi dev <path/to/file.py>
Run a specific file or package
fastapi run
Production mode, no reload, 0.0.0.0
fastapi dev --port <port>
Change the port (default 8000)
fastapi dev --host 0.0.0.0
Listen on all interfaces
fastapi dev --app <name>
Pick the app variable in the module
fastapi dev -e <module:app>
Give the import string directly
fastapi run --workers <n>
Several worker processes
Cannot be combined with --reload.
fastapi run --root-path /api
App sits behind a path-prefix proxy
fastapi run --forwarded-allow-ips '*'
Trust X-Forwarded-* from any proxy
fastapi dev --reload-dir <dir>
Watch only this directory
fastapi --version
Show CLI version
App and routes
app = FastAPI(title="<name>")
Create the app
@app.get("/")
Handle GET requests
@app.post("/items")
Handle POST requests
@app.put("/items/{item_id}")
Handle PUT requests
@app.delete("/items/{item_id}")
Handle DELETE requests
@app.get("/x", tags=["x"],
summary="...")
Group and label docs entries
@app.get("/x", deprecated=True)
Mark route deprecated in docs
router = APIRouter(prefix="/items")
Group routes in a module
app.include_router(router)
Mount a router
app.mount("/static",
StaticFiles(directory="static"))
Serve static files
FastAPI(lifespan=<ctx>)
Startup and shutdown logic
app.add_middleware(CORSMiddleware,
allow_origins=[...])
Enable CORS
Parameters
def f(item_id: int)
Path parameter from {item_id}
def f(skip: int = 0, limit: int = 10)
Query parameters with defaults
def f(q: str | None = None)
Optional query parameter
q: Annotated[str, Query(max_length=50)]
Validate a query parameter
n: Annotated[int, Path(ge=1)]
Validate a path parameter
tags: Annotated[list[str], Query()]
Repeated query values (?tags=a&tags=b)
x: Annotated[str | None, Header()] = None
Read a request header
c: Annotated[str | None, Cookie()] = None
Read a cookie
name: Annotated[str, Form()]
Read a form field
Needs the python-multipart package.
f: UploadFile
Receive an uploaded file
{path:path}
Path parameter that may contain slashes
Query(alias="item-query")
Use a name that is not a Python identifier
Responses
@app.get("/x", response_model=Item)
Filter and document the output
@app.post("/x", status_code=201)
Set the success status code
from fastapi import status
Named codes: status.HTTP_201_CREATED
raise HTTPException(status_code=404,
detail="...")
Send an error response
response_model_exclude_none
Omit None fields from output
return JSONResponse(content=<d>,
status_code=<n>)
Build the response yourself
return RedirectResponse("/new")
Redirect the client
return FileResponse(<path>)
Send a file from disk
return StreamingResponse(<gen>)
Stream a generator
def f(response: Response)
Set headers or cookies on the response
@app.exception_handler(<Exc>)
Custom handler for an exception
Dependencies
def f(db: Annotated[Session, Depends(get_db)])
Inject a dependency
CommonParams = Annotated[dict, Depends(common)]
Reusable dependency alias
def get_db(): yield db
Dependency with cleanup after the response
@app.get("/x",
dependencies=[Depends(<f>)])
Run a dependency without using its value
FastAPI(dependencies=[Depends(<f>)])
Apply to every route
app.dependency_overrides[<d>] = <f>
Swap a dependency in tests
OAuth2PasswordBearer(tokenUrl="token")
Bearer-token security scheme
def f(tasks: BackgroundTasks)
Queue work after the response
tasks.add_task(<func>, <arg>)
Schedule a background job
Testing and docs
client = TestClient(app)
Test client (needs httpx)
client.get("/items/1")
Call a route in a test
client.post("/items", json={...})
POST a JSON body
assert r.status_code == 200
Check the status
r.json()
Decode the JSON response
with TestClient(app) as client:
Also run lifespan startup/shutdown
/openapi.json
OpenAPI schema
FastAPI(docs_url=None, redoc_url=None)
Disable the docs pages
FastAPI(openapi_url=None)
Disable schema and docs entirely