向最终用户显示 FastAPI 验证错误
Displaying of FastAPI validation errors to end users
我正在寻找一些库或代码示例来将 FastAPI 验证消息格式化为人类可读的格式。例如。此端点:
@app.get("/")
async def hello(name: str):
return {"hello": name}
如果我们错过 name
查询参数,将产生下一个 json 输出:
{
"detail":[
{
"loc":[
"query",
"name"
],
"msg":"field required",
"type":"value_error.missing"
}
]
}
所以我的问题是,如何:
- 将其转换为类似 "name field is required" 的内容(针对各种可能的错误)以在 toasts 中显示。
- 用它来显示表单验证消息
- 如果可能,根据 api 描述自行生成表格
FastAPI 具有出色的异常处理功能,因此您可以通过多种方式自定义异常。
您可以引发 HTTPException,HTTPException 是一个正常的 Python 异常,带有与 API 相关的附加数据。但是你不能 return 你需要提高它,因为它是一个 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}
通过添加 name: str
作为查询参数,它会自动成为必需参数,因此您需要添加 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"
}
您可以自定义 content
,但是如果您愿意:
{
"Error":"Name field is missing",
"Customize":{
"This":"content",
"Also you can":"make it simpler"
}
}
我带着类似的问题来到这里 - 我最终处理了 RequestValidationError
以返回一个响应,其中每个字段都是该字段问题的数组。
对您请求的响应将变为(status_code=400)
{
"detail": "Invalid request",
"errors": {"name": ["field required"]}
}
在前端管理快餐栏通知非常方便,而且足够灵活。
这是处理程序
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}
),
)
我正在寻找一些库或代码示例来将 FastAPI 验证消息格式化为人类可读的格式。例如。此端点:
@app.get("/")
async def hello(name: str):
return {"hello": name}
如果我们错过 name
查询参数,将产生下一个 json 输出:
{
"detail":[
{
"loc":[
"query",
"name"
],
"msg":"field required",
"type":"value_error.missing"
}
]
}
所以我的问题是,如何:
- 将其转换为类似 "name field is required" 的内容(针对各种可能的错误)以在 toasts 中显示。
- 用它来显示表单验证消息
- 如果可能,根据 api 描述自行生成表格
FastAPI 具有出色的异常处理功能,因此您可以通过多种方式自定义异常。
您可以引发 HTTPException,HTTPException 是一个正常的 Python 异常,带有与 API 相关的附加数据。但是你不能 return 你需要提高它,因为它是一个 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}
通过添加 name: str
作为查询参数,它会自动成为必需参数,因此您需要添加 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"
}
您可以自定义 content
,但是如果您愿意:
{
"Error":"Name field is missing",
"Customize":{
"This":"content",
"Also you can":"make it simpler"
}
}
我带着类似的问题来到这里 - 我最终处理了 RequestValidationError
以返回一个响应,其中每个字段都是该字段问题的数组。
对您请求的响应将变为(status_code=400)
{
"detail": "Invalid request",
"errors": {"name": ["field required"]}
}
在前端管理快餐栏通知非常方便,而且足够灵活。
这是处理程序
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}
),
)