【问题标题】:POST call with only one numeric parameter in FastAPIFastAPI 中只有一个数字参数的 POST 调用
【发布时间】:2022-07-24 12:56:09
【问题描述】:

我有一个名为main.py 的文件,我在其中只使用一个输入参数(整数)进行了 POST 调用,其简化代码为:

from fastapi import FastAPI

app = FastAPI()

@app.post("/do_something/")
async def do_something(process_id: int):
    # some code
    return {"process_id": process_id}

现在,如果我运行测试代码,保存在文件test_main.py中,即:

from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_do_something():
    response = client.post(
        "/do_something/",
        json={
            "process_id": 16
        }
    )
    return response.json()

print(test_do_something())

我明白了

{'detail': [{'loc': ['query', 'process_id'], 'msg': 'field required', 'type': 'value_error.missing'}]}

我无法弄清楚错误是什么。它必须保持为 POST 调用。

【问题讨论】:

    标签: python fastapi


    【解决方案1】:

    错误基本上是说,缺少所需的查询参数“process_id”。原因是您发送带有请求正文(有效负载)的 POST 请求,即 JSON 数据;但是,您的端点需要一个查询参数。要接收 JSON 格式的数据,需要如下create a Pydantic BaseModel,并以与您已经做的相同的方式从客户端发送数据。

    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    class Item(BaseModel):
        process_id: int
        
    @app.post("/do_something")
    async def do_something(item: Item):
        # some code
        return item
    

    但是,如果您需要传递query parameter,那么您可以以与之前相同的方式创建端点,但在客户端中您将参数添加到 URL 本身,如下所示:

    def test_do_something():
        response = client.post("/do_something?process_id=16")
        return response.json()
    

    更新

    或者,您可以使用Body(..., embed=True) 传递单个主体参数,如下所示:

    @app.post("/do_something")
    async def do_something(process_id: int = Body(..., embed=True)):
        return process_id
    

    【讨论】:

    • 是否可以在不创建 Pydantic 模型的情况下做到这一点?通常,如果我有多个参数,我会使用,例如:async def do_something_else(items: List[Dict], process_id: int = Body(...)) 在定义中,client.post("/do_something_else/", json={"process_id": ..., "items": [{...}, {...}]}) 用于调用。
    • Body(...) 字段是可以的,当有少量参数时。 items: List[Dict] 适用于数据量很小且数据验证微不足道的场景。您甚至可以像这样获得整个请求正文:async def do_something_else(request: Request): return await request.json(),但建议使用 Pydantic 模型是有原因的(例如,您可以声明验证,以及定义任意深度嵌套的模型)。
    • 但是如果我只有一个数字参数,Body(...) 就不起作用,就像我的问题中的示例一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2021-08-09
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多