208 lines
7.8 KiB
Python
208 lines
7.8 KiB
Python
"""
|
||
Pydantic схемы для валидации данных API
|
||
"""
|
||
|
||
from pydantic import BaseModel, Field, ConfigDict
|
||
from typing import Optional
|
||
from datetime import datetime
|
||
|
||
# Базовые схемы для пользователей
|
||
|
||
class UserBase(BaseModel):
|
||
"""Базовая схема пользователя"""
|
||
telegram_id: int = Field(..., description="Telegram ID пользователя")
|
||
username: Optional[str] = Field(None, max_length=255, description="Username в Telegram")
|
||
first_name: Optional[str] = Field(None, max_length=255, description="Имя пользователя")
|
||
last_name: Optional[str] = Field(None, max_length=255, description="Фамилия пользователя")
|
||
language_code: str = Field(default="ru", max_length=10, description="Код языка")
|
||
|
||
class UserCreate(UserBase):
|
||
"""Схема для создания пользователя"""
|
||
pass
|
||
|
||
class UserUpdate(BaseModel):
|
||
"""Схема для обновления пользователя"""
|
||
username: Optional[str] = Field(None, max_length=255)
|
||
first_name: Optional[str] = Field(None, max_length=255)
|
||
last_name: Optional[str] = Field(None, max_length=255)
|
||
language_code: Optional[str] = Field(None, max_length=10)
|
||
is_active: Optional[bool] = None
|
||
|
||
class UserResponse(UserBase):
|
||
"""Схема ответа с данными пользователя"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
is_active: bool
|
||
is_admin: bool
|
||
created_at: datetime
|
||
updated_at: Optional[datetime] = None
|
||
|
||
# Базовые схемы для сообщений
|
||
|
||
class MessageBase(BaseModel):
|
||
"""Базовая схема сообщения"""
|
||
telegram_message_id: int = Field(..., description="ID сообщения в Telegram")
|
||
user_id: int = Field(..., description="ID пользователя в нашей БД")
|
||
text: Optional[str] = Field(None, description="Текст сообщения")
|
||
message_type: str = Field(default="text", max_length=50, description="Тип сообщения")
|
||
|
||
class MessageCreate(MessageBase):
|
||
"""Схема для создания сообщения"""
|
||
pass
|
||
|
||
class MessageResponse(MessageBase):
|
||
"""Схема ответа с данными сообщения"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
created_at: datetime
|
||
|
||
# Базовые схемы для настроек бота
|
||
|
||
class BotSettingBase(BaseModel):
|
||
"""Базовая схема настройки бота"""
|
||
key: str = Field(..., max_length=255, description="Ключ настройки")
|
||
value: Optional[str] = Field(None, description="Значение настройки")
|
||
description: Optional[str] = Field(None, description="Описание настройки")
|
||
|
||
class BotSettingCreate(BotSettingBase):
|
||
"""Схема для создания настройки"""
|
||
pass
|
||
|
||
class BotSettingUpdate(BaseModel):
|
||
"""Схема для обновления настройки"""
|
||
value: Optional[str] = None
|
||
description: Optional[str] = None
|
||
|
||
class BotSettingResponse(BotSettingBase):
|
||
"""Схема ответа с данными настройки"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
created_at: datetime
|
||
updated_at: Optional[datetime] = None
|
||
|
||
# Схемы для общих ответов API
|
||
|
||
class MessageResponseModel(BaseModel):
|
||
"""Общая схема ответа с сообщением"""
|
||
message: str
|
||
status: str = "success"
|
||
|
||
class ErrorResponse(BaseModel):
|
||
"""Схема ответа с ошибкой"""
|
||
detail: str
|
||
status: str = "error"
|
||
|
||
class HealthCheckResponse(BaseModel):
|
||
"""Схема ответа проверки здоровья"""
|
||
status: str
|
||
database: str
|
||
|
||
class RootResponse(BaseModel):
|
||
"""Схема корневого ответа"""
|
||
message: str
|
||
version: str
|
||
status: str
|
||
|
||
# Схемы для пагинации
|
||
|
||
class PaginationParams(BaseModel):
|
||
"""Параметры пагинации"""
|
||
limit: int = Field(default=100, ge=1, le=1000, description="Количество элементов на странице")
|
||
offset: int = Field(default=0, ge=0, description="Смещение")
|
||
|
||
class PaginatedResponse(BaseModel):
|
||
"""Схема ответа с пагинацией"""
|
||
items: list
|
||
total: int
|
||
limit: int
|
||
offset: int
|
||
has_next: bool
|
||
has_prev: bool
|
||
|
||
# Схемы для работы с тестами
|
||
|
||
class TestCategoryCreate(BaseModel):
|
||
"""Схема для создания категории тестов"""
|
||
name: str = Field(..., max_length=100, description="Название категории")
|
||
description: Optional[str] = Field(None, description="Описание категории")
|
||
|
||
class TestCategoryResponse(BaseModel):
|
||
"""Схема ответа с категорией тестов"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
name: str
|
||
description: Optional[str]
|
||
created_at: datetime
|
||
|
||
class TestCreate(BaseModel):
|
||
"""Схема для создания теста"""
|
||
title: str = Field(..., max_length=200, description="Название теста")
|
||
description: Optional[str] = Field(None, description="Описание теста")
|
||
category_id: Optional[int] = Field(None, description="ID категории")
|
||
is_active: bool = Field(default=True, description="Активен ли тест")
|
||
time_limit_minutes: Optional[int] = Field(None, ge=1, description="Лимит времени в минутах")
|
||
|
||
class TestResponse(BaseModel):
|
||
"""Схема ответа с тестом"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
title: str
|
||
description: Optional[str]
|
||
category_id: Optional[int]
|
||
is_active: bool
|
||
time_limit_minutes: Optional[int]
|
||
created_at: datetime
|
||
updated_at: Optional[datetime]
|
||
|
||
class QuestionCreate(BaseModel):
|
||
"""Схема для создания вопроса"""
|
||
test_id: int = Field(..., description="ID теста")
|
||
question_text: str = Field(..., description="Текст вопроса")
|
||
question_type: str = Field(default="single_choice", description="Тип вопроса")
|
||
order_number: int = Field(..., ge=1, description="Порядковый номер вопроса")
|
||
points: int = Field(default=1, ge=0, description="Количество баллов за правильный ответ")
|
||
image_id: Optional[int] = Field(None, description="ID изображения к вопросу")
|
||
|
||
class QuestionResponse(BaseModel):
|
||
"""Схема ответа с вопросом"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
test_id: int
|
||
question_text: str
|
||
question_type: str
|
||
order_number: int
|
||
points: int
|
||
image_id: Optional[int]
|
||
created_at: datetime
|
||
|
||
class AnswerOptionCreate(BaseModel):
|
||
"""Схема для создания варианта ответа"""
|
||
question_id: int = Field(..., description="ID вопроса")
|
||
option_text: str = Field(..., description="Текст варианта ответа")
|
||
is_correct: bool = Field(..., description="Правильный ли этот вариант")
|
||
order_number: int = Field(..., ge=1, description="Порядковый номер варианта")
|
||
|
||
class AnswerOptionResponse(BaseModel):
|
||
"""Схема ответа с вариантом ответа"""
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
id: int
|
||
question_id: int
|
||
option_text: str
|
||
is_correct: bool
|
||
order_number: int
|
||
created_at: datetime
|
||
|
||
class ImageUploadResponse(BaseModel):
|
||
"""Схема ответа при загрузке изображения"""
|
||
id: int
|
||
filename: str
|
||
content_type: str
|
||
file_size: int
|
||
message: str = "Изображение успешно загружено" |