news 2026/8/4 6:03:37

⚡ FastAPI 暴击入门:三行代码,让你的接口快到起飞

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
⚡ FastAPI 暴击入门:三行代码,让你的接口快到起飞

⚡ FastAPI 暴击入门:三行代码,让你的接口快到起飞

别被"后端框架"四个字吓到——FastAPI 可能是你写过最爽的接口框架。这篇不是官方文档的搬运,而是把知识库里啃过的干货,按"先跑起来再讲原理"的顺序重新炖了一遍。每一段代码都能直接复制运行,版本也对得上。我会盯着,别慌。


📑 目录

  1. FastAPI 到底是什么
  2. 三步跑起第一个接口
  3. 自动文档:/docs 与 /redoc
  4. 路由与参数:路径/查询/请求体
  5. Pydantic 模型与响应过滤
  6. APIRouter:把路由拆干净
  7. 依赖注入 Depends
  8. 异步编程:快在哪
  9. 数据库 & ORM 入门
  10. 自检清单

1. FastAPI 到底是什么

一句话:FastAPI 是一个用 Python 写接口的"快"框架——开发快、运行快、写起来还不容易出错。它站在两个巨人肩膀上:

  • Starlette:提供 ASGI 异步底层和 Web 能力(路由、请求、WebSocket 等)。
  • Pydantic v2:负责数据校验与序列化,性能好、类型提示友好。

它凭什么"快到飞起"?三个核心卖点:

能力说明对你意味着什么
极快的性能基于 ASGI,性能对标 Node / Go 同档高并发接口不虚
自动类型校验用 Python 类型提示自动校验入参少写一堆 if 判断
自动交互文档开箱即用 Swagger UI + ReDoc不用手写接口文档
异步原生async def一等公民I/O 密集场景爽歪歪
编辑器友好类型提示带来自动补全少查文档,效率拉满

💡先记住一个概念:ASGI
WSGI 是老一代(同步)Python Web 接口,ASGI 是新一代(支持异步)接口。FastAPI 是 ASGI 应用,所以要搭配支持 ASGI 的服务器(uvicornhypercorn)来跑,不能直接用老式python main.py启动


2. 三步跑起第一个接口

第 1 步:装包。官方推荐装[standard]额外组,它顺带把uvicorn(服务器)、python-multipart(表单)、pydantic-settings等常用依赖一并带上。

# 建议先建虚拟环境(venv / conda 都行),再装pipinstall"fastapi[standard]"# 装完后确认版本pip show fastapi|findstr"Version"# Windows# 本文基准:fastapi 0.141.x,pydantic 2.x

第 2 步:写应用。新建main.py,三行核心代码就能跑:

fromfastapiimportFastAPI app=FastAPI()# ① 创建应用实例@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 与 /redoc

FastAPI 自动生成两套交互式文档,不用写一行文档代码

地址样式用途
/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):# 声明 int,FastAPI 自动转类型+校验return{"item_id":item_id}

请求GET /items/42{"item_id": 42}。若你传/items/abc,FastAPI 直接返回422 校验错误,根本不会进函数——这就是类型提示的威力。

② 查询参数(Query Parameter)

URL 里?后面那一串,不是路径参数、且给了默认值的就是查询参数。

@app.get("/items/{item_id}")defread_item(item_id:int,q:str|None=None):return{"item_id":item_id,"q":q}# GET /items/42?q=hello → {"item_id":42,"q":"hello"}# GET /items/42 → {"item_id":42,"q":null}

③ 请求体(Request Body)

POST 这类"要提交数据"的接口,数据放请求体里,用Pydantic 模型接收(下一节细讲)。

frompydanticimportBaseModelclassItem(BaseModel):name:strprice:floatis_offer:bool=False# 带默认值,可省略@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:str@app.post("/users/",response_model=UserOut)defcreate_user(u:UserIn):# 假设存库后拿到 id=1return{"id":1,"name":u.name,"password":u.password}# ↑ 响应里 password 会被 response_model 自动剥掉!# 实际返回:{"id":1,"name":"xushuai"}

🚫安全红线
永远不要让"含密码/令牌/盐"的模型直接作为返回结构。用response_model指定一个精简过的输出模型,是后端防止敏感字段泄露的最低成本防线。这也是面试常问的"如何避免返回用户密码"的标准答法之一。

