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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:27:39