From 9a8b5ba9196ad3ef8ae3e41be3471a150b3a94a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=B4=D0=B5=D0=BB=D0=B8=D0=BD=D0=B0=20=D0=A1=D0=B0?= =?UTF-8?q?=D1=82=D1=82=D0=B0=D1=80=D0=BE=D0=B2=D0=B0?= Date: Thu, 4 Jun 2026 16:21:59 +0000 Subject: [PATCH] add models.py --- models.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 models.py diff --git a/models.py b/models.py new file mode 100644 index 0000000..283c770 --- /dev/null +++ b/models.py @@ -0,0 +1,35 @@ +from typing import Literal, Union, Annotated +from pydantic import BaseModel, Field + +# --- События --- +class HttpOkEvent(BaseModel): + """Успешное HTTP-событие (2xx)""" + kind: Literal["ok"] = Field(description="Тип события: успешный ответ") + status: Literal[200] = Field(description="HTTP статус-код успешного ответа") + path: str = Field(description="Путь запроса (endpoint)") + duration_ms: float = Field(description="Длительность запроса в миллисекундах") + + def __repr__(self) -> str: + return f"HttpOkEvent(kind='ok', status=200, path='{self.path}', duration_ms={self.duration_ms})" + + +class HttpErrorEvent(BaseModel): + """Ошибочное HTTP-событие (4xx/5xx)""" + kind: Literal["error"] = Field(description="Тип события: ошибка") + status: int = Field(description="HTTP статус-код ошибки (4xx или 5xx)", ge=400, le=599) + path: str = Field(description="Путь запроса (endpoint)") + error_message: str = Field(description="Сообщение об ошибке") + + def __repr__(self) -> str: + return f"HttpErrorEvent(kind='error', status={self.status}, path='{self.path}', error='{self.error_message[:30]}...')" + + +# --- Discriminated Union (способ 1: через аннотацию) --- +ApiEvent = Annotated[ + Union[HttpOkEvent, HttpErrorEvent], + Field(discriminator="kind") +] + +# Альтернативный способ через TypeAdapter (для прямого использования в Pydantic) +from pydantic import TypeAdapter +ApiEventAdapter = TypeAdapter(ApiEvent) \ No newline at end of file