FastAPI 教程
FastAPI 教程(中文版)
FastAPI 是一个现代、高性能的 Python Web 框架,用于构建 API。它基于 Python 类型提示(type hints),自动生成 OpenAPI 文档,支持异步,速度极快(与 Node.js 和 Go 相当)。
1. 安装 FastAPI 和 Uvicorn
pip install fastapi uvicorn
fastapi: 框架本体uvicorn: ASGI 服务器,用于运行 FastAPI 应用
2. 第一个 FastAPI 应用
创建 main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
运行应用
uvicorn main:app --reload
--reload:开发模式,代码修改后自动重启
访问:
- API: http://127.0.0.1:8000
- 自动文档(Swagger UI): http://127.0.0.1:8000/docs
- OpenAPI JSON: http://127.0.0.1:8000/openapi.json
3. 路径参数与查询参数
@app.get("/users/{user_id}")
def get_user(user_id: int, active: bool = True):
return {"user_id": user_id, "active": active}
user_id: 路径参数(必填)active: 查询参数(可选,默认True)
4. 请求体(POST)
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price_with_tax": item.price + (item.tax or 0)}
Pydantic 自动验证数据类型和格式
5. 查询参数与字符串验证
from fastapi import Query
@app.get("/items/")
def read_items(
skip: int = 0,
limit: int = 10,
q: str = Query(None, min_length=3, max_length=50)
):
return {"skip": skip, "limit": limit, "q": q}
6. 路径参数验证
from fastapi import Path
@app.get("/items/{item_id}")
def read_item(item_id: int = Path(..., gt=0, le=100)):
return {"item_id": item_id}
...表示必填gt=0:大于 0le=100:小于等于 100
7. 响应模型
from pydantic import BaseModel
class UserOut(BaseModel):
id: int
username: str
email: str | None = None
@app.get("/users/{user_id}", response_model=UserOut)
def get_user(user_id: int):
# 模拟数据库
return {"id": user_id, "username": "john_doe", "email": "john@example.com"}
只返回
response_model中定义的字段
8. 依赖注入(Dependency Injection)
from fastapi import Depends
async def get_current_user():
return {"user_id": 1, "username": "alice"}
@app.get("/profile")
def get_profile(user=Depends(get_current_user)):
return user
9. 异步支持
import asyncio
@app.get("/async")
async def async_endpoint():
await asyncio.sleep(1)
return {"message": "This is async!"}
10. 异常处理
from fastapi import HTTPException
@app.get("/items/{item_id}")
def read_item(item_id: int):
if item_id not in [1, 2, 3]:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}
11. 中间件(Middleware)
from fastapi import Request
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
12. 数据库集成(示例:SQLAlchemy + SQLite)
pip install sqlalchemy databases[sqlite]
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine)
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
Base.metadata.create_all(bind=engine)
# 在路由中使用
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/")
def create_user(name: str, db=Depends(get_db)):
user = User(name=name)
db.add(user)
db.commit()
db.refresh(user)
return user
13. 静态文件与模板
pip install jinja2
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import Request
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/html")
def get_html(request: Request):
return templates.TemplateResponse("index.html", {"request": request, "title": "FastAPI"})
templates/index.html:
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
<h1>Hello from FastAPI + Jinja2!</h1>
</body>
</html>
14. 安全(API Key 示例)
from fastapi import Security, Depends
from fastapi.security.api_key import APIKeyHeader
API_KEY = "secret123"
api_key_header = APIKeyHeader(name="X-API-Key")
def get_api_key(key: str = Depends(api_key_header)):
if key != API_KEY:
raise HTTPException(status_code=403, detail="Invalid API Key")
return key
@app.get("/secure")
def secure_endpoint(api_key: str = Depends(get_api_key)):
return {"message": "Secure data"}
15. 测试 FastAPI
from fastapi.testclient import TestClient
client = TestClient(app)
def test_read_root():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"Hello": "World"}
运行测试:
pip install pytest
pytest
16. 部署建议
| 方式 | 推荐工具 |
|---|---|
| 本地开发 | uvicorn main:app --reload |
| 生产部署 | uvicorn main:app --host 0.0.0.0 --port 80 --workers 4 |
| 容器化 | Docker + Gunicorn + Uvicorn |
Dockerfile 示例:
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
官方资源
- 文档:https://fastapi.tiangolo.com/zh/
- GitHub:https://github.com/tiangolo/fastapi
- 中文教程:https://fastapi.tiangolo.com/zh/tutorial/
小结
| 特性 | 说明 |
|---|---|
| 速度快 | 基于 Starlette,异步支持 |
| 自动文档 | Swagger UI + ReDoc |
| 类型安全 | Pydantic 验证 |
| 依赖注入 | 简洁优雅 |
| 易测试 | 内置 TestClient |
现在开始你的第一个 FastAPI 项目吧!
fastapi dev main.py # FastAPI CLI(0.104+)
推荐使用
fastapi-cli:pip install fastapi[all]
需要我为你生成一个完整的 FastAPI + SQLAlchemy + JWT 认证 + Docker 的项目模板吗?可以继续问我!