从数据库对象转 Pydantic,v2 用model_config = ConfigDict(from_attributes=True)(v1 的orm_mode=True已废弃):

frompydanticimportBaseModel,ConfigDictclassProductOut(BaseModel):model_config=ConfigDict(from_attributes=True)# 允许从 ORM 对象读属性id:intname:strprice:float

6. APIRouter:把路由拆干净

接口一多,全塞进main.py会爆炸。用APIRouter把同类接口拆成独立文件,最后在main.py收口。

# routers/items.pyfromfastapiimportAPIRouter router=APIRouter(prefix="/items",tags=["items"])# 前缀+分组标签@router.get("/")deflist_items():return[{"id":1,"name":"键盘"}]
# main.pyfromfastapiimportFastAPIfromrouters.itemsimportrouterasitems_router app=FastAPI()app.include_router(items_router)# 挂载后路由变为 /items/# 访问 GET /items/ 即生效,/docs 里也会归入 "items" 分组

7. 依赖注入 Depends

"依赖注入"听着玄学,其实就是把一段公共逻辑(比如解析分页、校验登录)抽出来,让 FastAPI 在调接口前自动帮你执行并传进来。好处:复用、解耦、好测试。

场景 A:公共分页参数

fromtypingimportAnnotatedfromfastapiimportDependsdefget_pagination(skip:int=0,limit:int=10):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 security=HTTPBearer()defget_current_user(token:Annotated[HTTPAuthorizationCredentials,Depends(security)]):iftoken.credentials!="secret-token":raiseHTTPException(status_code=status.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():a=call_api_a()# 等 1sb=call_api_b()# 再等 1sreturn{"a":a,"b":b}# 总共约 2 秒
# ✅ 异步:并发等待@app.get("/par")asyncdefpar():a,b=awaitasyncio.gather(call_api_a(),call_api_b())return{"a":a,"b":b}# 总共约 1 秒
importasynciofromtypingimportAnnotatedfromfastapiimportFastAPI app=FastAPI()asyncdeffetch_a():awaitasyncio.sleep(1)# 模拟 I/O 等待return"A"asyncdeffetch_b():awaitasyncio.sleep(1)return"B"@app.get("/parallel")asyncdefparallel():a,b=awaitasyncio.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 风格:用DeclarativeBase+Mapped+mapped_column

fromsqlalchemy.ormimportDeclarativeBase,Mapped,mapped_columnclassBase(DeclarativeBase):pass# 所有模型继承它classProduct(Base):__tablename__="products"id:Mapped[int]=mapped_column(primary_key=True)name:Mapped[str]=mapped_column()price:Mapped[float]=mapped_column()

把数据库会话(Session)通过yield依赖注入给接口,用完自动关:

fromsqlalchemyimportcreate_enginefromsqlalchemy.ormimportsessionmakerfrom.modelsimportBase engine=create_engine("sqlite:///./app.db")# 先用 sqlite 尝鲜SessionLocal=sessionmaker(bind=engine)defget_db():db=SessionLocal()try:yielddb# 把会话交给接口用finally:db.close()# 用完必关,防连接泄漏

🧠深挖:同步 vs 异步数据库
上面是同步SQLAlchemy(create_engine+Session),简单直观,适合入门。一旦要扛高并发,应换异步版(create_async_engine+AsyncSession),配合async def接口才能真正发挥异步优势。这部分我们放在 SQLAlchemy 博客里细拆。


自检清单(点开看答案)

Q1:FastAPI 为什么要搭配 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时,abcint失败 → 返回422

Q3:`response_model` 除了"好看",还有什么实际作用?

它是输出字段白名单:只返回声明在输出模型里的字段,自动把多余字段(如密码、内部字段)剥掉。这是防止敏感信息泄露的低成本的防线,也是从 ORM 对象转 API 输出时的标准做法。

Q4:`Depends` 解决了什么重复劳动?

把"每个接口都要做"的公共逻辑(分页解析、登录校验、拿数据库会话等)抽成一个函数,FastAPI 在调接口前自动执行并注入结果。避免在每个路由里复制粘贴同一段代码,也方便统一改逻辑、统一测试。

Q5:异步 `async def` 一定比同步 `def` 快吗?什么时候不该用?

不一定。只在I/O 密集型(等网络/数据库/磁盘)时异步才体现优势——等待期间能把线程让给别的请求。遇到CPU 密集型重计算,异步不会更快,还阻塞事件循环,应改用后台任务/线程池/独立进程。


📚 资料来源 & 版本核查

  • 本篇内容整理自 Obsidian 知识库03 - 参考资料/FASTAPI/第 01–07 章及06 - Wiki/FastAPI/卡片。
  • 版本基准(已联网核对,2026-08-03):FastAPI 0.141.x(最新稳定线 0.141.1)、Pydantic v2SQLAlchemy 2.0.x
  • 关键准确性说明:Pydantic v2 用ConfigDict(from_attributes=True),v1 的orm_mode=True已废弃;SQLAlchemy 2.0 用DeclarativeBase,旧的declarative_base()已不推荐。代码均按 2.x 写法给出,可直接运行。

徐帅 · 代码突击课 · FastAPI 暴击入门 · 基于 Obsidian 知识库整理

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/4 6:03:29

LAS点云数据解析实战:从二进制文件到三维应用的数据处理全流程

1. 项目概述&#xff1a;从LAS文件到三维世界的钥匙如果你手头有一堆后缀为.las或.laz的文件&#xff0c;看着它们动辄几个G的大小却无从下手&#xff0c;或者你听说过“点云”这个酷炫的词&#xff0c;想知道它到底怎么从一堆二进制数据变成屏幕上那些绚烂的三维模型&#xff…

作者头像 李华
网站建设 2026/8/4 6:02:50

Simulink动态系统建模:从微分方程到波特图的完整实现指南

1. 项目概述&#xff1a;从微分方程到频率响应&#xff0c;一次搞懂Simulink核心建模今天咱们来聊聊Simulink学习路上一个关键的里程碑&#xff1a;如何用微分模块和传递函数模块搭建动态系统模型&#xff0c;并最终通过波特图来分析它的频率特性。这听起来有点学术&#xff0c…

作者头像 李华
网站建设 2026/8/4 5:58:43

伽马函数:从反常积分到概率统计核心工具

1. 从“反常”到“核心”&#xff1a;伽马函数的魅力与定位在数学分析&#xff0c;特别是处理积分问题时&#xff0c;我们经常会遇到一些“反常”的积分——它们的积分区间是无穷的&#xff0c;或者被积函数在积分区间内有瑕点。处理这类积分&#xff0c;常常需要一些巧妙的技巧…

作者头像 李华
网站建设 2026/8/4 5:58:13

自然艺术装置创作:枯叶动态捕捉与材料处理技术

1. 项目背景与创作动机"冬风苍叶舞"这个标题让我想起去年冬天在北方山区的一次徒步经历。当时正值深冬&#xff0c;山间的老榆树早已褪尽绿叶&#xff0c;只剩下枯黄的叶片在凛冽的北风中盘旋起舞。这种自然景象给了我强烈的视觉冲击和创作冲动——我想用某种艺术形式…

作者头像 李华
网站建设 2026/8/4 5:57:48

嵌入式学习笔记--liunx基础命令(unbantu)

一、终端操作与使用权限1.打开终端有三种方式&#xff1a;右键选择“打开终端”&#xff1b;从应用程序面板启动&#xff1b;快捷键 Ctrl Alt T2.调整终端字号&#xff1a;放大 Ctrl Shift &#xff0c;缩小 Ctrl - 3.关闭终端&#xff1a;输入exit或按altf44…

作者头像 李华
网站建设 2026/8/4 5:56:54

终极Boot Camp驱动自动化:5分钟搞定Mac Windows驱动安装

终极Boot Camp驱动自动化&#xff1a;5分钟搞定Mac Windows驱动安装 【免费下载链接】brigadier Fetch and install Boot Camp ESDs with ease. 项目地址: https://gitcode.com/gh_mirrors/bri/brigadier 还在为Mac安装Windows系统后找不到驱动而烦恼吗&#xff1f;想象…

作者头像 李华