FastAPI и Pydantic (формат даты и кастомизация ответа)

При реализации проекта с использованием FastAPI и Pydantic возникло 2 вопроса:

  1. Каким образом можно изменить стандартную валидацию даты с YYYY-MM-DD на DD.MM.YYYY (пробовал несколько вариантов все равно в swagger отображается стандартная валидацию)

  2. Каким образом можно изменить ответ сервиса в случае возникновения ошибки (HTTP 422) с

    { "detail": [ { "loc": [ "string", 0 ], "msg": "string", "type": "string" } ] }

    на свой вариант ответа с передачей (в свой) значения msg


Ответы (1 шт):

Автор решения: strawdog

По поводу пользовательской валидации: пишите свой превалидатор и добавляете его в модель:

from datetime import date, datetime
from pydantic import BaseModel, BeforeValidator
from typing import Annotated

def custom_date(d: str) -> datetime:  
    d = datetime.strptime(d, "%d-%m-%Y") # ваш формат даты
    return d

class Model(BaseModel):
    d: Annotated[datetime, BeforeValidator(custom_date)]

MyModel = Model(d='23-04-2032') #ok
MyModel = Model(d='230-04-2032') #error
MyModel = Model(d='23-14-2032') #error
print(MyModel.model_dump())

можно попробовать кастомизировать, используя не объект datetime, а строку:

def custom_date(d: str) -> str:  
    _ = datetime.strptime(d, "%d-%m-%Y")    
    return d

class Model(BaseModel):
    d: Annotated[str, BeforeValidator(custom_date)]

что касается второй части вопроса, то вам читать про
@app.exception_handler(RequestValidationError):

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

UPDATE
что касается хинтов от сваггера, то можно попробовать расширить модель:

class Model(BaseModel):
    d: Annotated[str,
        BeforeValidator(custom_date),
        Field(json_schema_extra={'title': 'Date', 'examples': ['23-12-2024'],}
             )]
→ Ссылка