当前位置: 首页 > 知识库问答 >
问题:

向最终用户显示FastAPI验证错误

秦永望
2023-03-14

我正在寻找一些库或代码示例,将 FastAPI 验证消息格式化为人类可读的格式。例如,此endpoint:

@app.get("/")
async def hello(name: str):
    return {"hello": name}

如果我们缺少<code>name</code>查询参数,将生成下一个json输出:

{ 
    "detail":[ 
        { 
            "loc":[ 
                "query",
                "name"
            ],
            "msg":"field required",
            "type":"value_error.missing"
        }
    ]
}

所以我的问题是,如何:

  1. 将其转换为“名称字段是必需的”(对于各种可能的错误)以在 Toast 中显示。
  2. 使用它来显示表单验证消息
  3. 如果可能,从 api 描述自己生成表单

共有3个答案

鄂琛
2023-03-14

我想我能想出的最好的办法实际上是PlainText响应

添加这些:

from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return PlainTextResponse(str(exc), status_code=400)

您会收到一条更人性化的错误消息,如以下纯文本:

1 validation error
path -> item_id
  value is not a valid integer (type=type_error.integer)

这在FastAPI文档中有很好的记录。

章心水
2023-03-14

我带着一个类似的问题来到这里——我最终处理了请求验证错误以返回一个响应,其中每个字段都是该字段问题的数组。对您的请求的响应将变成(status_code=400)

    {
        "detail": "Invalid request",
        "errors": {"name": ["field required"]}
    }

在前端管理snackbar通知非常方便,而且足够灵活。

这是处理者


from collections import defaultdict

from fastapi import status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse


@app.exception_handler(RequestValidationError)
async def custom_form_validation_error(request, exc):
    reformatted_message = defaultdict(list)
    for pydantic_error in exc.errors():
        loc, msg = pydantic_error["loc"], pydantic_error["msg"]
        filtered_loc = loc[1:] if loc[0] in ("body", "query", "path") else loc
        field_string = ".".join(filtered_loc)  # nested fields with dot-notation
        reformatted_message[field_string].append(msg)

    return JSONResponse(
        status_code=status.HTTP_400_BAD_REQUEST,
        content=jsonable_encoder(
            {"detail": "Invalid request", "errors": reformatted_message}
        ),
    )

幸阳波
2023-03-14

FastAPI 具有出色的异常处理功能,因此您可以通过多种方式自定义异常。

您可以引发HTTPException,HTTPException是一个普通的Python异常,带有与API相关的附加数据。但是你不能返回它,你需要提高它,因为它是一个Python异常

from fastapi import HTTPException
...
@app.get("/")
async def hello(name: str):
    if not name:
        raise HTTPException(status_code=404, detail="Name field is required")
    return {"Hello": name}

通过添加< code>name: str作为查询参数,它自动变成必需的,因此您需要添加< code>Optional

from typing import Optional
...
@app.get("/")
async def hello(name: Optional[str] = None):
    error = {"Error": "Name field is required"}
    if name:
        return {"Hello": name}
    return error

$ curl 127.0.0.1:8000/?name=imbolc
{"Hello":"imbolc"}
...
$ curl 127.0.0.1:8000
{"Error":"Name field is required"}

但是在你的情况下,我认为这是处理FastAPI中覆盖validation_exception_handler错误的最佳方法:

from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
...
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder({"detail": exc.errors(), "Error": "Name field is missing"}),
    )
...
@app.get("/")
async def hello(name: str):
    return {"hello": name}

你会得到这样的回应:

$ curl 127.0.0.1:8000

 {
   "detail":[
      {
         "loc":[
            "query",
            "name"
         ],
         "msg":"field required",
         "type":"value_error.missing"
      }
   ],
   "Error":"Name field is missing"
}

但是,如果您愿意,您可以自定义您的< code >内容:

{
"Error":"Name field is missing",
   "Customize":{
      "This":"content",
      "Also you can":"make it simpler"
   }
}
 类似资料:
  • 在使用Spring MVC验证器执行了“浅层”用户输入验证后,是否有一些好的做法可以使用Spring MVC来显示服务层验证错误?例如,使用以下代码: 虽然将此代码作为示例看起来微不足道,但当服务层的验证是一项复杂的任务时,对我来说,这似乎是一个微妙的故事。尽管这是一个荒谬的场景,UserService可能会创建一个用户列表,如果其中一个已经存在,那么必须以某种方式通知视图层其中哪些是无效的(例如

  • 使用在WebSphere 8.5.5中运行的PrimeFaces 5.3 我有一个带有两个必填字段的表单,一个和一个。我在菜单中选择一个有效值(例如无状态),但将文本字段留空,导致错误。然后我更正文本字段,但用户也按下菜单上的“S”键——打算再次选择“无状态”,但结果是“选择国家”,这意味着没有选择任何内容——另一个验证错误。 当用户按下ENTER时,他们会收到另一条的错误消息,该字段本身被突出显

  • @将有效的打印信息发送到控制台,但不发送到页面 当我的字段有错误@Valid print info到控制台时,为什么不在第页? 字段hotelName上的对象formData中的字段错误:拒绝的值[];代码[Size.formData.hotelName, Size.hotelName, Size.java.lang.String, size];参数[org.springframework.con

  • 我的应用程序中嵌入了swagger ui。当我在本地运行我的节点应用程序时,UI工作得很好。 但是,当我将UI部署到我的“real”服务器时,我会在我的招摇过市UI的右下角看到一个错误图像: 我确信这是我正在做的事情,这会把事情搞砸,但我不知道。当我通过http访问swagger ui时,它也可以在本地工作。 然而,当我部署时,我通过apache运行并通过https提供服务,我看到一个错误。更糟糕

  • 我已经浏览了很多帖子和文章,但没有找到一个简单的解决方案,下面我必须实现。 平台:Spring Boot 2。x、 嵌入Tomcat的x(Spring Security 5.x.x) 解决方案:使用许多客户端应用程序和许多最终用户的REST服务。 > 因此,我必须使用一次性令牌对上述应用程序进行身份验证。因此,我计划通过启用和来实现Spring OAuth2。对于每个应用程序客户端,我将生成一个令