⚡ FastAPI 暴击入门三行代码让你的接口快到起飞别被后端框架四个字吓到——FastAPI 可能是你写过最爽的接口框架。这篇不是官方文档的搬运而是把知识库里啃过的干货按先跑起来再讲原理的顺序重新炖了一遍。每一段代码都能直接复制运行版本也对得上。我会盯着别慌。 目录FastAPI 到底是什么三步跑起第一个接口自动文档/docs 与 /redoc路由与参数路径/查询/请求体Pydantic 模型与响应过滤APIRouter把路由拆干净依赖注入 Depends异步编程快在哪数据库 ORM 入门自检清单1. FastAPI 到底是什么一句话FastAPI 是一个用 Python 写接口的快框架——开发快、运行快、写起来还不容易出错。它站在两个巨人肩膀上Starlette提供 ASGI 异步底层和 Web 能力路由、请求、WebSocket 等。Pydantic v2负责数据校验与序列化性能好、类型提示友好。它凭什么快到飞起三个核心卖点能力说明对你意味着什么极快的性能基于 ASGI性能对标 Node / Go 同档高并发接口不虚自动类型校验用 Python 类型提示自动校验入参少写一堆 if 判断自动交互文档开箱即用 Swagger UI ReDoc不用手写接口文档异步原生async def一等公民I/O 密集场景爽歪歪编辑器友好类型提示带来自动补全少查文档效率拉满先记住一个概念ASGIWSGI 是老一代同步Python Web 接口ASGI 是新一代支持异步接口。FastAPI 是 ASGI 应用所以要搭配支持 ASGI 的服务器uvicorn或hypercorn来跑不能直接用老式python main.py启动。2. 三步跑起第一个接口第 1 步装包。官方推荐装[standard]额外组它顺带把uvicorn服务器、python-multipart表单、pydantic-settings等常用依赖一并带上。# 建议先建虚拟环境venv / conda 都行再装pipinstallfastapi[standard]# 装完后确认版本pip show fastapi|findstrVersion# Windows# 本文基准fastapi 0.141.xpydantic 2.x第 2 步写应用。新建main.py三行核心代码就能跑fromfastapiimportFastAPI appFastAPI()# ① 创建应用实例app.get(/)# ② 绑定 GET 路由defread_root():return{msg:Hello, FastAPI!}# ③ 返回字典自动转 JSON第 3 步启动服务器。用uvicorn启动main:app表示main.py 里的 app 变量--reload让改代码后自动重启仅开发用。uvicorn main:app--reload# 看到类似输出就成功了# Uvicorn running on http://127.0.0.1:8000# 打开浏览器访问 http://127.0.0.1:8000 → {msg:Hello, FastAPI!}⚠️端口被占用若提示端口被占用换一个即可uvicorn main:app --reload --port 8080。浏览器访问http://127.0.0.1:8080。注意uvicorn默认只监听本机 127.0.0.1想让同局域网其他人访问需要加--host 0.0.0.0生产环境请配合反向代理勿直接暴露。3. 自动文档/docs 与 /redocFastAPI 自动生成两套交互式文档不用写一行文档代码地址样式用途/docsSwagger UI可在线点按钮发请求、调试接口最常用/redocReDoc排版更顺眼、适合阅读整份 API 说明启动后直接浏览器打开 http://127.0.0.1:8000/docs 。每个接口的参数、返回结构都自动列好还能直接Try it out填参发送。这是 FastAPI 最爽的点之一——文档即代码永远不会和实现对不上。深挖文档从哪来FastAPI 在启动时扫描你写的路由、参数类型、Pydantic 模型自动生成一份OpenAPI 规范JSON挂在/openapi.json。Swagger 和 ReDoc 只是把这份 JSON 渲染成不同界面。所以你的类型提示写得越准文档越准。4. 路由与参数路径/查询/请求体一个接口通常要接收三类输入FastAPI 用不同写法区分且自动帮你做类型转换和校验。① 路径参数Path Parameter写在{}里是 URL 路径的一部分常用于查某个具体资源。app.get(/items/{item_id})defread_item(item_id:int):# 声明 intFastAPI 自动转类型校验return{item_id:item_id}请求GET /items/42→{item_id: 42}。若你传/items/abcFastAPI 直接返回422 校验错误根本不会进函数——这就是类型提示的威力。② 查询参数Query ParameterURL 里?后面那一串不是路径参数、且给了默认值的就是查询参数。app.get(/items/{item_id})defread_item(item_id:int,q:str|NoneNone):return{item_id:item_id,q:q}# GET /items/42?qhello → {item_id:42,q:hello}# GET /items/42 → {item_id:42,q:null}③ 请求体Request BodyPOST 这类要提交数据的接口数据放请求体里用Pydantic 模型接收下一节细讲。frompydanticimportBaseModelclassItem(BaseModel):name:strprice:floatis_offer:boolFalse# 带默认值可省略app.post(/items/)defcreate_item(item:Item):# 自动解析 JSON 体 → Item 对象return{name:item.name,price:item.price}记忆口诀参数来源怎么判断路径里有{}的是路径参数函数参数里没出现在路径、且带默认值的是查询参数用 Pydantic 模型声明的是请求体。拿不准时去/docs看一眼——界面上写得一清二楚。5. Pydantic 模型与响应过滤Pydantic 是 FastAPI 的数据守门员进来帮你校验出去帮你序列化。最容易被忽略、却最有用的是response_model——它能在返回时只挑允许的字段输出天然防信息泄露。frompydanticimportBaseModelclassUserIn(BaseModel):# 入参允许接收密码name:strpassword:strclassUserOut(BaseModel):# 出参刻意不含 passwordid:intname:strapp.post(/users/,response_modelUserOut)defcreate_user(u:UserIn):# 假设存库后拿到 id1return{id:1,name:u.name,password:u.password}# ↑ 响应里 password 会被 response_model 自动剥掉# 实际返回{id:1,name:xushuai}安全红线永远不要让含密码/令牌/盐的模型直接作为返回结构。用response_model指定一个精简过的输出模型是后端防止敏感字段泄露的最低成本防线。这也是面试常问的如何避免返回用户密码的标准答法之一。从数据库对象转 Pydanticv2 用model_config ConfigDict(from_attributesTrue)v1 的orm_modeTrue已废弃frompydanticimportBaseModel,ConfigDictclassProductOut(BaseModel):model_configConfigDict(from_attributesTrue)# 允许从 ORM 对象读属性id:intname:strprice:float6. APIRouter把路由拆干净接口一多全塞进main.py会爆炸。用APIRouter把同类接口拆成独立文件最后在main.py收口。# routers/items.pyfromfastapiimportAPIRouter routerAPIRouter(prefix/items,tags[items])# 前缀分组标签router.get(/)deflist_items():return[{id:1,name:键盘}]# main.pyfromfastapiimportFastAPIfromrouters.itemsimportrouterasitems_router appFastAPI()app.include_router(items_router)# 挂载后路由变为 /items/# 访问 GET /items/ 即生效/docs 里也会归入 items 分组7. 依赖注入 Depends依赖注入听着玄学其实就是把一段公共逻辑比如解析分页、校验登录抽出来让 FastAPI 在调接口前自动帮你执行并传进来。好处复用、解耦、好测试。场景 A公共分页参数fromtypingimportAnnotatedfromfastapiimportDependsdefget_pagination(skip:int0,limit:int10):return{skip:skip,limit:limit}app.get(/items/)deflist_items(p:Annotated[dict,Depends(get_pagination)]):return{分页:p,data:[]}场景 B登录态校验实战高频用HTTPBearer自动从请求头取Authorization: Bearer token校验失败直接抛 401。fromfastapiimportDepends,HTTPException,statusfromfastapi.securityimportHTTPBearer,HTTPAuthorizationCredentials securityHTTPBearer()defget_current_user(token:Annotated[HTTPAuthorizationCredentials,Depends(security)]):iftoken.credentials!secret-token:raiseHTTPException(status_codestatus.HTTP_401_UNAUTHORIZED,detail无效令牌,)return{user:xushuai}app.get(/me)defme(user:Annotated[dict,Depends(get_current_user)]):returnuser# 没抛异常才进得来为什么用Annotated[..., Depends(...)]这是 FastAPI 推荐的现代写法类型提示 依赖信息放一起IDE 补全更准。老写法user: dict Depends(get_current_user)也能跑但在复杂场景前者更清晰、更不容易写错。8. 异步编程快在哪FastAPI 支持async def定义异步接口。重点不是异步一定更快而是它能在等待 I/O网络、数据库、文件时把线程让出来处理别的请求。# ❌ 同步串行等待app.get(/seq)defseq():acall_api_a()# 等 1sbcall_api_b()# 再等 1sreturn{a:a,b:b}# 总共约 2 秒# ✅ 异步并发等待app.get(/par)asyncdefpar():a,bawaitasyncio.gather(call_api_a(),call_api_b())return{a:a,b:b}# 总共约 1 秒importasynciofromtypingimportAnnotatedfromfastapiimportFastAPI appFastAPI()asyncdeffetch_a():awaitasyncio.sleep(1)# 模拟 I/O 等待returnAasyncdeffetch_b():awaitasyncio.sleep(1)returnBapp.get(/parallel)asyncdefparallel():a,bawaitasyncio.gather(fetch_a(),fetch_b())return{a:a,b:b}⚠️异步的边界异步只对I/O 密集型等网络/数据库/磁盘有效。若是CPU 密集型算大数、图像处理async不会变快反而可能阻塞事件循环。正确做法CPU 重活丢给后台任务、线程池run_in_threadpool或独立进程/Worker。9. 数据库 ORM 入门真实接口大多要连数据库。FastAPI 官方推荐用SQLAlchemy作 ORM。下一篇博客会深挖 SQLAlchemy这里先放一个能跑的最小骨架让你对接口怎么读到库里的数据有个整体概念。现代 SQLAlchemy 2.0 风格用DeclarativeBaseMappedmapped_column。fromsqlalchemy.ormimportDeclarativeBase,Mapped,mapped_columnclassBase(DeclarativeBase):pass# 所有模型继承它classProduct(Base):__tablename__productsid:Mapped[int]mapped_column(primary_keyTrue)name:Mapped[str]mapped_column()price:Mapped[float]mapped_column()把数据库会话Session通过yield依赖注入给接口用完自动关fromsqlalchemyimportcreate_enginefromsqlalchemy.ormimportsessionmakerfrom.modelsimportBase enginecreate_engine(sqlite:///./app.db)# 先用 sqlite 尝鲜SessionLocalsessionmaker(bindengine)defget_db():dbSessionLocal()try:yielddb# 把会话交给接口用finally:db.close()# 用完必关防连接泄漏深挖同步 vs 异步数据库上面是同步SQLAlchemycreate_engineSession简单直观适合入门。一旦要扛高并发应换异步版create_async_engineAsyncSession配合async def接口才能真正发挥异步优势。这部分我们放在 SQLAlchemy 博客里细拆。自检清单点开看答案Q1FastAPI 为什么要搭配 uvicorn而不能 python main.py 直接跑因为 FastAPI 是ASGI应用不是 WSGI。它需要 ASGI 服务器uvicorn/hypercorn来驱动异步事件循环。python main.py只是定义了app对象没有启动服务器所以不会监听端口。答法要点ASGI 异步接口 需要 ASGI 服务器。Q2路径参数和查询参数在代码上怎么区分给个会 422 的例子。路径参数写在路由{xxx}里且函数签名声明类型查询参数是函数里带默认值、没出现在路径的参数。例app.get(/items/{i}) def f(i: int, q: str None)——i是路径参数、q是查询参数。请求/items/abc时abc转int失败 → 返回422。Q3response_model 除了好看还有什么实际作用它是输出字段白名单只返回声明在输出模型里的字段自动把多余字段如密码、内部字段剥掉。这是防止敏感信息泄露的低成本的防线也是从 ORM 对象转 API 输出时的标准做法。Q4Depends 解决了什么重复劳动把每个接口都要做的公共逻辑分页解析、登录校验、拿数据库会话等抽成一个函数FastAPI 在调接口前自动执行并注入结果。避免在每个路由里复制粘贴同一段代码也方便统一改逻辑、统一测试。Q5异步 async def 一定比同步 def 快吗什么时候不该用不一定。只在I/O 密集型等网络/数据库/磁盘时异步才体现优势——等待期间能把线程让给别的请求。遇到CPU 密集型重计算异步不会更快还阻塞事件循环应改用后台任务/线程池/独立进程。 资料来源 版本核查本篇内容整理自 Obsidian 知识库03 - 参考资料/FASTAPI/第 01–07 章及06 - Wiki/FastAPI/卡片。版本基准已联网核对2026-08-03FastAPI 0.141.x最新稳定线 0.141.1、Pydantic v2、SQLAlchemy 2.0.x。关键准确性说明Pydantic v2 用ConfigDict(from_attributesTrue)v1 的orm_modeTrue已废弃SQLAlchemy 2.0 用DeclarativeBase旧的declarative_base()已不推荐。代码均按 2.x 写法给出可直接运行。徐帅 · 代码突击课 · FastAPI 暴击入门 · 基于 Obsidian 知识库整理