Why FastAPI?
FastAPI is a Python framework for building web APIs. It relies on Python’s type annotations: from the signature of your functions, it validates incoming data, converts responses to JSON and generates interactive documentation. It is built on Starlette (the web part) and Pydantic (validation). This course uses FastAPI 0.162 and Pydantic 2.14 (Python 3.10 or newer). It is today one of the most popular choices for Python APIs, including for serving machine learning models.
Installation
In a virtual environment:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install "fastapi[standard]" # latest version: FastAPI + Uvicorn server + CLI tools
A first application
# main.py
from fastapi import FastAPI
app = FastAPI(title="Shop API", version="1.0.0") # the application object
@app.get("/") # path operation: GET method on "/"
def racine():
# A returned dict is automatically converted to JSON
return {"message": "Bienvenue sur l'API"}
@app.get("/sante")
def sante():
return {"statut": "ok"}
You run the development server, which reloads on every change:
fastapi dev main.py
# -> Serving at: http://127.0.0.1:8000
In production, you use fastapi run main.py (no auto-reload). Then test:
curl http://127.0.0.1:8000/sante
# {"statut":"ok"}
The automatic documentation
Open http://127.0.0.1:8000/docs: FastAPI generates a Swagger UI interface that lists your routes and lets you try them out (“Try it out”). Another presentation is available at /redoc. Both read the OpenAPI schema exposed as JSON at /openapi.json, a standard that other tools can use (client generation, tests).
What does the decorator do?
@app.get("/") registers the racine function in the application’s routing table: “when a GET request arrives at /, call this function”. The decorator returns the function unchanged. When a request is received, FastAPI looks for the matching route:
- found → it calls the function and serializes the result as JSON (status 200 by default);
- unknown path →
404with{"detail": "Not Found"}; - known path but another method (POST instead of GET) →
405 Method Not Allowed.
There is one decorator per HTTP method: @app.get, @app.post, @app.put, @app.patch, @app.delete.
def or async def?
@app.get("/meteo")
async def meteo():
# async def is useful if you await an asynchronous operation:
# données = await client_http.get(...)
return {"ciel": "dégagé"}
If your function does not use await (or uses classic blocking libraries), simply write def: FastAPI runs it in a thread pool without blocking the server. Using async def and then calling blocking code (a synchronous SQL query, time.sleep) would block all requests.
Key takeaways
app = FastAPI(), one decorator per route, functions that return dicts.fastapi devto develop,/docsto explore and test.defby default,async defwhen you useawait.
Exercises
Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.
A mini router with decorators
To understand what
@app.getdoes, implement theMiniAppclass:routes: dictionary(method, path) -> function;get(chemin)andpost(chemin): decorators that register the function and return it unchanged;appeler(methode, chemin): returns(200, json)with the result serialized byjson.dumps(..., ensure_ascii=False),(404, '{"detail": "Not Found"}')if the path is unknown,(405, '{"detail": "Method Not Allowed"}')if the path exists for another method.
Then create
app = MiniApp()and two GET routes:/returning{"message": "Bienvenue sur l'API"}and/santereturning{"statut": "ok"}.import json class MiniApp: def __init__(self): self.routes = {} def get(self, chemin): ... def post(self, chemin): ... def appeler(self, methode, chemin): ... app = MiniApp() # @app.get("/") ...Run your first FastAPI API
In your working environment: create a virtual environment, install
fastapi[standard], writemain.pywith the/and/santeroutes, then runfastapi dev main.py. Query the API withcurland open/docs. Finally, add a/versionroute that returns{"version": "1.0.0"}and check that it appears in the documentation without restarting.- curl http://127.0.0.1:8000/sante returns {"statut":"ok"}
- The /docs page lists the three routes
- The /version route appears after saving thanks to auto-reload
- curl on a nonexistent route returns {"detail":"Not Found"} with status 404
Automatic documentation
At which URL does FastAPI serve the Swagger UI interface by default?
- /swagger
- /docs
- /api
- /openapi
End-of-lesson quiz
What does FastAPI do with a dict returned by a route function?
- It displays it as HTML
- It converts it to a JSON response
- It raises an error
Which command runs the development server with auto-reload?
- fastapi dev main.py
- python main.py --reload
- fastapi run main.py
When should you use async def?
- Always, it's faster
- When the function uses await on asynchronous operations
- Never with FastAPI
The rest of the course
- Path and Query Parameters18 min
- Request Bodies and Pydantic Models20 min
- Full CRUD, HTTP Errors and Routers20 min
- Dependencies, Database and Tests20 min