如何在FastAPI中为dependencies参数中的函数传递参数?
如何在FastAPI中为dependencies参数中的函数传递参数?
嘿,这个问题我刚好碰到过,FastAPI里完全可以实现你要的效果——既给依赖函数传递自定义参数,又能让它正常读取请求头这类请求相关的数据,下面给你两种常用的方案:
方案一:用闭包(嵌套函数)实现
这是最简洁的方式,通过外层函数接收你要传递的参数,内层函数作为实际的依赖处理逻辑,同时可以访问外层函数的参数,还能正常接收FastAPI注入的请求数据。
示例代码如下:
from fastapi import Depends, Header, Annotated, FastAPI, HTTPException app = FastAPI() # 模拟解码token的函数,你可以替换成自己的逻辑 def decode_token(auth_header: str): # 这里假设Bearer token里包含color字段 token = auth_header.split(" ")[1] # 实际场景中应该用JWT库解码,这里简化返回 return {"color": token.split(".")[0]} def verify_token(allowed_color: str): # 内层函数是实际被Depends调用的依赖 async def _verify_token(Authorization: Annotated[str, Header()]): # 可以直接使用外层传入的allowed_color参数 token_payload = decode_token(Authorization) if token_payload.get("color") != allowed_color: raise HTTPException(status_code=403, detail="没有对应颜色的访问权限") # 验证通过后可以返回payload,供后续使用(如果需要的话) return token_payload # 返回内层函数 return _verify_token # 路由中使用时,直接调用外层函数并传入参数,再用Depends包裹 @app.get("/read_items/", dependencies=[Depends(verify_token("red"))]) async def read_items(): return [{"item": "Foo"}, {"item": "Bar"}]
这样写的好处是,verify_token("red")会返回_verify_token函数,这个函数既能拿到你传入的"red"参数,又能正常接收FastAPI注入的Authorization请求头,完美解决了你提到的问题。
方案二:用类作为依赖
如果你的验证逻辑比较复杂,需要维护状态或者多个方法,用类的方式会更清晰。类的__init__方法接收自定义参数,__call__方法作为依赖的执行逻辑,同样可以接收FastAPI注入的请求数据。
示例代码:
from fastapi import Depends, Header, Annotated, FastAPI, HTTPException app = FastAPI() def decode_token(auth_header: str): token = auth_header.split(" ")[1] return {"color": token.split(".")[0]} class VerifyToken: def __init__(self, allowed_color: str): # 在初始化时接收自定义参数 self.allowed_color = allowed_color # __call__方法会被Depends调用,作为实际的依赖逻辑 async def __call__(self, Authorization: Annotated[str, Header()]): token_payload = decode_token(Authorization) if token_payload.get("color") != self.allowed_color: raise HTTPException(status_code=403, detail="没有对应颜色的访问权限") return token_payload # 路由中直接实例化类并传入参数 @app.get("/read_items/", dependencies=[Depends(VerifyToken("red"))]) async def read_items(): return [{"item": "Foo"}, {"item": "Bar"}]
为什么装饰器不行?
你提到的装饰器方案确实没法实现,因为装饰器是在路由注册阶段执行的,而不是请求处理阶段,这时候还没有请求对象,自然没法读取请求头里的Token。而FastAPI的依赖是在每次请求处理时执行的,所以能正常获取请求相关的数据。
备注:内容来源于stack exchange,提问作者shearichard
相关产品推荐
相关产品推荐

