Basics
Installation
pip install fastapi
pip install "uvicorn[standard]"
Basic App Structure
from fastapi import FastAPI
app = FastAPI(
title="My API",
description="A simple API example",
version="1.0.0"
)
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
Running the Application
Development Server
uvicorn main:app --reload
uvicorn main:app --reload --port 8080
uvicorn main:app --reload --host 0.0.0.0
Production Server
uvicorn main:app --host 0.0.0.0 --port 8000
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
HTTP Methods
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
@app.post("/items/")
async def create_item(item: Item):
return item
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
return {"message": f"Item {item_id} deleted"}
@app.patch("/items/{item_id}")
async def patch_item(item_id: int, item: ItemUpdate):
return {"item_id": item_id, **item.dict()}
Path Parameters
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(user_id: int, item_id: str):
return {"user_id": user_id, "item_id": item_id}
# Path parameter with validation
from fastapi import Path
@app.get("/items/{item_id}")
async def read_item(
item_id: int = Path(..., title="The ID of the item", gt=0, le=1000)
):
return {"item_id": item_id}
Query Parameters
@app.get("/items/")
async def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
# Optional query parameters
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str = None, short: bool = False):
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not short:
item.update({"description": "This is an amazing item"})
return item
# Query parameter validation
from fastapi import Query
@app.get("/items/")
async def read_items(
q: str = Query(None, min_length=3, max_length=50),
skip: int = Query(0, ge=0),
limit: int = Query(10, gt=0, le=100)
):
return {"q": q, "skip": skip, "limit": limit}
Request Body
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
return item
# Multiple request bodies
@app.post("/items/{item_id}")
async def create_item(item_id: int, item: Item, user: User):
return {"item_id": item_id, "item": item, "user": user}
Response Models
from pydantic import BaseModel
class ItemResponse(BaseModel):
name: str
price: float
@app.post("/items/", response_model=ItemResponse)
async def create_item(item: Item):
return item
# Multiple response models
from fastapi import status
@app.post("/items/", response_model=ItemResponse, status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
return item
Error Handling
from fastapi import HTTPException
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
# Custom exception handler
from fastapi import Request
from fastapi.responses import JSONResponse
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something"}
)
App Configuration
from fastapi import FastAPI
app = FastAPI(
title="My Super Project",
description="This is a very fancy project",
version="2.5.0",
openapi_url="/api/v1/openapi.json",
docs_url="/documentation",
redoc_url="/redoc"
)
# Disable docs in production
app = FastAPI(docs_url=None, redoc_url=None)