FastAPI 是当下 Python 异步 Web 框架的"顶流"。它基于 Starlette (异步底层)+ Pydantic (数据校验)+ Uvicorn(ASGI 服务),让你用几乎写纯 Python 的方式,自动获得类型校验、自动文档、异步高并发三大能力。本文包含可直接运行的完整代码,读完就能上手写生产级接口。
一、FastAPI 是什么?一句话定位
FastAPI 是一个现代、高性能的 Python Web 框架 ,专门用于构建 API。
它不发模板、不做后台管理(那是 Django 的活),它只做一件事:让你用最快的速度、最少的代码、最强的类型约束,写出能扛高并发的 RESTful API。
如果你之前用 Flask 写接口,你会爱上它的自动校验;如果你用 Django REST Framework,你会惊讶于它的轻量和速度。
二、FastAPI 的"三大件":核心依赖组件
FastAPI 本身并不从零造轮子,而是站在巨人肩膀上。理解它的核心依赖,才能理解它为什么快、为什么好用。
| 核心组件 | 角色定位 | FastAPI 用它做什么 |
|---|---|---|
| Starlette | ASGI 工具集 / 异步底层框架 | 提供路由、请求/响应对象、WebSocket、后台任务、中间件等底层能力 |
| Pydantic | 数据验证与序列化库 | 利用 Python 类型注解做请求参数校验、自动转换、文档生成 |
| Uvicorn | ASGI 服务器(基于 uvloop + httptools) | 运行 FastAPI 应用,支持异步事件循环,性能碾压传统的 WSGI(如 Gunicorn + Flask) |
三者的关系:
scss
你的业务代码 (FastAPI)
↓
路由/中间件/WS (Starlette)
↓
数据校验/序列化 (Pydantic)
↓
高性能 ASGI 服务 (Uvicorn)
三、为什么选 FastAPI?5 大核心优势
和传统框架对比,FastAPI 的优势不是"好一点",而是代际差距:
| 能力 | Flask | Django DRF | FastAPI |
|---|---|---|---|
| 异步原生支持 | ❌ 需插件 | ❌ 需 Channels | ✅ 原生 async/await |
| 数据自动校验 | ❌ 手动写 | ⚠️ Serializer 类 | ✅ Pydantic 类型注解自动校验 |
| 自动 API 文档 | ❌ 手写 Swagger | ⚠️ 需配置 | ✅ 自动生成 Swagger + ReDoc |
| 性能(并发) | 低(WSGI) | 低(WSGI) | 高(ASGI,接近 Node.js/Go) |
| 学习曲线 | 平缓 | 较陡 | 极平缓(会 Python 类型注解就会用) |
优势 1:类型注解即文档 + 校验
你写的 Python 类型,同时变成了:
- 请求参数校验器(非法请求自动 422)
- 接口文档的参数说明
- IDE 的智能提示
优势 2:异步原生,性能拉满
基于 ASGI 和 asyncio,单实例轻松支撑数千并发连接,特别适合:
- 高并发 API 网关
- 微服务间大量 RPC 调用
- 长连接(WebSocket、SSE)
优势 3:自动生成双文档
启动服务后,访问:
/docs→ Swagger UI(交互式调试,前端最爱)/redoc→ ReDoc(美观的只读文档)
四、实战:15 行代码跑起来
4.1 安装
bash
pip install fastapi uvicorn
4.2 最小 Hello World
python
# main.py
from fastapi import FastAPI
app = FastAPI(title="我的第一个 FastAPI 服务")
@app.get("/")
async def root():
return {"message": "Hello FastAPI", "framework": "🚀"}
# 运行:uvicorn main:app --reload
启动命令拆解:
main:Python 文件名(main.py)app:FastAPI 实例名--reload:开发模式,代码改动自动重启(生产环境别用)
浏览器访问 http://127.0.0.1:8000/docs,你会看到已经生成好的 Swagger 文档。
五、核心概念实战:路径、查询、请求体
FastAPI 的优雅之处在于:参数位置决定其行为 ,不需要你手动从 request 对象里扒数据。
python
from fastapi import FastAPI, Query, Path
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
# ========== 1. 路径参数(/items/{item_id})==========
@app.get("/items/{item_id}")
async def read_item(
item_id: int = Path(..., description="商品ID", ge=1), # 自动校验:必须是整数,>=1
):
return {"item_id": item_id, "type": "路径参数"}
# ========== 2. 查询参数(?skip=0&limit=10)==========
@app.get("/items/")
async def list_items(
skip: int = Query(0, description="分页偏移"),
limit: int = Query(10, le=100, description="每页数量,最大100"),
q: Optional[str] = Query(None, min_length=2, description="搜索关键词"),
):
"""
查询参数自动从 URL 中解析:
/items/?skip=0&limit=10&q=iphone
"""
return {"skip": skip, "limit": limit, "q": q}
# ========== 3. 请求体(POST JSON)==========
class Item(BaseModel):
name: str = Field(..., min_length=1, max_length=50)
price: float = Field(..., gt=0, description="必须大于0")
is_offer: Optional[bool] = None
@app.post("/items/")
async def create_item(item: Item):
"""
FastAPI 自动完成:
1. 读取请求体 JSON
2. 校验字段类型和约束
3. 反序列化为 Item 对象
4. 校验失败自动返回 422 Unprocessable Entity
"""
return {
"item_name": item.name,
"item_price": item.price,
"with_discount": item.is_offer
}
运行测试
bash
# 启动
uvicorn main:app --reload
# 测试路径参数
curl http://localhost:8000/items/42
# 测试查询参数 + 校验(limit>100 会报错)
curl "http://localhost:8000/items/?skip=0&limit=101"
# 测试 POST 请求体(合法)
curl -X POST http://localhost:8000/items/ \
-H "Content-Type: application/json" \
-d '{"name":"iPhone 16","price":5999.0,"is_offer":true}'
# 测试 POST 请求体(非法:price 为负数)
curl -X POST http://localhost:8000/items/ \
-H "Content-Type: application/json" \
-d '{"name":"iPhone","price":-100}'
六、Pydantic:FastAPI 的"隐形翅膀"
上面代码里的 BaseModel 就是 Pydantic。它给 FastAPI 带来了声明式校验的能力:
python
from pydantic import BaseModel, EmailStr, validator
class UserCreate(BaseModel):
username: str
email: EmailStr # 自动校验邮箱格式
password: str
age: int = Field(..., ge=18, le=120)
@validator('password')
def password_strength(cls, v):
if len(v) < 8:
raise ValueError('密码至少8位')
return v
@app.post("/users/")
async def create_user(user: UserCreate):
# 走到这里,user 已经通过了所有校验
return {"msg": f"用户 {user.username} 创建成功"}
不需要写 if not isinstance(...) 这种脏代码,校验失败时 FastAPI 会自动组装标准的 422 错误响应:
json
{
"detail": [
{
"loc": ["body", "age"],
"msg": "ensure this value is less than or equal to 120",
"type": "value_error.number.not_le"
}
]
}
七、异步实战:真正的性能武器
FastAPI 的 async 不是摆设。当你需要并发调用多个外部 API 或数据库时,性能差距会拉开:
python
import asyncio
import httpx
from fastapi import FastAPI
app = FastAPI()
async def fetch_data(url: str):
async with httpx.AsyncClient() as client:
resp = await client.get(url, timeout=5.0)
return resp.json()
@app.get("/aggregate")
async def aggregate_data():
"""
并发请求两个外部接口,总耗时 ≈ max(接口A耗时, 接口B耗时)
而不是串行的 A + B
"""
urls = [
"https://api.github.com/users/octocat",
"https://api.github.com/users/torvalds"
]
# asyncio.gather 并发执行
results = await asyncio.gather(
*[fetch_data(url) for url in urls],
return_exceptions=True
)
return {"data": results}
⚠️ 注意 :如果你的代码里调用了同步阻塞库 (如
requests、pymysql),必须改用异步版本(httpx、aiomysql),否则 async 形同虚设。
八、生产环境部署
开发用 uvicorn main:app --reload,生产环境推荐 Gunicorn + Uvicorn Worker:
bash
# 安装
pip install gunicorn
# 启动:4 个 worker 进程,每个进程内是 uvloop 异步循环
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
或者直接用 Uvicorn 多进程模式:
bash
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
九、总结:FastAPI 适合什么场景?
| 场景 | 推荐指数 | 原因 |
|---|---|---|
| 微服务 API 网关 | ⭐⭐⭐⭐⭐ | 异步高并发,天然适合 I/O 密集 |
| 机器学习模型服务 | ⭐⭐⭐⭐⭐ | 快速暴露模型接口,自动校验输入特征 |
| 后台管理 + 复杂业务 | ⭐⭐⭐ | 无内置 ORM/Admin,需配合 SQLAlchemy |
| 纯静态网站/SSR | ⭐⭐ | 用 Next.js/Nuxt 更合适 |
学习路径建议
sql
Day 1: 安装 → Hello World → 路径/查询/请求体参数
Day 2: Pydantic 模型 → 嵌套模型 → 响应模型控制
Day 3: 依赖注入(Depends) → 数据库连接池 → 异步 ORM(SQLAlchemy 2.0)
Day 4: 认证(OAuth2/JWT) → 中间件 → CORS
Day 5: 后台任务 → WebSocket → 部署(Gunicorn + Docker)