python - 如何使用 FastAPI 更改默认的 Pydantic 错误消息?

标签 python fastapi pydantic

有什么方法可以更改 Pydantic 的默认响应,使 "msg""message"

{
    "detail": [
        {
            "loc": [
                "body",
                "password"
            ],
            "msg": "Password should at least 8 characters long.",
            "type": "value_error"
        }
    ]
}

最佳答案

这看起来像一个 JSON 响应,而 Pydantic 本身不会为 ValidationError 给出 JSON 响应。它应该只是一个常规的 raise-d Exception 像这样:

In [2]: from pydantic import BaseModel, constr

In [3]: class Credentials(BaseModel):
   ...:     password: constr(min_length=8)
   ...: 

In [4]: Credentials(password="xyz")
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 Credentials(password="xyz")

...

ValidationError: 1 validation error for Credentials
password
  ensure this value has at least 8 characters (type=value_error.any_str.min_length; limit_value=8)

我认为您使用的是 FastAPI ( which has Pydantic integration ),当请求出现 ValidationError 时,此 JSON 响应实际上是 FastAPI 的内置错误响应,如 FastAPI docs on Handling Errors 中所述.我可以使用此示例复制类似的错误格式:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel, constr

class Credentials(BaseModel):
    password: constr(min_length=8)

app = FastAPI()

@app.post("/login")
async def login(credentials: Credentials):
    print(credentials)  # This is just as an example!
    return JSONResponse(status_code=200)
$ curl -s --header "Content-Type: application/json" --request POST --data '{"password":"xyz"}' http://localhost:8000/login | jq
{
  "detail": [
    {
      "loc": [
        "body",
        "password"
      ],
      "msg": "ensure this value has at least 8 characters",
      "type": "value_error.any_str.min_length",
      "ctx": {
        "limit_value": 8
      }
    }
  ]
}

要更改响应正文,请查看 Use the RequestValidationError body 上的 FastAPI 文档这表明您可以访问默认的 detail 错误列表,然后您可以编辑或复制到自定义的详细信息列表,然后将其设置为 JSON 的 content错误响应。

from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel, constr

class Credentials(BaseModel):
    password: constr(min_length=8)

app = FastAPI()

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    # Get the original 'detail' list of errors
    details = exc.errors()
    modified_details = []
    # Replace 'msg' with 'message' for each error
    for error in details:
        modified_details.append(
            {
                "loc": error["loc"],
                "message": error["msg"],
                "type": error["type"],
            }
        )
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder({"detail": modified_details}),
    )


@app.post("/login")
async def login(credentials: Credentials):
    print(credentials)  # Just as an example!
    return JSONResponse(status_code=200)
$ curl -s --header "Content-Type: application/json" --request POST --data '{"password":"xyz"}' http://localhost:8000/login | jq
{
  "detail": [
    {
      "loc": [
        "body",
        "password"
      ],
      "message": "ensure this value has at least 8 characters",
      "type": "value_error.any_str.min_length"
    }
  ]
}

当然,您也可以只定义自己的自定义contentJSONResponse

关于python - 如何使用 FastAPI 更改默认的 Pydantic 错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71895606/

相关文章:

python - 如何使用 pydantic 模式从 sqlalchemy 关系中单独获取列

python - 从 FastAPI 中发布的 Pydantic 模型更新 SQLAlchemy ORM 现有模型?

python - 将 pandas dtypes 转换为 BigQuery 类型表示

python - 使用 xlwings 和 python 复制工作表

python - 如何提高FastAPI中的GET查询性能?

python - Fastapi - 需要使用 Body 和 Depends 作为默认值

python - pydantic.error_wrappers.ValidationError : value is not a valid list (type=type_error. 列表)

python - Pydantic 从 __eq__ 中排除字段以避免递归错误

python - 未定义的名称 'ndimage' 即使我已经使用 import scipy.ndimage 和 loop 导入了它

python - 如何在 Flask-SQLAlchemy 中进行多对多查询?