尧图精选

FastAPI 全局依赖(Global Dependencies):用 `FastAPI(dependencies=[...])` 为整个应用统一注入校验逻辑

🕒 发布时间:2026/9/8 20:38:24 📁 来源:尧图网络
FastAPI 全局依赖Global Dependencies用FastAPI(dependencies[...])为整个应用统一注入校验逻辑【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi全局依赖是 FastAPI 依赖注入体系在“应用Application级”的应用方式与在单个路径操作装饰器上声明dependencies类似你可以在创建FastAPI()实例时传入一个依赖列表使这些依赖被应用到该应用内的每一个路径操作上。本文以 docs/fr/docs/tutorial/dependencies/global-dependencies.md 为核心结合仓库内的可运行示例docs_src/dependencies/tutorial012_an_py310.py、单元测试tests/test_tutorial/test_dependencies/test_tutorial012.py以及 fastapi/applications.py 源码带你掌握如何编写应用级依赖、它与路径装饰器依赖的异同、内部是如何传递到每条路由的以及如何用include_router(..., dependencies...)为“一组路径”统一声明依赖。为什么要用全局依赖对于某些类型的应用你希望某些检查或逻辑无条件作用于所有接口而不是逐个手写。典型场景包括全站统一的简单鉴权或网关校验如校验每个请求都携带的X-Token、X-Key头全站统一的访问审计、限流计数、租户上下文解析全站统一的入口级异常拦截或资源初始化。你当然可以把这些依赖逐条写进每一个app.get(...)的dependencies[...]里但那样既重复又容易漏写。FastAPI 允许把同样的依赖列表直接交给FastAPI应用本身——正如你可以在路径操作装饰器上添加dependencies你也可以把它们添加到FastAPI应用上。基本用法把依赖挂到FastAPI()构造器当依赖被加到应用级别后它们会作用于应用里的所有路径操作。仓库中完整的可运行示例位于 docs_src/dependencies/tutorial012_an_py310.py使用Annotated的推荐写法from typing import Annotated from fastapi import Depends, FastAPI, Header, HTTPException async def verify_token(x_token: Annotated[str, Header()]): if x_token ! fake-super-secret-token: raise HTTPException(status_code400, detailX-Token header invalid) async def verify_key(x_key: Annotated[str, Header()]): if x_key ! fake-super-secret-key: raise HTTPException(status_code400, detailX-Key header invalid) return x_key app FastAPI(dependencies[Depends(verify_token), Depends(verify_key)]) app.get(/items/) async def read_items(): return [{item: Portal Gun}, {item: Plumbus}] app.get(/users/) async def read_users(): return [{username: Rick}, {username: Morty}]关键的一行是app FastAPI(dependencies[Depends(verify_token), Depends(verify_key)])FastAPI()构造器接受一个可选的dependencies参数它是一个由Depends()组成的列表。这里的两个依赖都没有被任何端点函数作为参数使用但每次请求进入/items/或/users/时它们都会被自动解析并执行。仓库同时提供了不使用Annotated的等价版本 docs_src/dependencies/tutorial012_py310.py仅将参数写法换成默认值形式async def verify_token(x_token: str Header()): ...两种写法行为一致Annotated版本是当前 FastAPI 文档推荐的主流风格。逐行解读两个校验依赖verify_token声明了一个必填的请求头参数x_tokenHeader()不带默认值即为必填。如果它不等于预设的fake-super-secret-token就抛出HTTPException(status_code400, detailX-Token header invalid)。verify_key同样声明必填请求头x_key并校验值校验通过后return x_key。注意这个返回值并不会被传给任何端点函数因为全局依赖没有对应的函数参数它只是“顺便返回”而已完全不影响逻辑。说明示例中使用的是虚构的X-Key/X-Token自定义头。在真实项目中实现安全校验时更推荐使用内置的 安全相关工具这里的写法只是为了演示“依赖会在每个路径上被执行”这一机制。与路径操作装饰器dependencies的异同在深入全局依赖前先回顾一下它在路径操作装饰器上的兄弟用法app.get(/items/, dependencies[Depends(verify_token), Depends(verify_key)]) async def read_items(): return [{item: Foo}, {item: Bar}]对照仓库示例 docs_src/dependencies/tutorial006_an_py310.py 可以看出两者的核心机制完全一致只是作用范围不同声明位置写法生效范围路径操作装饰器app.get(/items/, dependencies[...])仅该路径操作FastAPI 应用实例FastAPI(dependencies[...])应用中全部路径操作APIRouter / include_routerinclude_router(router, dependencies[...])该路由分组下的路径操作无论声明在哪一层这些依赖都会与普通依赖一样被解析resolve与执行不把返回值注入端点函数的参数因此可以放心复用那些“会返回值”的普通依赖即使返回值用不上依赖也照常执行支持声明自身的请求约束如必填头参数也能继续嵌套依赖其他子依赖可以raise异常如HTTPException来中断请求。在应用级声明还有一个附带好处端点函数签名保持干净不会出现“看起来没用”的未使用参数避免编辑器静态检查告警和初学者的困惑——这一点同样来自路径操作装饰器依赖文档中的 Tip 说明。用测试用例验证全局依赖的行为仓库的测试 tests/test_tutorial/test_dependencies/test_tutorial012.py 同时针对tutorial012_py310与tutorial012_an_py310两个模块运行用TestClient逐一验证了全局依赖的各种行为。下面这些断言就是文档所述机制的直接证据缺少请求头 → 422 校验错误且两个端点表现一致def test_get_no_headers_items(client: TestClient): response client.get(/items/) assert response.status_code 422, response.text assert response.json() { detail: [ {type: missing, loc: [header, x-token], msg: Field required, input: None}, {type: missing, loc: [header, x-key], msg: Field required, input: None}, ] }对应文件中的test_get_no_headers_users断言/users/返回完全相同的 422验证了“全局依赖作用于所有路径操作”。请求头值错误 → 400detail 指出是哪一个头非法response client.get(/items/, headers{X-Token: invalid}) assert response.status_code 400 assert response.json() {detail: X-Token header invalid}两个头都正确 → 200 并正常返回业务数据response client.get( /items/, headers{ X-Token: fake-super-secret-token, X-Key: fake-super-secret-key, }, ) assert response.status_code 200 assert response.json() [{item: Portal Gun}, {item: Plumbus}]此外测试里的test_openapi_schema还印证了一个细节/items/与/users/两个路径的 OpenAPI 描述中都自动带上了x-token、x-key两个必填的header参数。也就是说应用级依赖所声明的请求约束会扩散到每一个路径操作的 API 文档与参数校验中——这是它和“中间件式”黑盒处理的一个重要区别依赖的请求参数是可声明、可校验、可文档化的。源码视角dependencies是如何传到每条路由的FastAPI 应用层的全局依赖并非魔法它的传递链在源码中清晰可见。在 fastapi/applications.py 中FastAPI.__init__的签名里就包含dependencies参数其 docstring约第 331–348 行明确写着A list of global dependencies, they will be applied to each request...一组全局依赖它们会被应用到每一个请求FastAPI 实例在内部维护了一个APIRouter即self.router构造FastAPI()时传入的dependencies会被交给这个内部路由器而通过app.get(...)、app.post(...)等注册的每个路径操作本质上都是在往这个路由器上添加路由。因此应用级的dependencies会对之后注册的、以及经由include_router挂载进来的所有路径操作统一生效。从实现角度看可以理解为 FastAPI 采用了“路由器级依赖”的聚合模型无论依赖声明在应用层还是路由分组层最终都会在路由构建阶段被合并进对应路径操作的依赖解析链中由 FastAPI 的依赖求解器统一处理包括子依赖、缓存、异常上抛等语义。这也是为什么测试中verify_token抛出的HTTPException(status_code400)能精确中断请求并返回该状态码。进阶为“一组路径操作”声明依赖全局依赖只提供“全部”与“单个路径”两个极端中间的“一组路径”粒度该怎么做原文档在结尾给出指引阅读更大的应用 - 多文件结构教程学习如何为一个路径操作分组声明单个dependencies参数。这一能力的落点有两个创建APIRouter时传dependencies使该分组内所有路由共享一组依赖在app.include_router(...)挂载时传dependencies。例如示意模式来自 applications.py 中include_router的dependencies参数说明from fastapi import APIRouter, Depends router APIRouter( prefix/admin, dependencies[Depends(verify_token)], ) router.get(/stats/) async def get_stats(): return {ok: True} app.include_router(router)这样/admin/stats/及其余所有挂在该router下的路径都会先经过verify_token。在 fastapi/applications.py 中include_router约第 1441–1521 行同样开放了dependencies参数docstring 明确说明“一组会被应用到该分组下所有路径操作的依赖”并会把它转发给内部的router.include_router(...)见 applications.py 中调用处。于是你可以把依赖按作用域组织成清晰的层次应用级全站强制逻辑→路由分组级模块化子应用的公共逻辑配合 更大的应用教程 的多文件结构→路径装饰器级单接口特有逻辑→函数参数级需要消费返回值时。实践建议与使用边界结合示例代码、测试与源码使用全局依赖时有几点值得留意适合放全局依赖的对整站所有接口无条件生效的入口校验、统一约定检查。这类逻辑通常“只需要被执行不需要消费返回值”正好契合dependencies列表的语义。不要混淆依赖与中间件全局依赖仍然拥有完整的参数声明/校验能力会把其参数并入每个路径的 OpenAPI 文档测试的test_openapi_schema已证明而Middleware是更底层的 WSGI/ASGI 层面的处理。需要“可声明、可校验、可文档化”的请求约束时优先考虑依赖。依赖也可以有自己的依赖全局依赖函数内同样可以继续声明请求参数或嵌套Depends完整复用依赖注入体系的所有能力。返回值为空或不被使用都没关系如verify_token不返回值verify_key返回了值但无处接收——两者都会在每个请求到来时按声明顺序被解析执行。真实安全场景示例的硬编码 Token 头仅用于教学做生产级认证时应改用 OAuth2、API Key 等内置安全方案见安全教程避免在代码中写死密钥比对。如果想在本地亲手跑一遍效果可以基于仓库的测试模块启动验证把 docs_src/dependencies/tutorial012_an_py310.py 中定义的app交给fastapi.testclient.TestClient与 tests/test_tutorial/test_dependencies/test_tutorial012.py 的做法一致分别用“无头请求、错误 Token、正确 Token、缺 Key、全部正确”等组合打向/items/和/users/即可观察 422、400、200 三种结果——这正是“一份依赖全站生效”最直观的验证方式。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →