ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FastAPI 实战教程(上):核心机制、项目配置与完整请求链路

FastAPI 实战教程(上):核心机制、项目配置与完整请求链路 内容依据 FastAPI 0.142.2 与官方文档整理采集日期2026-10-03。系列导航上篇核心机制、项目配置与完整请求链路本文下篇数据库、JWT、测试部署与热门项目架构拆解全系列目录上篇先把 FastAPI 的运行机制讲清楚FastAPI、Starlette、Pydantic 与 Uvicorn 的关系Python 环境、依赖安装、启动命令与接口文档路由注册与 Path、Query、Header、Body 参数Pydantic 输入校验、响应模型与数据边界依赖注入、依赖缓存和yield资源清理async def、普通def与阻塞调用异常处理、统一错误结构与 APIRouter 拆分下篇把 Demo 扩展成生产项目配置管理、数据库 Session、Repository 与事务JWT 登录、密码安全、中间件与后台任务Lifespan、自动化测试、Docker 与生产部署Open WebUI、Langflow、Full Stack FastAPI Template 源码架构拆解从三个项目提炼可复用的生产级目录结构摘要FastAPI 的“快”不只指运行性能也来自类型提示驱动的开发方式。本文从一次 HTTP 请求的完整链路出发讲清路由、参数提取、Pydantic 校验、响应模型、依赖注入、异常处理与 async/await并给出可直接运行的最小项目。一、FastAPI 到底是什么FastAPI 是一个使用现代 Python 类型提示构建 API 的 Web 框架。它的核心并不是某个神奇装饰器而是把三个成熟组件组合在了一起Starlette提供 ASGI、路由、中间件、WebSocket 等 Web 能力Pydantic负责数据解析、类型转换、校验与 SchemaUvicorn作为 ASGI Server 接收和转发网络请求。开发者写下一个函数签名FastAPI 会同时从中获得参数来源、类型约束、运行时校验规则和 OpenAPI 文档。这就是它“声明一次获得多种能力”的关键。一次请求大致经过客户端 → Uvicorn/ASGI → 中间件 → 路由匹配 → 依赖解析 → Pydantic 校验 → 路径函数 → 响应模型 → JSON二、安装与第一个接口Python 版本建议使用 3.10 或更高。推荐在虚拟环境中安装标准依赖python-m venv.venv.venv\Scripts\Activate.ps1 python-m pip install--upgrade pip pip installfastapi[standard]使用 uv 时uv init fastapi-democdfastapi-demo uvaddfastapi[standard]新建main.pyfromfastapiimportFastAPI appFastAPI(titleFastAPI Demo,version1.0.0)app.get(/)asyncdefroot():return{message:Hello FastAPI}开发模式启动fastapi dev main.py启动后可以访问接口http://127.0.0.1:8000/Swagger UIhttp://127.0.0.1:8000/docsReDochttp://127.0.0.1:8000/redocOpenAPI JSONhttp://127.0.0.1:8000/openapi.jsonfastapi dev会启用热重载适合本地开发生产环境应使用fastapi run或显式配置 Uvicorn不要开启 reload。【截图占位】补充 Swagger UI 首页和/接口调用结果。三、路由URL 和函数如何关联fromfastapiimportFastAPI,status appFastAPI()app.get(/users/{user_id},tags[users])asyncdefget_user(user_id:int):return{id:user_id}app.post(/users,status_codestatus.HTTP_201_CREATED,tags[users],)asyncdefcreate_user():return{created:True}app.get()、app.post()被称为路径操作装饰器。它们登记了HTTP 方法URL 模板状态码标签与文档元数据最终要执行的 Python 函数。静态路由应放在动态路由之前app.get(/users/me)asyncdefread_current_user():return{id:me}app.get(/users/{user_id})asyncdefread_user(user_id:str):return{id:user_id}否则/users/me可能先匹配到{user_id}。四、FastAPI 如何判断参数来自哪里FastAPI 会结合路径模板、类型和显式标记判断数据来源。fromtypingimportAnnotatedfromfastapiimportBody,Header,QueryfrompydanticimportBaseModel,FieldclassItemCreate(BaseModel):name:strField(min_length2,max_length50)price:floatField(gt0)description:str|NoneNoneapp.post(/shops/{shop_id}/items)asyncdefcreate_item(shop_id:int,item:ItemCreate,limit:Annotated[int,Query(ge1,le100)]20,user_agent:Annotated[str|None,Header()]None,source:Annotated[str,Body(embedTrue)]web,):return{shop_id:shop_id,item:item,limit:limit,user_agent:user_agent,source:source,}这里的来源分别是参数来源判断依据shop_idPath出现在/shops/{shop_id}中limitQuery普通标量且使用Queryuser_agentHeader显式使用HeaderitemJSON BodyPydantic 模型sourceJSON Body显式使用Body如果客户端把shop_id传成无法转换的字符串或者价格小于等于 0请求会在进入函数之前返回 422。业务代码因此不用重复写大量类型判断。五、Pydantic 模型输入校验不等于数据库模型frompydanticimportBaseModel,ConfigDict,EmailStr,FieldclassUserCreate(BaseModel):email:EmailStr password:strField(min_length8,max_length128)nickname:strField(min_length2,max_length30)classUserPublic(BaseModel):model_configConfigDict(from_attributesTrue)id:intemail:EmailStr nickname:str不要用同一个模型同时承担创建参数、数据库实体和公开响应。上面的拆分可以避免把密码字段意外返回给客户端。response_model不只是文档声明它还会校验并过滤响应app.post(/users,response_modelUserPublic,status_code201)asyncdefcreate_user(payload:UserCreate):saved{id:1,email:payload.email,nickname:payload.nickname,password:payload.password,}returnsaved尽管saved中含有password最终响应只会保留UserPublic声明的字段。这是一道非常实用的输出边界。六、依赖注入FastAPI 最值得掌握的能力依赖注入的作用是让路径函数声明“我需要什么”由框架负责创建、复用和清理。fromtypingimportAnnotatedfromfastapiimportDepends,Header,HTTPExceptionasyncdefget_token(authorization:Annotated[str|None,Header()]None,)-str:ifauthorization!Bearer demo-token:raiseHTTPException(status_code401,detailInvalid token)returnauthorization.removeprefix(Bearer )TokenAnnotated[str,Depends(get_token)]app.get(/profile)asyncdefprofile(token:Token):return{token:token}执行/profile时FastAPI 会先解析get_token需要的 Header再执行它最后把返回值注入token。依赖还可以继续依赖其他依赖asyncdefget_current_user(token:Token):return{id:1,token:token}CurrentUserAnnotated[dict,Depends(get_current_user)]app.get(/orders)asyncdeflist_orders(user:CurrentUser):return{user_id:user[id],items:[]}FastAPI 会构建一棵依赖图并在单次请求中缓存默认依赖结果。数据库会话、当前用户、权限检查和配置对象都适合用依赖表达。需要资源清理时使用yieldasyncdefget_resource():resourceawaitopen_resource()try:yieldresourcefinally:awaitresource.close()yield之前相当于进入资源之后相当于退出清理。七、async def 和 def 应该怎么选关键不是“异步一定更快”而是被调用的 I/O 库是否支持await。app.get(/async-resource)asyncdefasync_resource():dataawaitasync_http_client.get(https://example.com)returndata.json()如果第三方库是异步的使用async def并await。如果使用传统阻塞库可以写普通defapp.get(/sync-report)defsync_report():returnblocking_report_library.build()FastAPI 会在线程池中执行普通def路径函数避免直接阻塞事件循环。最危险的写法是在async def中直接调用耗时的阻塞函数app.get(/bad)asyncdefbad():time.sleep(5)# 阻塞事件循环return{ok:True}CPU 密集型计算也不会因为async自动变快。图片处理、模型推理或大规模计算应放进进程池、任务队列或独立服务。八、异常处理与统一错误结构fromfastapiimportHTTPExceptionapp.get(/items/{item_id})asyncdefread_item(item_id:int):ifitem_id!1:raiseHTTPException(status_code404,detail{code:ITEM_NOT_FOUND,message:Item not found},)return{id:item_id}大型项目中可以定义领域异常并集中转换fromfastapiimportRequestfromfastapi.responsesimportJSONResponseclassDomainError(Exception):def__init__(self,code:str,message:str):self.codecode self.messagemessageapp.exception_handler(DomainError)asyncdefhandle_domain_error(request:Request,exc:DomainError):returnJSONResponse(status_code400,content{code:exc.code,message:exc.message},)业务层只抛领域异常HTTP 状态码和响应结构由 Web 层统一决定避免每个路由重复拼装错误。九、拆分成可维护的项目当接口超过十几个后不要继续把所有代码堆在main.pyapp/ ├── main.py ├── api/ │ ├── deps.py │ └── routes/ │ ├── users.py │ └── items.py ├── schemas/ │ ├── user.py │ └── item.py ├── services/ └── core/ └── config.py路由文件fromfastapiimportAPIRouter routerAPIRouter(prefix/items,tags[items])router.get()asyncdeflist_items():return[]主应用只负责装配fromfastapiimportFastAPIfromapp.api.routesimportitems appFastAPI()app.include_router(items.router,prefix/api/v1)APIRouter 不是为了“目录好看”而是把路由前缀、标签、依赖和领域边界组合成可独立理解的模块。十、本期小结掌握 FastAPI 的关键不是记住装饰器而是理解一次请求如何依次完成Uvicorn 把网络请求转换成 ASGI 事件Starlette 中间件和路由找到路径函数FastAPI 解析依赖图和参数来源Pydantic 完成转换与校验路径函数执行业务逻辑响应模型过滤输出并生成 JSON同一份类型信息生成 OpenAPI 文档。掌握上面的请求链路后就可以进入真实工程数据库会话、事务、JWT、配置、中间件、测试、后台任务、部署以及热门开源项目的架构选择。继续阅读FastAPI 实战教程下数据库、JWT、测试部署与热门项目架构拆解参考资料FastAPI 官方教程https://fastapi.tiangolo.com/tutorial/Request Bodyhttps://fastapi.tiangolo.com/tutorial/body/Dependencieshttps://fastapi.tiangolo.com/tutorial/dependencies/Asynchttps://fastapi.tiangolo.com/async/Bigger Applicationshttps://fastapi.tiangolo.com/tutorial/bigger-applications/PyPIhttps://pypi.org/project/fastapi/
返回列表