475 lines
14 KiB
Python
475 lines
14 KiB
Python
"""
|
||
Pydantic модели для ответов Kwork API.
|
||
|
||
Все модели соответствуют структуре, найденной при анализе HAR дампа.
|
||
Используются для валидации и типизации ответов API.
|
||
"""
|
||
|
||
from datetime import datetime
|
||
from typing import Any
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class KworkUser(BaseModel):
|
||
"""
|
||
Информация о пользователе Kwork.
|
||
|
||
Attributes:
|
||
id: Уникальный ID пользователя.
|
||
username: Имя пользователя (логин).
|
||
avatar_url: URL аватара или None.
|
||
is_online: Статус онлайн.
|
||
rating: Рейтинг пользователя (0-5).
|
||
|
||
Example:
|
||
user = KworkUser(id=123, username="seller", rating=4.9)
|
||
print(f"{user.username}: {user.rating} ★")
|
||
"""
|
||
|
||
id: int
|
||
username: str
|
||
avatar_url: str | None = None
|
||
is_online: bool = False
|
||
rating: float | None = None
|
||
|
||
|
||
class KworkCategory(BaseModel):
|
||
"""
|
||
Категория кворков.
|
||
|
||
Attributes:
|
||
id: Уникальный ID категории.
|
||
name: Название категории.
|
||
slug: URL-safe идентификатор.
|
||
parent_id: ID родительской категории для вложенности.
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
slug: str
|
||
parent_id: int | None = None
|
||
|
||
|
||
class Kwork(BaseModel):
|
||
"""
|
||
Кворк — услуга на Kwork.
|
||
|
||
Базовая модель кворка с основной информацией.
|
||
|
||
Attributes:
|
||
id: Уникальный ID кворка.
|
||
title: Заголовок кворка.
|
||
description: Краткое описание.
|
||
price: Цена в рублях.
|
||
currency: Валюта (по умолчанию RUB).
|
||
category_id: ID категории.
|
||
seller: Информация о продавце.
|
||
images: Список URL изображений.
|
||
rating: Рейтинг кворка (0-5).
|
||
reviews_count: Количество отзывов.
|
||
created_at: Дата создания.
|
||
updated_at: Дата последнего обновления.
|
||
"""
|
||
|
||
id: int
|
||
title: str
|
||
description: str | None = None
|
||
price: float
|
||
currency: str = "RUB"
|
||
category_id: int | None = None
|
||
seller: KworkUser | None = None
|
||
images: list[str] = Field(default_factory=list)
|
||
rating: float | None = None
|
||
reviews_count: int = 0
|
||
created_at: datetime | None = None
|
||
updated_at: datetime | None = None
|
||
|
||
|
||
class KworkDetails(Kwork):
|
||
"""
|
||
Расширенная информация о кворке.
|
||
|
||
Наследует все поля Kwork плюс дополнительные детали.
|
||
|
||
Attributes:
|
||
full_description: Полное описание услуги.
|
||
requirements: Требования к заказчику.
|
||
delivery_time: Срок выполнения в днях.
|
||
revisions: Количество бесплатных правок.
|
||
features: Список дополнительных опций.
|
||
faq: Список вопросов и ответов.
|
||
"""
|
||
|
||
full_description: str | None = None
|
||
requirements: str | None = None
|
||
delivery_time: int | None = None
|
||
revisions: int | None = None
|
||
features: list[str] = Field(default_factory=list)
|
||
faq: list[dict[str, str]] = Field(default_factory=list)
|
||
|
||
|
||
class PaginationInfo(BaseModel):
|
||
"""
|
||
Информация о пагинации.
|
||
|
||
Attributes:
|
||
current_page: Текущая страница (начиная с 1).
|
||
total_pages: Общее количество страниц.
|
||
total_items: Общее количество элементов.
|
||
items_per_page: Элементов на странице.
|
||
has_next: Есть ли следующая страница.
|
||
has_prev: Есть ли предыдущая страница.
|
||
"""
|
||
|
||
current_page: int = 1
|
||
total_pages: int = 1
|
||
total_items: int = 0
|
||
items_per_page: int = 20
|
||
has_next: bool = False
|
||
has_prev: bool = False
|
||
|
||
|
||
class CatalogResponse(BaseModel):
|
||
"""
|
||
Ответ API каталога кворков.
|
||
|
||
Attributes:
|
||
kworks: Список кворков на странице.
|
||
pagination: Информация о пагинации.
|
||
filters: Доступные фильтры.
|
||
sort_options: Доступные опции сортировки.
|
||
"""
|
||
|
||
kworks: list[Kwork] = Field(default_factory=list)
|
||
pagination: PaginationInfo | None = None
|
||
filters: dict[str, Any] | None = None
|
||
sort_options: list[str] = Field(default_factory=list)
|
||
|
||
|
||
class Project(BaseModel):
|
||
"""
|
||
Проект (заказ на бирже фриланса).
|
||
|
||
Attributes:
|
||
id: Уникальный ID проекта.
|
||
title: Заголовок проекта.
|
||
description: Описание задачи.
|
||
budget: Бюджет проекта.
|
||
budget_type: Тип бюджета: "fixed" (фиксированный) или "hourly" (почасовой).
|
||
category_id: ID категории.
|
||
customer: Информация о заказчике.
|
||
status: Статус проекта: "open", "in_progress", "completed", "cancelled".
|
||
created_at: Дата создания.
|
||
updated_at: Дата обновления.
|
||
bids_count: Количество откликов.
|
||
skills: Требуемые навыки.
|
||
"""
|
||
|
||
id: int
|
||
title: str
|
||
description: str | None = None
|
||
budget: float | None = None
|
||
budget_type: str = "fixed"
|
||
category_id: int | None = None
|
||
customer: KworkUser | None = None
|
||
status: str = "open"
|
||
created_at: datetime | None = None
|
||
updated_at: datetime | None = None
|
||
bids_count: int = 0
|
||
skills: list[str] = Field(default_factory=list)
|
||
|
||
|
||
class ProjectsResponse(BaseModel):
|
||
"""
|
||
Ответ API списка проектов.
|
||
|
||
Attributes:
|
||
projects: Список проектов.
|
||
pagination: Информация о пагинации.
|
||
"""
|
||
|
||
projects: list[Project] = Field(default_factory=list)
|
||
pagination: PaginationInfo | None = None
|
||
|
||
|
||
class Review(BaseModel):
|
||
"""
|
||
Отзыв о кворке или проекте.
|
||
|
||
Attributes:
|
||
id: Уникальный ID отзыва.
|
||
rating: Оценка от 1 до 5.
|
||
comment: Текст отзыва.
|
||
author: Автор отзыва.
|
||
kwork_id: ID кворка (если отзыв о кворке).
|
||
created_at: Дата создания.
|
||
"""
|
||
|
||
id: int
|
||
rating: int = Field(ge=1, le=5)
|
||
comment: str | None = None
|
||
author: KworkUser | None = None
|
||
kwork_id: int | None = None
|
||
created_at: datetime | None = None
|
||
|
||
|
||
class ReviewsResponse(BaseModel):
|
||
"""
|
||
Ответ API списка отзывов.
|
||
|
||
Attributes:
|
||
reviews: Список отзывов.
|
||
pagination: Информация о пагинации.
|
||
average_rating: Средний рейтинг.
|
||
"""
|
||
|
||
reviews: list[Review] = Field(default_factory=list)
|
||
pagination: PaginationInfo | None = None
|
||
average_rating: float | None = None
|
||
|
||
|
||
class Notification(BaseModel):
|
||
"""
|
||
Уведомление пользователя.
|
||
|
||
Attributes:
|
||
id: Уникальный ID уведомления.
|
||
type: Тип уведомления: "message", "order", "system", etc.
|
||
title: Заголовок уведомления.
|
||
message: Текст уведомления.
|
||
is_read: Прочитано ли уведомление.
|
||
created_at: Дата создания.
|
||
link: Ссылка для перехода (если есть).
|
||
"""
|
||
|
||
id: int
|
||
type: str
|
||
title: str
|
||
message: str
|
||
is_read: bool = False
|
||
created_at: datetime | None = None
|
||
link: str | None = None
|
||
|
||
|
||
class NotificationsResponse(BaseModel):
|
||
"""
|
||
Ответ API списка уведомлений.
|
||
|
||
Attributes:
|
||
notifications: Список уведомлений.
|
||
unread_count: Количество непрочитанных уведомлений.
|
||
"""
|
||
|
||
notifications: list[Notification] = Field(default_factory=list)
|
||
unread_count: int = 0
|
||
|
||
|
||
class Dialog(BaseModel):
|
||
"""
|
||
Диалог (чат) с пользователем.
|
||
|
||
Attributes:
|
||
id: Уникальный ID диалога.
|
||
participant: Собеседник.
|
||
last_message: Текст последнего сообщения.
|
||
unread_count: Количество непрочитанных сообщений.
|
||
updated_at: Время последнего сообщения.
|
||
"""
|
||
|
||
id: int
|
||
participant: KworkUser | None = None
|
||
last_message: str | None = None
|
||
unread_count: int = 0
|
||
updated_at: datetime | None = None
|
||
|
||
|
||
class AuthResponse(BaseModel):
|
||
"""
|
||
Ответ API аутентификации.
|
||
|
||
Attributes:
|
||
success: Успешность аутентификации.
|
||
user_id: ID пользователя.
|
||
username: Имя пользователя.
|
||
web_auth_token: Токен для последующих запросов.
|
||
message: Сообщение (например, об ошибке).
|
||
"""
|
||
|
||
success: bool
|
||
user_id: int | None = None
|
||
username: str | None = None
|
||
web_auth_token: str | None = None
|
||
message: str | None = None
|
||
|
||
|
||
class ErrorDetail(BaseModel):
|
||
"""
|
||
Детали ошибки API.
|
||
|
||
Attributes:
|
||
code: Код ошибки.
|
||
message: Сообщение об ошибке.
|
||
field: Поле, вызвавшее ошибку (если применимо).
|
||
"""
|
||
|
||
code: str
|
||
message: str
|
||
field: str | None = None
|
||
|
||
|
||
class APIErrorResponse(BaseModel):
|
||
"""
|
||
Стандартный ответ API об ошибке.
|
||
|
||
Attributes:
|
||
success: Всегда False для ошибок.
|
||
errors: Список деталей ошибок.
|
||
message: Общее сообщение об ошибке.
|
||
"""
|
||
|
||
success: bool = False
|
||
errors: list[ErrorDetail] = Field(default_factory=list)
|
||
message: str | None = None
|
||
|
||
|
||
class City(BaseModel):
|
||
"""
|
||
Город из справочника.
|
||
|
||
Attributes:
|
||
id: Уникальный ID города.
|
||
name: Название города.
|
||
country_id: ID страны.
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
country_id: int | None = None
|
||
|
||
|
||
class Country(BaseModel):
|
||
"""
|
||
Страна из справочника.
|
||
|
||
Attributes:
|
||
id: Уникальный ID страны.
|
||
name: Название страны.
|
||
code: Код страны (ISO).
|
||
cities: Список городов в стране.
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
code: str | None = None
|
||
cities: list[City] = Field(default_factory=list)
|
||
|
||
|
||
class TimeZone(BaseModel):
|
||
"""
|
||
Часовой пояс.
|
||
|
||
Attributes:
|
||
id: Уникальный ID.
|
||
name: Название пояса.
|
||
offset: Смещение от UTC (например, "+03:00").
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
offset: str
|
||
|
||
|
||
class Feature(BaseModel):
|
||
"""
|
||
Дополнительная функция (feature) для кворка.
|
||
|
||
Attributes:
|
||
id: Уникальный ID функции.
|
||
name: Название.
|
||
description: Описание.
|
||
price: Стоимость в рублях.
|
||
type: Тип: "extra", "premium", etc.
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
description: str | None = None
|
||
price: float
|
||
type: str
|
||
|
||
|
||
class Badge(BaseModel):
|
||
"""
|
||
Значок (достижение) пользователя.
|
||
|
||
Attributes:
|
||
id: Уникальный ID значка.
|
||
name: Название значка.
|
||
description: Описание достижения.
|
||
icon_url: URL иконки значка.
|
||
"""
|
||
|
||
id: int
|
||
name: str
|
||
description: str | None = None
|
||
icon_url: str | None = None
|
||
|
||
|
||
# Generic response wrapper
|
||
class DataResponse(BaseModel):
|
||
"""
|
||
Универсальный ответ API с данными.
|
||
|
||
Используется как обёртка для различных ответов API.
|
||
|
||
Attributes:
|
||
success: Успешность запроса.
|
||
data: Полезные данные (словарь).
|
||
message: Дополнительное сообщение.
|
||
"""
|
||
|
||
success: bool = True
|
||
data: dict[str, Any] | None = None
|
||
message: str | None = None
|
||
|
||
|
||
class ValidationIssue(BaseModel):
|
||
"""
|
||
Проблема, найденная при валидации текста.
|
||
|
||
Attributes:
|
||
type: Тип проблемы: "error", "warning", "suggestion".
|
||
code: Код ошибки (например, "SPELLING", "GRAMMAR", "LENGTH").
|
||
message: Описание проблемы.
|
||
position: Позиция в тексте (если применимо).
|
||
suggestion: Предлагаемое исправление (если есть).
|
||
"""
|
||
|
||
type: str = "error"
|
||
code: str
|
||
message: str
|
||
position: int | None = None
|
||
suggestion: str | None = None
|
||
|
||
|
||
class ValidationResponse(BaseModel):
|
||
"""
|
||
Ответ API валидации текста.
|
||
|
||
Используется для эндпоинта /api/validation/checktext.
|
||
|
||
Attributes:
|
||
success: Успешность валидации.
|
||
is_valid: Текст проходит валидацию (нет критических ошибок).
|
||
issues: Список найденных проблем.
|
||
score: Оценка качества текста (0-100, если доступна).
|
||
message: Дополнительное сообщение.
|
||
"""
|
||
|
||
success: bool = True
|
||
is_valid: bool = True
|
||
issues: list[ValidationIssue] = Field(default_factory=list)
|
||
score: int | None = None
|
||
message: str | None = None
|