Skip to content

fastapi-explicit-openapi-contract

Visible FastAPI operations pin locally reviewable metadata and avoid statically provable OpenAPI gaps.

Why

FastAPI can infer valid schemas and default statuses. This stricter organizational policy pins locally reviewable metadata while also detecting response, status, and routing mismatches that inference cannot fix.

Fix

Follow the diagnostic family: pin operation metadata, annotate parameter locations, preserve concrete schemas, document escaping alternate statuses, or correct a statically proven route conflict.

Examples

Before — flagged Visible operation without an explicit success status
api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/users")
async def users() -> list[UserResponse]:
return []
After — preferred Operation with an explicit OpenAPI contract
api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/users", status_code=200)
async def read_users() -> list[UserResponse]:
return []
Before — flagged Unnamed record leaves the response schema implicit
api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/health", status_code=200)
async def health():
return {"status": "ok"}
After — preferred Named response type documents the record
api.py
from fastapi import APIRouter
from pydantic import BaseModel
class HealthResponse(BaseModel):
status: str
router = APIRouter()
@router.get("/health", status_code=200)
async def health() -> HealthResponse:
return HealthResponse(status="ok")
Before — flagged A bare mapping erases the generated response schema
api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/users", status_code=200)
async def read_users() -> dict:
return {}
After — preferred A named response type preserves a concrete schema
api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/users", status_code=200)
async def read_users() -> list[UserResponse]:
return []

Formerly: fastapi-openapi-contract