26

我正在构建一个简单的 API 来测试数据库。当我使用 get request 时,一切正常,但是如果我更改为 post,我会收到“无法处理的实体”错误:

这是 FastAPI 代码:

from fastapi import FastAPI

app = FastAPI()

@app.post("/")
def main(user):
    return user

然后,我的请求使用 javascript

let axios = require('axios')

data = { 
    user: 'smith' 
}

axios.post('http://localhost:8000', data)
    .then(response => (console.log(response.url)))

也使用 Python

import requests

url = 'http://127.0.0.1:8000'
data = {'user': 'Smith'}

response = requests.post(url, json=data)
print(response.text)

我也尝试解析为 json,使用 utf-8 编码,并更改标题。没有什么对我有用。

4

7 回答 7

24

直接来自文档

函数参数将被识别如下:

  • 如果参数也在path中声明,它将被用作路径参数。
  • 如果参数是单数类型(如 int、float、str、bool 等),它将被解释为查询参数。
  • 如果参数被声明为Pydantic 模型的类型,它将被解释为请求。”

因此,要创建一个接收带有用户字段的正文的 POST 端点,您可以执行以下操作:

from fastapi import FastAPI
from pydantic import BaseModel


app = FastAPI()


class Data(BaseModel):
    user: str


@app.post("/")
def main(data: Data):
    return data
于 2020-01-28T10:58:53.093 回答
18

在我的情况下,我从不同的 python 项目中调用 python API,就像这样

queryResponse = requests.post(URL, data= query)

我正在使用数据属性,我将其更改为 json,然后它对我有用

queryResponse = requests.post(URL, json = query)
于 2021-07-15T08:16:02.830 回答
3

对于获取请求体的 POST 请求,您需要执行以下操作

创建 Pydantic 基本模型用户

from pydantic import BaseModel

class User(BaseModel):
    user_name: str


@app.post("/")
def main(user: User):
   return user
于 2020-06-16T12:28:57.870 回答
2

FastAPI 基于Python 类型提示,因此当您传递查询参数时,它接受key : value对,您需要以某种方式声明它。

即使是这样的事情也会奏效

from typing import Dict, Any
...
@app.post("/")
def main(user: Dict[Any, Any] = None):
    return user

Out: {"user":"Smith"}

但是使用 Pydantic 方式更有效

class User(BaseModel):
    user: str

@app.post("/")
def main(user: User):
    return user

Out: {"user":"Smith"}
于 2020-07-26T10:16:53.787 回答
1

如果您正在使用fetchAPI 并且仍然收到422 Unprocessable Entity,请确保您已设置Content-Type标头:

fetch(someURL, {
  method: "POST",
  headers: {
    "Content-type": "application/json"
  },
  body
}).then(...)

这解决了我的问题。在服务器端,我使用的是 Pydantic 模型,所以如果您不使用这些模型,请参阅上面的答案。

于 2022-01-16T07:36:23.493 回答
0

此处发布的答案是正确的。当涉及到 JSON 发布请求时,应该使用 Pydantic 模型(关于表单数据,请看这里)。但是,如果不想使用 Pydantic 模型,他们也可以使用Body parameters。如果使用单个 body 参数(如您的示例中),您可以使用特殊的Body参数embed。下面是一个工作示例。

应用程序.py

import uvicorn
from fastapi import Body, FastAPI

app = FastAPI()

@app.post("/")
async def main(user: str = Body(..., embed=True)):
    return {"user": user}
    
if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000, debug=True)

测试.py

import requests

url = 'http://127.0.0.1:8000'
payload ={"user": "foo"}
resp = requests.post(url=url, json=payload)
print(resp.json())
于 2022-01-08T20:29:08.957 回答
0

就我而言,我的 FastAPI 端点需要的是表单数据而不是 JSON。因此,解决方法是发送表单数据而不是 JSON。(注:对于node-js,FormData不可用,可以使用form-data )

于 2021-12-29T11:25:21.387 回答