Валидация даты в параметрах запроса, не отдаёт ошибку в swagger на FastAPI
Получаю и валидирую 2 даты через параметры запроса и хочу в случае ошибки выдавать ответ в swagger. Но swagger валится в 500 ошибку. Как починить то? :)
Пример запроса:
localhost:8080/dashboard?start_date=2023-05-11&end_date=2023-05-11
Router:
router.get('/dashboard', tags=['Dashboard'])
async def get_dashboard(date: DashboardDate = Depends()):
Model:
class DashboardDate(BaseModel):
start_date: str
end_date: str
@root_validator(pre=True)
def date_validation(cls, values):
if 'start_date' not in values and 'end_date' not in values:
raise ValueError('Должны быть указаны обе даты')
if values['start_date'] >= values['end_date']:
raise ValueError('Начальная дата должна быть меньше конечной даты')
try:
values['start_date'] = datetime.strptime(values['start_date'], '%Y-%m-%d').isoformat()
values['end_date'] = datetime.strptime(values['end_date'], '%Y-%m-%d').isoformat()
except:
raise ValueError('Указан неверный формат даты')
return values
Ответы (1 шт):
Автор решения: Maksim Alekseev
→ Ссылка
Что бы получить 400 ошибку можно рейзить HTTPException и первая проверка лишняя, потому что поле по дефолту обязательное и ошибка и так будет рейзиться.
from fastapi import HTTPException, status
class DashboardDate(BaseModel):
start_date: str
end_date: str
@root_validator(pre=True)
def date_validation(cls, values):
if values['start_date'] >= values['end_date']:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Начальная дата должна быть меньше конечной даты')
try:
values['start_date'] = datetime.strptime(values['start_date'], '%Y-%m-%d').isoformat()
values['end_date'] = datetime.strptime(values['end_date'], '%Y-%m-%d').isoformat()
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
return values
Запрос:
http://127.0.0.1:8000/dashboard?start_date=2023-05-11&end_date=2023-05-11
Вывод:
{
"detail": "Начальная дата должна быть меньше конечной даты"
}
Запрос:
http://127.0.0.1:8000/dashboard?start_date=2023-05-11&end_date=2023-05-12
Вывод
{
"start_date": "2023-05-11T00:00:00",
"end_date": "2023-05-12T00:00:00"
}
Запрос:
http://127.0.0.1:8000/dashboard?start_date=2023-05-11&end_date=2023-05%2F12
Вывод:
{
"detail": "time data '2023-05/12' does not match format '%Y-%m-%d'"
}
Вот здесь более развернутый ответ.