Run main.py in development mode
fastapi dev main.py
Create FastAPI app
app = FastAPI()
How to define path parameters?
Define get endpoint accepting id in URL
Path paramters: define them in path like variables in format string, accept them in argument list (same name).
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}How to define query parameters
Query paramters: when you declare other function parameters that are not part of the path parameters, they are automatically interpreted as “query” parameters.
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip: skip + limit]How to limit path parameters to predefined set of values
Use enum to define parameter model.
class ModelName(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
passAnnotated[int, Path(<<VALIDATION OPTIONS>>)]
Can be also used for Query(), Body(), Header(), and Cookie()
Validation is same as pydantic fields.
@app.get("/items/{item_id}")
async def read_items(item_id: Annotated[int, Path(title="The ID of the item to get")]):
results = {"item_id": item_id}
return resultsHow to define common set of query parameters (to be shared by multiple endpoints)
FastAPI will extract the data for each field from the query parameters in the request and give you the Pydantic model you defined.
Use Query Parameter Models.
class FilterParams(BaseModel):
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_queryHow to define request body
To declare a request body, you use Pydantic models.
class Item(BaseModel):
name: str
@app.post("/items/")
async def create_item(item: Item):
passDefine POST endpoint /items
@app.post("/items/")
Define GET endpoint /items with "items" tag, short and long description of it.
@app.get("/items",
tags=["items"], # they will define sections in Swagger UI
summary="Short",
description="More descriptive"
)
async def read_items():
passHow to return HTTP 404 error
Throw HTTPException
raise HTTPException(
status_code=404,
detail="Item not found",
headers={"X-Error": "There goes my error"},
)Read cookie named ads_id
@app.get("/items/")
async def read_items(ads_id: Annotated[str | None, Cookie()] = None):
return {"ads_id": ads_id}Define set of possible cookies that endpoint can accept
class Cookies(BaseModel):
# Forbid Extra
model_config = {"extra": "forbid"}
session_id: str
fatebook_tracker: str | None = None
googall_tracker: str | None = None
@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
return cookiesRead User-Agent heade rin endpoint
@app.get("/items/")
async def read_items(user_agent: Annotated[str | None, Header()] = None):
return {"User-Agent": user_agent}Respond with status code 201 on success from an endpoint
@app.post("/items/", status_code=201)
async def create_item(name: str):
return {"name": name}Accept form fields for username and password
Required: pip install python-multipart
@app.post("/login/")
async def login(username: Annotated[str, Form()], password: Annotated[str, Form()]):
return {"username": username}How to define path dependencies
Dependency should be a "callable". You can use a Python class as a dependency.
# Define Dependency
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
return commonsUsing class
class CommonQueryParams:
def \_\_init\_\_(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
async def read_items(commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]):
# commons: Annotated[CommonQueryParams, Depends()] # shortcut
passHow to add CORS support
app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
How to test FastAPI apps
Use TestClient based on httpx (similar API to requests)
from fastapi.testclient import TestClient
from .main import app
client = TestClient(app)
def test_read_item():
response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})