FastAPI 单参数主体导致 Pydantic 验证错误

Pra*_* T. 5 python http-post httprequest pydantic fastapi

我有一个 POST FastAPI 方法。我不想构造类或查询字符串。所以,我决定应用Body()方法。

@app.post("/test-single-int")
async def test_single_int(
    t: int = Body(...)
):
    pass
Run Code Online (Sandbox Code Playgroud)

这是请求

POST http://localhost:8000/test-single-int/

{
  "t": 10
}
Run Code Online (Sandbox Code Playgroud)

这是回应

HTTP/1.1 422 Unprocessable Entity
date: Fri, 22 May 2020 10:00:16 GMT
server: uvicorn
content-length: 83
content-type: application/json
connection: close

{
  "detail": [
    {
      "loc": [
        "body",
        "s"
      ],
      "msg": "str type expected",
      "type": "type_error.str"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

但是,在尝试了许多样本后,我发现如果我有多个Body(). 例如,

POST http://localhost:8000/test-single-int/

{
  "t": 10
}
Run Code Online (Sandbox Code Playgroud)

要求

POST http://localhost:8000/test-multi-mix/

{
  "s": "test",
  "t": 10
}
Run Code Online (Sandbox Code Playgroud)

回复

HTTP/1.1 200 OK
date: Fri, 22 May 2020 10:16:12 GMT
server: uvicorn
content-length: 4
content-type: application/json
connection: close

null
Run Code Online (Sandbox Code Playgroud)

有没有人对我的实现有任何想法?有错吗?这不是最佳实践吗?或者这是一个错误?

fun*_*man 8

这不是错误,而是 Body 的行为方式,它存在用于“扩展”请求参数文档如何概述

class Item(BaseModel):
    name: str

class User(BaseModel):
    username: str
    full_name: str = None


@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int,
    item: Item,
    user: User,
    importance: int = Body(..., gt=0),
    q: str = None
):
    pass
Run Code Online (Sandbox Code Playgroud)

此视图的有效请求正文为:

{
    "item": {
        "name": "Foo",
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}
Run Code Online (Sandbox Code Playgroud)

如果你真的想单独使用 Body ,你必须指定embed=True,这个按预期工作:

@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id:int,
    importance: int = Body(..., gt=0, embed=True),
    q: str = None
):
    pass
Run Code Online (Sandbox Code Playgroud)