FastAPI中Lambda生成依赖时类型提示失效的解决方法问询
FastAPI授权依赖的类型提示修复方案
问题描述
我在构建FastAPI应用时,使用可调用实例依赖项实现授权逻辑——创建类实例时传入需要验证的权限列表。为简化代码,我用Lambda函数接收required_permissions参数来生成对应的依赖项,代码如下:
class AuthorizationDependency(): def __init__(self, required_permissions: list[str]): self.required_permissions # 注:此处存在笔误,未完成属性赋值 def __call__(self, user: Annotated[User, Depends(get_user)]) -> User: if user.has_permissions(required_permissions): # 注:应引用实例属性self.required_permissions return user raise Exception() Authorization = lambda required_permissions: Annotated[ User, Depends(AuthorizationDependency(required_permissions)), # 注:原代码此处缺失闭合括号 ]
使用时的代码:
@router.get( path="/my_things", ) async def get_things( user: Authorization( required_permissions=["read:things"] ), ): return user.things
代码功能正常,但user参数的类型被Pylance识别为Any,无法获得正确的类型提示。直接用变量存储Annotated类型别名时,类型推断正常,说明Lambda函数的返回类型没有被类型检查器正确识别。
解决方案
Lambda函数的类型推断能力有限,无法让Pylance正确识别返回的Annotated类型。可以将Lambda替换为带明确类型注解的普通函数,同时修复原代码中的小错误:
步骤1:修复AuthorizationDependency类的错误
首先补全类中的属性赋值和引用,同时使用更具体的异常类型:
from typing import Annotated from fastapi import Depends class AuthorizationDependency: def __init__(self, required_permissions: list[str]): self.required_permissions = required_permissions # 完成属性赋值 def __call__(self, user: Annotated[User, Depends(get_user)]) -> User: if user.has_permissions(self.required_permissions): # 引用实例属性 return user raise PermissionError("Insufficient permissions")
步骤2:替换Lambda为带类型注解的普通函数
定义一个普通函数,明确标注返回类型为Annotated[User, Depends[AuthorizationDependency]],让类型检查器能正确识别:
from typing import Annotated, TypeVar # 定义绑定到User的类型变量,确保类型推断准确 UserT = TypeVar("UserT", bound=User) def Authorization(required_permissions: list[str]) -> Annotated[UserT, Depends[AuthorizationDependency]]: return Annotated[ User, Depends(AuthorizationDependency(required_permissions)) ]
步骤3:保持原有使用方式不变
修改后,原有调用代码无需改动,Pylance将正确推断user参数的类型为User,提供正常的类型提示:
@router.get(path="/my_things") async def get_things( user: Authorization(required_permissions=["read:things"]), ): return user.things # 此处将获得User类型的自动补全和类型检查
替代方案:使用泛型类生成依赖
如果需要更灵活的类型支持(比如适配User的子类),可以将AuthorizationDependency改为泛型类,同时配合类型注解增强类型推断:
from typing import Generic, TypeVar, Annotated from fastapi import Depends T = TypeVar("T", bound=User) class AuthorizationDependency(Generic[T]): def __init__(self, required_permissions: list[str]): self.required_permissions = required_permissions def __call__(self, user: Annotated[T, Depends(get_user)]) -> T: if user.has_permissions(self.required_permissions): return user raise PermissionError("Insufficient permissions") def Authorization(required_permissions: list[str]) -> Annotated[T, Depends[AuthorizationDependency[T]]]: return Annotated[ T, Depends(AuthorizationDependency[T](required_permissions)) ]
这种方式能更好地支持继承场景,同时保持类型提示的准确性。
内容的提问来源于stack exchange,提问作者Antônio Bezerra
相关产品推荐
相关产品推荐

