![](/img/trans.png)
[英]How to change the default Pydantic error message using FastAPI?
[英]Is it possible to change the pydantic error messages in fastAPI?
在 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"
}
]
}
我想发送一条简单的消息: {"field-name":"error message"}
。
在他们提到的 Pydantic 文档中,在 try: except 块中创建一个模型实例并在 except 块中构造错误消息。 但是在快速 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)
这里fastapi本身创建的location实例就是问题所在。
有没有办法构造错误消息?
实际上这个错误消息来自fastapi.exceptions
,您可以通过覆盖自定义异常来实现,
想象一下我有这样的简单应用程序:
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
如果我将无效值发送到我的请求正文
{
"title": 22,
"size": "hehe"
}
现在错误将更加个性化:
{
"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"
}
}
您可以更改异常内容,一切由您决定。
我正在为它写一个中间件。
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
我不确定你会比其他答案更喜欢我的答案。 您可以使用不同的错误消息创建自定义 pydantic。 有点矫枉过正,但可以解决您的特定问题。 在这个例子中,当我插入一个未经许可的 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.