为什么选 FastAPI
你写 Python API 用过哪些框架?Flask?Django?
Flask 太轻量,手写校验代码写到怀疑人生。Django 太重,搭个简单接口还要配 ORM、写模板。
FastAPI 刚刚好。
它有两个最让我上瘾的功能:
自动文档 — 你写完代码,它自动给你生成 Swagger UI。不用写一行文档,API 长什么样一眼就能看到。
类型校验 — 用 Python 类型注解声明参数,FastAPI 自动帮你校验。传错类型直接 422,不用自己写 if 判断。
我上周用 FastAPI 搭了一个内部工具,从建项目到能访问,10 分钟搞定。下面手把手教你。
第一步:装依赖
pip install fastapi uvicorn
FastAPI 是核心库,uvicorn 是 ASGI 服务器,用来跑你的应用。
第二步:写第一个接口
新建 main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello, FastAPI!"}
@app.get("/items/{item_id}")
def get_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
启动:
uvicorn main:app --reload
打开浏览器访问 http://localhost:8000,看到 {"message": "Hello, FastAPI!"}。
访问 http://localhost:8000/items/42?q=hello,看到 {"item_id": 42, "q": "hello"}。
注意:URL 路径里的 item_id 声明了 int 类型。如果你传字符串,比如 /items/abc,FastAPI 直接返回 422 错误,不会崩。
第三步:自动生成的文档
这才是 FastAPI 的杀手锏。
打开 http://localhost:8000/docs,你会看到一个交互式文档页面。
所有接口列在那里,可以在线测试。不需要写任何额外代码。
如果你打开 /redoc,会看到一个更简洁的文档页面,适合给客户看。
第四步:用 Pydantic 做请求体校验
GET 请求参数校验完了,POST 请求体呢?
FastAPI 用 Pydantic 模型来定义请求体:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
tax: float = 0.0
@app.post("/items")
def create_item(item: Item):
return {"item": item, "message": "created"}
现在 POST 到 /items,请求体必须是 JSON 格式:
{
"name": "笔记本",
"price": 4999.0,
"tax": 500.0
}
少一个字段、类型不对,FastAPI 直接拒绝,错误信息告诉你缺了什么、类型是什么。
第五步:加个简单的"数据库"
别一上来就接数据库。先用内存字典模拟,跑通了再改。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
# 内存"数据库"
fake_db = {}
class Item(BaseModel):
name: str
price: float
description: Optional[str] = None
tax: float = 0.0
@app.get("/items")
def list_items():
return list(fake_db.values())
@app.get("/items/{item_id}")
def get_item(item_id: str):
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
return fake_db[item_id]
@app.post("/items")
def create_item(item: Item):
item_id = str(len(fake_db) + 1)
item_dict = item.model_dump()
item_dict["item_id"] = item_id
fake_db[item_id] = item_dict
return item_dict
@app.delete("/items/{item_id}")
def delete_item(item_id: str):
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
del fake_db[item_id]
return {"message": "deleted"}
四个接口:增删改查,全部跑通。
第六步:接真正的数据库
内存数据库有个问题:重启就没了。
FastAPI 配合 SQLAlchemy 或 Tortoise ORM 都很方便。这里用最简单的 SQLite + SQLAlchemy:
pip install sqlalchemy aiosqlite
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy import create_engine, Column, Integer, String, Float
from sqlalchemy.orm import sessionmaker, declarative_base
from pydantic import BaseModel
from typing import Optional
DATABASE_URL = "sqlite:///./items.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class ItemModel(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
price = Column(Float)
description = Column(String, nullable=True)
tax = Column(Float, default=0.0)
Base.metadata.create_all(bind=engine)
class ItemCreate(BaseModel):
name: str
price: float
description: Optional[str] = None
tax: float = 0.0
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/items")
def list_items(db=Depends(get_db)):
return db.query(ItemModel).all()
@app.post("/items")
def create_item(item: ItemCreate, db=Depends(get_db)):
db_item = ItemModel(**item.model_dump())
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
启动后,数据会持久化到 items.db 文件里。
几个实用技巧
1. 状态码不用手动设
@app.get("/items/{item_id}")
def get_item(item_id: int):
# 找不到直接 return None,FastAPI 不会帮你抛 404
# 需要手动抛
if not found:
raise HTTPException(status_code=404)
2. 请求头、Cookie、Query 参数都能拿
from fastapi import Header, Cookie
@app.get("/items")
def list_items(
user_agent: str = Header(default=""),
session_id: str = Cookie(default="")
):
return {"user_agent": user_agent, "session_id": session_id}
3. 路由分组,组织大项目
from fastapi import APIRouter
items_router = APIRouter(prefix="/items", tags=["商品"])
users_router = APIRouter(prefix="/users", tags=["用户"])
# 在 main.py 里注册
app.include_router(items_router)
app.include_router(users_router)
生产环境怎么跑
开发用 uvicorn main:app --reload 就够了。生产环境去掉 --reload:
uvicorn main:app --host 0.0.0.0 --port 8000
用 systemd 或者 Docker 托管起来。
总结一下
FastAPI 上手成本很低。你会 Python 基本语法,就能写出能跑的 API。
最值钱的是它的类型系统和自动文档——写完代码,文档就有了,不用再单独维护。
你现在就可以复制上面的代码,10 分钟搭一个属于自己的 API。
下一步想学什么?数据库操作?认证授权?还是部署上线?评论区告诉我。