简体   繁体   English

是否可以更改 fastAPI 中的 pydantic 错误消息?

[英]Is it possible to change the pydantic error messages in fastAPI?

In the FastAPI framework, the pydantic error messages are showing like below.在 FastAPI 框架中,pydantic 错误消息如下所示。

{"detail": [
{
    "loc": [
        "body",
        "location",
        "name"
    ],
    "msg": "field required",
    "type": "value_error.missing"
},
{
    "loc": [
        "body",
        "location",
        "name12"
    ],
    "msg": "extra fields not permitted",
    "type": "value_error.extra"
}
]
}

I want to send a simple message: {"field-name":"error message"} .我想发送一条简单的消息: {"field-name":"error message"}

In Pydantic document they mentioned like, create a model instance in the try: except blocks and construct the error message in the except block.在他们提到的 Pydantic 文档中,在 try: except 块中创建一个模型实例并在 except 块中构造错误消息。 But in fast API, model instance created by fastapi itself, for example, if I write an URL like below但是在快速 API 中,由 fastapi 本身创建的模型实例,例如,如果我写一个像下面这样的 URL

@router.post("/", response_model=DataModelOut)
async def create_location(location: schemas.LocationIn, user: str = Depends(get_current_user) ):
return model.save(location,user)

Here the location instance created by fastapi itself is the problem.这里fastapi本身创建的location实例就是问题所在。

Is there any way to construct the error message?有没有办法构造错误消息?

Actually this error messages coming from fastapi.exceptions , You can achieve that by overriding the custom exceptions,实际上这个错误消息来自fastapi.exceptions ,您可以通过覆盖自定义异常来实现,

Imagine i have simple app like this:想象一下我有这样的简单应用程序:

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

@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(),
                "body": exc.body,
                 "your_additional_errors": {"Will be": "Inside", "This":" Error message"}}),
    )

class Item(BaseModel):
    title: str
    size: int

@app.post("/items/")
async def create_item(item: Item):
    return item

If i send values invalid values to my Request body如果我将无效值发送到我的请求正文

{
 "title": 22,
 "size": "hehe"
}

Now the error will be more customized:现在错误将更加个性化:

{
  "detail": [
    {
      "loc": [
        "body",
        "size"
      ],
      "msg": "value is not a valid integer",
      "type": "type_error.integer"
    }
  ],
  "body": {
    "title": 22,
    "size": "hehe"
  },
  "your_additional_errors": {
    "Will be": "Inside the",
    "Error": "Message"
  }
}

You can change the content of exception, everything is up to you.您可以更改异常内容,一切由您决定。

I am writing a middle ware for it.我正在为它写一个中间件。

async def genrange(s):
    import json
    s = json.loads(s)
    yield json.dumps({"message":{k.get("loc")[-1]:k.get("msg") for k in s['detail']},
        "id":None})

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    status_code = response.status_code
    if status_code >=300:
        async for i in response.body_iterator:
            data = genrange(i)
        response.body_iterator = data
    return response

I'm not sure you'll like my answer better than the other answers.我不确定你会比其他答案更喜欢我的答案。 You can create a custom pydantic, with diffrent error messages.您可以使用不同的错误消息创建自定义 pydantic。 Kinda overkill, but could solve you a specific problem.有点矫枉过正,但可以解决您的特定问题。 In this example, I am changing the error message, when I insert an unpermitted HttpUrlSceme.在这个例子中,当我插入一个未经许可的 HttpUrlSceme 时,我正在更改错误消息。

class UrlSchemePermittedError(errors.UrlError):
    code = 'url.scheme'
    msg_template = 'URL scheme not cool'

    def __init__(self, allowed_schemes: Set[str]):
        super().__init__(allowed_schemes=allowed_schemes)

class AnyHttpUrlDirrentMessage(AnyUrl):
    allowed_schemes = {'http', 'https'}
    @classmethod
    def validate_parts(cls, parts: Dict[str, str]) -> Dict[str, str]:
        """
        A method used to validate parts of an URL.
        Could be overridden to set default values for parts if missing
        """
        scheme = parts['scheme']
        if scheme is None:
            raise errors.UrlSchemeError()

        if cls.allowed_schemes and scheme.lower() not in cls.allowed_schemes:
            raise UrlSchemePermittedError(cls.allowed_schemes)

        port = parts['port']
        if port is not None and int(port) > 65_535:
            raise errors.UrlPortError()

        user = parts['user']
        if cls.user_required and user is None:
            raise errors.UrlUserInfoError()

        return parts

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM