18.FastAPI错误处理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18.FastAPI错误处理相关的知识,希望对你有一定的参考价值。
参考技术A 当我们需要在FastAPI中返回错误时,可以使用HTTPException返回错误信息。HTTPException是包含了与API相关数据的Python异常,所以在程序需要raise,而不是return。 HTTPException的参数包括:代码示例:
执行请求:
上面的请求是一个返回正确结果的请求。下面执行一个返回错误的请求:
在FastAPI中,可以根据用户的需求进行自定义异常的封装和处理,对于自定义异常首先需要定义一个继承自Exception的自定义异常类,然后使用 @app.exception_handler() 添加自定义异常控制器。这样就可以在路由方法中raise相应的异常进行响应。
代码示例:
执行请求:
从以上示例可以看出,当请求http://127.0.0.1:8000/language/c时,由于找不到c语言的说明,所以触发LangException异常,该异常将被lang_exception_handle方法处理。
Python:带有发布请求的 FastAPI 错误 422
【中文标题】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())
【讨论】:
以上是关于18.FastAPI错误处理的主要内容,如果未能解决你的问题,请参考以下文章
python错误处理之try...except...finally...错误处理机制。