You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI中返回值的上下文管理器依赖可否设置为全局使用?

结论

FastAPI中通过app.include_router的dependencies参数、或者全局app.dependencies配置的依赖,返回值会被默认丢弃,无法直接被路径操作函数获取。但可以通过两种变通方案实现类似全局依赖的效果,避免每个路径操作重复写完整依赖声明。

方案1:将客户端实例存入request.state

修改依赖函数,把生成的AsyncClient挂载到请求对象的state属性上,全局依赖正常注册后,路径操作直接从request中读取实例即可。同时依赖可以自动从请求头解析token,无需手动传参。

修改后的依赖代码:

from fastapi import Request, Header
import httpx

async def get_client(request: Request, authorization: str = Header(alias="Authorization")):
    # 从请求头提取Bearer token
    token = authorization.removeprefix("Bearer ")
    client = httpx.AsyncClient(headers={"Authorization": f"Bearer {token}"})
    
    try:
        # 将客户端实例挂载到请求对象的state属性
        request.state.client = client
        yield client
    finally:
        # 响应返回后自动关闭客户端
        await client.aclose()

路由注册代码(注意dependencies参数接收的是依赖列表):

app.include_router(
    router,
    prefix="/api",
    dependencies=[Depends(get_client)]
)

路径操作代码,无需再单独声明依赖:

@router.get("/", status_code=status.HTTP_200_OK)
async def get_something(request: Request):
    # 直接从state中读取复用的客户端实例,httpx异步方法需要加await
    resp = await request.state.client.get('https://www.google.com')

方案2:用Annotated类型别名简化依赖声明

如果不想操作request对象,也可以通过类型别名减少冗余代码,虽然仍需要在路径操作参数中声明,但代码量极低,同时保留完整的类型提示:

from typing import Annotated
import httpx
from fastapi import Depends

# 定义依赖的类型别名,仅需声明一次
Client = Annotated[httpx.AsyncClient, Depends(get_client)]

# 路径操作直接使用别名即可
@router.get("/", status_code=status.HTTP_200_OK)
async def get_something(client: Client):
    resp = await client.get('https://www.google.com')

内容的提问来源于stack exchange,提问作者anjuna47

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:36:04