FastAPI builds documentation from routes, types, and Pydantic models. /docs is
therefore a visual representation of your API contract, not a separate document.
For a learner, Swagger UI is a laboratory: inspect parameters, send a real request,
and immediately check the status code and response body.
What to open after startup
http://127.0.0.1:8000/docsโ Swagger UI with Try it out;http://127.0.0.1:8000/redocโ reference-style documentation;http://127.0.0.1:8000/openapi.jsonโ the source OpenAPI schema.
Swagger UI and ReDoc read the same schema. If a UI looks wrong, inspect
/openapi.json first.
Exercise an endpoint
- Expand the endpoint and select Try it out.
- Fill in path, query, or body parameters.
- Select Execute.
- Compare Request URL, status code, and response body with the task.
- Send invalid data and inspect the
422response.
This is useful manual exploration, not a replacement for automated tests.
Add API information
from fastapi import FastAPI
app = FastAPI(
title="Task Manager API",
summary="API for a learning task manager",
description="Create, find, update, and delete tasks.",
version="1.0.0",
contact={"name": "Support", "email": "support@example.com"},
)
version describes your API, not FastAPI. description supports Markdown.
Describe and group routes
from fastapi import APIRouter, status
router = APIRouter(prefix="/tasks", tags=["Tasks"])
@router.get(
"/",
summary="List tasks",
description="Returns tasks with filtering and pagination.",
response_description="The matching tasks",
status_code=status.HTTP_200_OK,
)
def list_tasks():
return []
app.include_router(router)
summary names the action, description explains important behavior, and a tag
groups one resource. Endpoints do not appear until their router is included.
Show request and response bodies
from pydantic import BaseModel, Field
class TaskCreate(BaseModel):
title: str = Field(
min_length=3,
max_length=120,
description="A short task title",
examples=["Write tests"],
)
class TaskRead(TaskCreate):
id: int
@router.post("/", response_model=TaskRead, status_code=201)
def create_task(task: TaskCreate):
return {"id": 1, **task.model_dump()}
Field contributes constraints and an input example. response_model documents and
validates the response and filters fields absent from the public model. Prefer modern
examples=[...] over the deprecated single example.
Expected failures can be documented too:
@router.get(
"/{task_id}",
response_model=TaskRead,
responses={404: {"description": "Task not found"}},
)
def get_task(task_id: int):
...
Documentation does not implement the error. The route must actually return 404, and
a test should confirm it.
Authorization in Swagger UI
OAuth2PasswordBearer adds Authorize:
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")
The route must use the security dependency. tokenUrl points to the endpoint that
issues a token.
Common problems
- No response schema โ add a return type or
response_model. - A parameter appears in query instead of body โ use a Pydantic model for the body.
- An endpoint is absent โ check
include_router. - An example is missing โ use
examples=[...]orjson_schema_extra. - Authorize is absent โ attach the security dependency to the route.
- The schema looks stale โ restart the server and refresh without browser cache.
Before finishing, run one successful and one failing request through /docs. Confirm
that input constraints, success status, response schema, and expected failures appear.
๐ฌ Comments (0)
No comments yet
Be the first to share your opinion about this article!