FastAPI 通过 TestClient 在 get 请求中传递参数

FastAPI passing params in get request via TestClient

提问人:Matheus Schaly 提问时间:11/17/2023 更新时间:11/17/2023 访问量:58

问:

我目前正在使用 FastAPI 的 TestClient,遇到了一个意想不到的行为,我想澄清一下。

工作示例:

from fastapi.testclient import TestClient
from fastapi import status

def my_func(client: TestClient) -> None:
   response = client.get(
       app.url_path_for("v1-my-endpoint"),
       params={"xx": "11", "yy": "22"}
   )
   assert response.status_code == status.HTTP_200_OK

非工作示例:

from fastapi.testclient import TestClient
from fastapi import status

def my_func(client: TestClient) -> None:
   my_params={"xx": "11", "yy": "22"}
   response = client.get(
       app.url_path_for("v1-my-endpoint"),
       params=my_params
   )
   assert response.status_code == status.HTTP_200_OK

第二个示例,我在变量 (my_params) 中定义参数,引发以下错误:

error: Argument "params" to "get" of "TestClient" has incompatible type "Dict[str, object]"; expected "Union[QueryParams, Mapping[str, Union[Union[str, int, float, bool, None], Sequence[Union[str, int, float, bool, None]]]], List[Tuple[str, Union[str, int, float, bool, None]]], Tuple[Tuple[str, Union[str, int, float, bool, None]], ...], str, bytes, None]"  [arg-type]

我很好奇直接提供参数和传递包含参数的变量之间的行为差异。为什么第一个示例有效,而第二个示例会引发错误?在 FastAPI 中使用 TestClient 时,推荐的参数传递方式是什么?

python pytest fastapi

评论

0赞 Yurii Motov 11/17/2023
我刚刚检查了一下,这两个例子都有效。我没有收到此错误。

答:

0赞 thesonyman101 11/17/2023 #1

在我使用 FastAPI 的经验中,我遇到过类似的情况。在第二个示例中,使用 FastAPI 的 TestClient 时遇到的错误与类型提示以及 Python 的类型检查器(如 mypy)如何解释 params 参数的类型有关。

在工作示例中,您直接将字典传递给 params 参数。在这里,Python 的类型推断正确地理解字典的键和值是字符串,因此它与 params 参数的预期类型匹配。

但是,在非工作示例中,当您将 my_params 定义为变量,然后将其传递给 params 时,类型检查器无法推断字典中键和值的确切类型。它默认为 Dict[str, object],这是一个比 TestClient.get() 预期的更广泛的类型。params 的预期类型更具体,不仅允许字符串,还允许整数、浮点数、布尔值和这些类型的序列。

若要解决此问题,可以为 my_params 字典提供显式类型提示,以确保它与预期类型匹配。以下是修改非工作示例的方法:

from typing import Dict, Union
from fastapi.testclient import TestClient
from fastapi import status

def my_func(client: TestClient) -> None:
    my_params: Dict[str, Union[str, int, float, bool, None]] = {"xx": "11", "yy": "22"}
    response = client.get(
        app.url_path_for("v1-my-endpoint"),
        params=my_params
    )
    assert response.status_code == status.HTTP_200_OK

通过为 my_params 提供显式类型提示,可以通知类型检查器字典中每个键和值的特定类型。这应该可以防止类型错误,并使第二个示例的工作方式与第一个示例类似。

评论

1赞 NotTheDr01ds 11/19/2023
欢迎回到 Stack Overflow!请注意,不允许使用 AI 工具(例如 ChatGPT)来生成或改写您在 Stack Overflow 上发布的内容,即使您事先审查了这些内容。另请参阅有关此主题的相关帮助。我们希望您能坚持下去,并继续成为社区的重要成员,在未来贡献您自己的优质答案和问题!