为什么选 FastAPI
Python Web 框架里,Flask 简单但太原始,Django 功能全但太重。FastAPI 是新一代的选择:
- 快:性能接近 Node.js 和 Go(基于 Starlette + Pydantic)
- 自动文档:写完代码自动生成交互式 API 文档,前端看了直呼内行
- 类型安全:用 Python 类型注解做参数校验,类型错了直接返回 422
- 异步原生:天生支持 async/await,IO 密集场景性能碾压
pip install fastapi uvicorn
第一个接口:5 行代码
# main.py
from fastapi import FastAPI
app = FastAPI(title="我的第一个API")
@app.get("/")
def hello():
return {"message": "Hello FastAPI"}
@app.get("/items/{item_id}")
def get_item(item_id: int): # 声明 int 类型,自动转换和校验
return {"item_id": item_id, "name": f"商品{item_id}"}
启动:
uvicorn main:app --reload --port 8000
--reload:改代码自动重启,开发必备main:app:指 main.py 文件里的 app 对象
现在访问:
http://127.0.0.1:8000/items/42→ 返回 JSONhttp://127.0.0.1:8000/items/abc→ 自动返回 422 错误(因为 abc 不是 int)http://127.0.0.1:8000/docs→ 自动生成的 Swagger 文档页面,可以直接在页面上测试接口
参数校验:Pydantic 的威力
POST 请求的数据校验,用 Pydantic 模型声明:
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class ItemCreate(BaseModel):
name: str = Field(min_length=1, max_length=50, description="商品名")
price: float = Field(gt=0, description="价格必须大于0")
stock: int = Field(default=0, ge=0)
tags: list[str] = []
@app.post("/items")
def create_item(item: ItemCreate):
return {"message": "创建成功", "data": item}
发请求时:
- 字段缺失/类型错误/不满足约束 → 自动返回详细的 422 错误信息
- 一切正常 →
item是一个类型安全的对象,IDE 有完整提示
再也不用手写 if not name: return error 这类校验代码。
查询参数与路径参数
from typing import Optional
@app.get("/items")
def list_items(
keyword: Optional[str] = None, # 可选查询参数 ?keyword=xxx
page: int = 1, # 带默认值
size: int = Field(default=20, le=100), # 限制最大100
):
return {"keyword": keyword, "page": page, "size": size}
一个完整的小项目:待办事项 API
把前面的知识串起来,写一个带增删改查的完整 API:
# todo.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
app = FastAPI(title="待办事项API")
# 用列表模拟数据库(下节换成真实数据库)
todos = []
next_id = 1
class TodoCreate(BaseModel):
title: str = Field(min_length=1, max_length=100)
done: bool = False
class Todo(TodoCreate):
id: int
@app.get("/todos", response_model=list[Todo])
def list_todos():
"""获取所有待办"""
return todos
@app.post("/todos", response_model=Todo, status_code=201)
def create_todo(item: TodoCreate):
"""创建待办"""
global next_id
todo = Todo(id=next_id, **item.model_dump())
next_id += 1
todos.append(todo)
return todo
@app.get("/todos/{todo_id}", response_model=Todo)
def get_todo(todo_id: int):
"""获取单个待办"""
for t in todos:
if t.id == todo_id:
return t
raise HTTPException(status_code=404, detail="待办不存在")
@app.put("/todos/{todo_id}", response_model=Todo)
def update_todo(todo_id: int, item: TodoCreate):
"""更新待办"""
for i, t in enumerate(todos):
if t.id == todo_id:
todos[i] = Todo(id=todo_id, **item.model_dump())
return todos[i]
raise HTTPException(status_code=404, detail="待办不存在")
@app.delete("/todos/{todo_id}", status_code=204)
def delete_todo(todo_id: int):
"""删除待办"""
for i, t in enumerate(todos):
if t.id == todo_id:
todos.pop(i)
return
raise HTTPException(status_code=404, detail="待办不存在")
response_model 的好处:自动过滤返回值(比如不暴露内部字段)、生成准确的文档、做响应校验。
连接真实数据库(以 SQLite + SQLAlchemy 为例)
pip install sqlalchemy
# database.py
from sqlalchemy import Column, Integer, String, Boolean, create_engine
from sqlalchemy.orm import declarative_base, sessionmaker
engine = create_engine("sqlite:///./todos.db", connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(bind=engine)
Base = declarative_base()
class TodoModel(Base):
__tablename__ = "todos"
id = Column(Integer, primary_key=True, index=True)
title = Column(String(100), nullable=False)
done = Column(Boolean, default=False)
Base.metadata.create_all(engine) # 自动建表
在 FastAPI 中用依赖注入管理数据库会话:
from fastapi import Depends
from sqlalchemy.orm import Session
def get_db():
"""每个请求一个会话,结束自动关闭"""
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/todos")
def list_todos(db: Session = Depends(get_db)):
return db.query(TodoModel).all()
@app.post("/todos", status_code=201)
def create_todo(item: TodoCreate, db: Session = Depends(get_db)):
todo = TodoModel(**item.model_dump())
db.add(todo)
db.commit()
db.refresh(todo)
return todo
生产部署
开发用 --reload,生产环境这样跑:
# 4 个 worker 进程,绑定所有网卡
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
更稳的方案是 gunicorn 管理 uvicorn worker(Linux):
pip install gunicorn
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
前面再挂 Nginx 反向代理,搞定域名和 HTTPS,就是标准的生产架构。
进阶方向
到这里你已经能写可用的 API 了。下一步按需学习:
- 用户认证:
fastapi-users或手写 JWT(python-jose) - 跨域 CORS:前端联调必配
CORSMiddleware - 后台任务:
BackgroundTasks处理发邮件这类慢操作 - 限流:
slowapi防止接口被刷 - 测试:
fastapi.testclient基于 httpx,写接口测试很顺手
写在最后
FastAPI 的设计哲学是「别让我重复写样板代码」。类型注解即校验、代码即文档——把这两个特性用足,你的接口开发效率会提升一个量级。建议把待办事项的例子亲手跑通,再把它改造成一个你自己真正需要的小工具。







评论 (0)
还没有评论,快来抢沙发吧~