Mypy + FastAPI response_model

Mypy + FastAPI response_model

我的任务是在我们的 FastAPI 项目中处理从 Mypy 0.770 到 0.870 的更新,这产生了一个我无法完全理解的错误。我的端点可以 return 基于某些条件的两种不同模型,这在端点装饰器中表示如下:

@router.get("/", response_model=Union[Model1, Model2])

Mypy 0.870 现在抱怨这个,说明

Argument "response_model" to "get" of "APIRouter" has incompatible type "object"; expected "Optional[Type[Any]]"

将其设置为单一类型,例如 Model1 甚至 str 可消除错误。 Any 然而, 有效吗。

现在,查看 get 方法,我看到 response_model 参数被键入为 Type[Any],我认为它一定是一个指针。

如何为我的 API 定义非简单 return 模型并让 Mypy 开心?

编辑:我试图在较小的框架中重现该问题,但没有成功。以下代码工作正常:

from typing import Any, Type, Union


def test1(var, response_model: Type[Any]):
    print(f"Accepted Type[Any], {var}")

def test2(var, response_model: Union[dict, set]):
    print(f"Accepted Union, {var}")

def main():
    test1('test1', response_model=Union[dict, set])
    test2('test2', response_model=Union[dict, set])

if __name__ == '__main__':
    main()

Type[] of something 表示未实例化此类型的 class,而此处的 Model1 表示 Model1 class 或从 Model1.

继承的任何实例

尽管如此,错误消息还是很神秘。

你在用什么python -v?在 python 世界中打字是一件新鲜事,python 版本之间也可能发生变化。如果您遇到了 mypy 版本,那么升级 python 以及它们一起使用可能会很好。

此外,您使用的 fastapi 版本是什么?我也会尝试将其更新到最新的 0.55.1。 Tiangolo 自己写道,他们在打字时遇到了错误

source

这是较新版本的 mypy 中引入的兼容性问题。 Github 上有一个关于此主题的未解决问题: https://github.com/tiangolo/fastapi/issues/2279

在讨论中,他们提供了以下解决方法:

  • 使用不同的方法创建类型别名:

    NewModel = TypeVar('NewModel',Model1,Model2)

  • 创建新的 Pydantic 模型:

    class NewModel(BaseModel):
         __root__: Union[Model1, Model2]