Python:带有发布请求的 FastAPI 错误 422
Posted
技术标签:
【中文标题】Python:带有发布请求的 FastAPI 错误 422【英文标题】:Python: FastAPI error 422 with post request 【发布时间】:2020-05-12 16:54:11 【问题描述】:我正在构建一个简单的 API 来测试数据库。当我使用获取请求时,一切正常,但如果我更改为发布,我会收到“无法处理的实体”错误:
这里是 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 编码,并更改标题。没有什么对我有用。
【问题讨论】:
您是否启动了运行 fastapi 应用程序的服务器(如 uvicorn)? 【参考方案1】:直接来自documentation:
函数参数将被识别如下:
如果路径中也声明了该参数,则将其用作路径参数。 如果参数是单数类型(如int、float、str、bool等),它将被解释为查询参数。 如果参数被声明为Pydantic模型的类型,它将被解释为请求body。”
因此,要创建一个接收带有用户字段的正文的 POST 端点,您可以执行以下操作:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Data(BaseModel):
user: str
@app.post("/")
def main(data: Data):
return data
【讨论】:
【参考方案2】:就我而言,我是从不同的 python 项目中调用 python API 的
queryResponse = requests.post(URL, data= query)
我使用的是 data 属性,我将其更改为 json,然后它对我有用
queryResponse = requests.post(URL, json = query)
【讨论】:
谢谢!这也让我的工作......但我仍然希望我知道为什么通过数据(如帮助文件指令)传递字典会导致 422 错误状态代码。 我读到数据字段是用于 FormData 格式的......这似乎是一个用于传递 html 表单数据的 javascript 类。 github.com/tiangolo/fastapi/issues/3373【参考方案3】:对于获取请求体的POST请求,需要如下操作
创建一个 Pydantic 基础模型用户
from pydantic import BaseModel
class User(BaseModel):
user_name: str
@app.post("/")
def main(user: User):
return user
【讨论】:
【参考方案4】: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"
【讨论】:
【参考方案5】:如果您正在使用fetch
API 并且仍然得到 422 Unprocessable Entity,请确保您已设置 Content-Type 标头:
fetch(someURL,
method: "POST",
headers:
"Content-type": "application/json"
,
body
).then(...)
这解决了我的问题。在服务器端,我使用的是 Pydantic 模型,所以如果您不使用这些模型,请参阅上面的答案。
【讨论】:
不管怎样,直到我将 fastapi 从 0.63 版本更新到 0.70 之前,我才开始遇到问题。我一直用头撞墙,直到我看到你的反应。我最初使用 jquery,其中“类型”设置为“json”。我改变了我的保存功能,使用上面设置的 Content-type 的 fetch api,问题解决了!【参考方案6】:就我而言,我的 FastAPI 端点需要的是表单数据而不是 JSON。因此,解决方法是发送表单数据而不是 JSON。 (注:对于node-js,FormData不可用,可以使用form-data)
【讨论】:
【参考方案7】:here 发布的答案是正确的。当涉及到 JSON 发布请求时,应该使用 Pydantic 模型(关于表单数据,请查看here)。但是,如果不想使用 Pydantic 模型,他们也可以使用Body parameters。如果使用单个主体参数(如您的示例),则可以使用特殊的 Body parameter embed。下面是一个工作示例。
app.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)
test.py
import requests
url = 'http://127.0.0.1:8000'
payload ="user": "foo"
resp = requests.post(url=url, json=payload)
print(resp.json())
【讨论】:
以上是关于Python:带有发布请求的 FastAPI 错误 422的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 websockets 从 FastAPI 获取实时数据流时如何修复错误(不支持的升级请求。)?
Azure 应用服务Python fastapi Function在Azure
python3.6 async/await 仍然与 fastAPI 同步工作