Skip to main content

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)