【问题标题】:FastAPI passing json in get request via TestClientFastAPI通过TestClient在get请求中传递json
【发布时间】:2020-08-06 12:57:01
【问题描述】:

我正在尝试测试我用 Fastapi 编写的 api。我的路由器中有以下方法:

@app.get('/webrecord/check_if_object_exist')
async def check_if_object_exist(payload: WebRecord) -> bool:
    key = get_key_of_obj(payload.data) if payload.key is None else payload.key
    return await check_if_key_exist(key)

以及我的测试文件中的以下测试:

client = TestClient(app)
class ServiceTest(unittest.TestCase):
.....
    def test_check_if_object_is_exist(self):
        webrecord_json = {'a':1}
        response = client.get("/webrecord/check_if_object_exist", json=webrecord_json)
        assert response.status_code == 200
        assert response.json(), "webrecord should already be in db, expected : True, got : {}".format(response.json())

当我在调试中运行代码时,我意识到 get 方法中的断点没有到达。当我更改发布请求的类型时,一切正常。

我做错了什么?

【问题讨论】:

  • 可能您正在将一些数据发布到需要 GET 请求的 URL。 Fastapi 使用 starlette,它使用请求。我在 get 请求中看不到任何 json 参数。您是否检查过请求的 url 是否正确? requests.readthedocs.io/en/master/user/quickstart/…
  • 你可以看到请求类型是get,我正在使用客户端的get函数。请求网址确实正确。如何在正文中传递 json 以获取请求?
  • 这就是我的观点。为了在获取请求中传递数据,您应该在 url 中对其进行编码,因此我询问了 url。我会在测试和服务器代码中将您的请求类型更改为 POST(因此服务器接受该 url 的 POST 请求)
  • 正如我在帖子中提到的那样,我后来所做的一切都奏效了。我还检查了 put 方法,它也基于 request.put。有一个发送 json 的选项,只需要传递标头,但它仍然不起作用,请查看这篇文章 - stackoverflow.com/questions/38752091/…
  • 这就是我的观点。为了传递数据,您必须使用 POST,或者作为替代,PUT。但是 GET 不能用于传递数据,除非您在 url 中显式编码数据,但如果您有大量数据或者您希望它采用特定格式(例如 JSON),则不建议这样做。要么更改数据的表示形式,要么永远无法使用 GET 通过正文传递数据

标签: python fastapi


【解决方案1】:

为了通过 GET 请求向服务器发送数据,您必须在 url 中对其进行编码,因为 GET 没有任何正文。如果您需要特定格式(例如 JSON),则不建议这样做,因为您必须解析 url、解码参数并将它们转换为 JSON。

或者,您可以向您的服务器发布搜索请求。 POST 请求允许使用不同格式(包括 JSON)的正文。

如果你还想要 GET 请求

    @app.get('/webrecord/check_if_object_exist/{key}')
async def check_if_object_exist(key: str, data: str) -> bool:
    key = get_key_of_obj(payload.data) if payload.key is None else payload.key
    return await check_if_key_exist(key)


client = TestClient(app)
class ServiceTest(unittest.TestCase):
.....
    def test_check_if_object_is_exist(self):
        response = client.get("/webrecord/check_if_object_exist/key", params={"data": "my_data")
        assert response.status_code == 200
        assert response.json(), "webrecord should already be in db, expected : True, got : {}".format(response.json())

这将允许从 url mydomain.com/webrecord/check_if_object_exist/{对象的键}获取请求。

最后一点:我将所有参数都设为强制性。您可以通过默认声明为None 来更改它们。见fastapi Docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2019-04-05
    • 2023-01-08
    相关资源
    最近更新 更多