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错误处理的主要内容,如果未能解决你的问题,请参考以下文章

17)错误处理

Lua 错误处理

PHP:自定义错误处理程序 - 处理解析和致命错误

python错误处理之try...except...finally...错误处理机制。

python错误处理之try...except...finally...错误处理机制。

MySql错误处理-错误处理的例子