Begin by installing FastAPI with all recommended dependencies. This includes the ASGI server
uvicorn, which is commonly used to run FastAPI applications.
pip install fastapi[all]
This command ensures you have FastAPI and the tools to run it in development mode.
To start building your API, import FastAPI and create an app instance. This instance will be used to define routes and middleware.
from fastapi import FastAPI
app = FastAPI()
This app serves as the main entry point for your API.
Routing defines how your application handles incoming HTTP requests. Use decorators with HTTP methods to register endpoint functions.
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.post("/items/")
async def create_item(item: dict):
return item
Here, read_root handles GET requests to the root path, and create_item handles POST
requests to /items/.
Path parameters are part of the URL and defined in route paths, while query parameters are optional key-value pairs.
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
item_id is required and extracted from the URL; q is an optional query parameter passed
as ?q=somevalue.
Use Pydantic models to define the expected JSON request body structure. FastAPI automatically parses and validates request bodies using these models.
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None
@app.post("/items/")
async def create_item(item: Item):
return item
The Item model defines the data schema expected in the POST body.
Define response models with Pydantic to control and document the shape of responses returned by your endpoints.
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int):
return {"name": "Foo", "price": 42.0}
This ensures the response will always conform to the declared schema, improving reliability and auto-generated docs.
FastAPI supports dependencies for reusable logic like validation, authentication, or common parameters.
from fastapi import Depends
def common_parameters(q: str | None = None):
return q
@app.get("/items/")
async def read_items(q: str = Depends(common_parameters)):
return {"q": q}
Depends allows the app to call common_parameters beforehand and inject its return
value.
Raise HTTP exceptions to provide custom error responses and status codes.
from fastapi import HTTPException
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id != 42:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}
This raises a 404 Not Found error with a JSON message if the item ID is not found.
Perform slower tasks like sending emails or logging asynchronously with background tasks, so the API response is not delayed.
from fastapi import BackgroundTasks
def write_log(message: str):
with open("log.txt", "a") as log:
log.write(message + "\n")
@app.post("/send/")
async def send_email(background_tasks: BackgroundTasks, email: str):
background_tasks.add_task(write_log, f"Send email to {email}")
return {"message": "Email sent in background"}
Tasks added to background_tasks run after the response is sent.
Middleware intercepts requests and responses globally allowing modification, logging, or custom headers.
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class SimpleMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
response = await call_next(request)
response.headers["X-Custom-Header"] = "Value"
return response
app.add_middleware(SimpleMiddleware)
This example adds a custom header to every response.
FastAPI integrates security utilities like OAuth2 tokens to protect endpoints.
from fastapi.security import OAuth2PasswordBearer
from fastapi import Depends
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
return {"token": token}
This endpoint extracts and returns the token from the HTTP Authorization header.
Use uvicorn to serve your FastAPI app. The --reload option enables live-reload during
development.
uvicorn main:app --reload
Here main is the filename (without .py), and app is the FastAPI instance.