FastAPI is one of the hottest web frameworks in the Python ecosystem, known for its high performance, automatic documentation generation, and strong type hints. It’s especially suitable for building RESTful APIs and data interfaces. This guide will take you from zero to proficiency using 8 code examples, step-by-step!
I. Environment Setup
First, install the required libraries (Python 3.7+):
bash
pip install fastapi uvicorn
fastapi: The core framework.uvicorn: An ASGI server (used to run FastAPI applications).
II. Hello World: Your First FastAPI App
Create a file main.py and write the following code:
python
from fastapi import FastAPI
# Create a FastAPI instance
app = FastAPI()
# Define a route: GET request + root path
@app.get("/")
def read_root():
return {"message": "Hello FastAPI!"}
# Startup command (run in terminal):
# uvicorn main:app --reload
Run it:
- After running the startup command in the terminal, you’ll see output like this:textINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [xxxxx] using WatchFiles
- Visit
http://127.0.0.1:8000in your browser. You’ll see the JSON response:{"message": "Hello FastAPI!"} - Automatically generated API docs: Visit
http://127.0.0.1:8000/docsfor Swagger UI interactive documentation (allows direct API testing). Visithttp://127.0.0.1:8000/redocfor a cleaner ReDoc version.
III. Core Features: Path Parameters & Query Parameters
3.1 Path Parameters (Parameters in the URL)
Used for passing required resource identifiers (e.g., user ID, product ID).
python
from fastapi import FastAPI
app = FastAPI()
# Path parameter: `item_id` is part of the path, type-hinted as `int`
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
3.2 Query Parameters (Parameters after ? in the URL)
Used for passing optional filtering criteria (e.g., pagination, search keywords).
python
# Example request: /items/5?q=apple
# Response: {"item_id": 5, "q": "apple"}
# Without `q`: /items/5
# Response: {"item_id": 5, "q": null}
3.3 Type Validation & Default Values
FastAPI automatically performs data validation based on type hints.
python
# If you visit /items/abc (where item_id is not an int), a 422 error is returned:
# {"detail": [{"loc": ["path", "item_id"], "msg": "value is not a valid integer", "type": "type_error.integer"}]}
IV. Request Body: Receiving JSON Data
Used for passing complex data when creating resources (e.g., user registration, form submission). Uses Pydantic for data validation.
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Define a request body model (Pydantic)
class Item(BaseModel):
name: str # Required field (no default value)
price: float # Required field
is_offer: bool = None # Optional field (default is None)
# Handle POST request + JSON body
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price": item.price}
How to test:
- Go to
http://127.0.0.1:8000/docs, find the/items/endpoint, click “Try it out”, and input this JSON:json{ “name”: “iPhone”, “price”: 5999.9, “is_offer”: true } - Click “Execute”. Response:
{"item_name": "iPhone", "item_price": 5999.9}. - If required fields are missing (e.g.,
name), a 422 error is automatically returned with details.
V. Comprehensive Example: Book Management API
A complete CRUD example showcasing practical FastAPI use.
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI()
# 1. Define a data model
class Book(BaseModel):
id: Optional[int] = None # ID is optional (auto-generated on creation)
title: str
author: str
price: float
# 2. Mock database (use MySQL/PostgreSQL in real projects)
books = [
Book(id=1, title="Python Programming", author="张三", price=59.9),
Book(id=2, title="FastAPI Guide", author="李四", price=49.9)
]
# 3. CRUD Endpoint Implementations
# Get all books
@app.get("/books", response_model=List[Book])
def get_all_books():
return books
# Get a single book (by ID)
@app.get("/books/{book_id}", response_model=Book)
def get_book(book_id: int):
for book in books:
if book.id == book_id:
return book
# If not found, return a 404 error
raise HTTPException(status_code=404, detail="Book not found")
# Create a book
@app.post("/books", response_model=Book)
def create_book(book: Book):
# Generate a new ID (last book's ID + 1, or 1 if list is empty)
new_id = books[-1].id + 1 if books else 1
new_book = Book(id=new_id, **book.dict())
books.append(new_book)
return new_book
# Update a book
@app.put("/books/{book_id}", response_model=Book)
def update_book(book_id: int, updated_book: Book):
for idx, book in enumerate(books):
if book.id == book_id:
# Keep original ID, update other fields
books[idx] = Book(id=book_id, **updated_book.dict())
return books[idx]
raise HTTPException(status_code=404, detail="Book not found")
# Delete a book
@app.delete("/books/{book_id}")
def delete_book(book_id: int):
for idx, book in enumerate(books):
if book.id == book_id:
books.pop(idx)
return {"detail": "Book deleted"}
raise HTTPException(status_code=404, detail="Book not found")
Testing:
- Visit
http://127.0.0.1:8000/docsto test all endpoints interactively. - For example, when creating a book, the input JSON is automatically validated for field types.
- Responses strictly follow the format defined by
response_model.
VI. Useful Feature: Dependency Injection
FastAPI’s dependency injection system simplifies code reuse (e.g., for authorization, database connections).
python
from fastapi import FastAPI, Depends
app = FastAPI()
# Define a dependency (reusable logic)
def get_current_user():
# In a real project, parse user info from a token here
return {"username": "admin", "role": "admin"}
# Use the dependency in an endpoint
@app.get("/users/me")
def read_current_user(user: dict = Depends(get_current_user)):
return user
Run it: Visit /users/me, response: {"username": "admin", "role": "admin"}.
VII. CORS (Cross-Origin Resource Sharing)
If your frontend (e.g., Vue/React) needs to call the API, you must handle CORS.
python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Configure allowed origins, methods, headers
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # In production, specify exact domains (e.g., ["http://localhost:8080"])
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods
allow_headers=["*"], # Allow all headers
)
@app.get("/")
def read_root():
return {"message": "CORS configured"}
VIII. Deployment for Production
Development uses --reload for auto-restarts. Production requires optimized configuration.
bash
# Production startup command (using Gunicorn as a reverse proxy) pip install gunicorn # Run: workers = (CPU cores * 2) + 1 gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
Summary
FastAPI’s core advantages:
- High Performance: Built on ASGI, supports async, performance close to Node.js/Go.
- Automatic Documentation: Generates interactive API docs with no extra configuration.
- Strong Type Validation: Pydantic ensures data validity, reducing debugging effort.
- Ease of Use: Clean syntax, gentle learning curve.