Повторный экзамен: Structured output — Union событий API: README.md

This commit is contained in:
2026-06-02 06:02:37 +00:00
parent 66885382dd
commit 70b785ef09
+142 -2
View File
@@ -1,3 +1,143 @@
# task-6a1d75e5-povtornyy-ekzamen-structu
# Structured Output Union событий API
Решения домашних заданий
## 📖 Описание
`solution.py` – практическое задание, в котором из **сырого лога** (несколько строк разного формата) извлекаются типизированные события через **Pydantic v2** и **LangChain ≥1.0**.
Задача закрепляет работу с **Union + Enums + StructuredOutput**: одна входная лента, разные схемы, явный `type`/`kind` для маршрутизации.
> **Цель** – получить список типизированных событий `ApiEvent` из произвольного текста, а затем вывести их в табличном виде.
---
## 📦 Установка зависимостей
```bash
# Создайте и активируйте виртуальное окружение (необязательно)
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Установите зависимости
pip install langchain-core langchain-openai pydantic python-dotenv
```
> **Важно**:
> * `langchain-openai` подключает OpenAI API.
> * Для работы с другими LLM (например, Ollama) замените `langchain-openai` на `langchain-ollama` и поправьте импорт в `solution.py`.
> * В файле `.env` укажите переменную `OPENAI_API_KEY` (или `OLLAMA_BASE_URL` для Ollama).
---
## 🏃‍♂️ Запуск
### 1. Запуск по умолчанию (пример лога)
```bash
python solution.py
```
> Вы увидите вывод, где каждая строка лога преобразована в объект `ApiEvent` и напечатана в виде таблицы:
```
Вход: 3 строки лога разного формата
Выход:
┌───────┬───────────────────────┬────────┬───────────────┐
│ kind │ path │ status │ duration_ms │
├───────┼───────────────────────┼────────┼───────────────┤
│ ok │ /api/v1/users │ 200 │ 123 │
│ error │ /api/v1/orders │ 404 │ 0 │
│ error │ /api/v1/payments │ 500 │ 0 │
└───────┴───────────────────────┴────────┴───────────────┘
```
### 2. Передача собственного текста
```bash
python solution.py --text "GET /api/v1/products 200 45ms\nPOST /api/v1/cart 500 Internal Server Error"
```
> Скрипт разбивает входной текст на строки, отправляет каждую в LLM, получает типизированный объект и выводит таблицу.
### 3. Использование собственного файла лога
```bash
python solution.py --file path/to/your.log
```
> Внутри `solution.py` реализована простая логика: если указан `--file`, то читается содержимое файла и используется в качестве входного текста.
---
## 📦 Структура проекта
```
.
├── solution.py # Основной скрипт
├── .env # Переменные окружения (OPENAI_API_KEY)
└── README.md # Это файл
```
---
## 🔧 Как это работает
1. **Модели**
```python
class HttpOkEvent(BaseModel):
kind: Literal["ok"] = Field(..., description="Тип события: OK")
status: Literal[200] = Field(..., description="HTTP статус 200")
path: str = Field(..., description="Запрошенный путь")
duration_ms: int = Field(..., description="Время выполнения в миллисекундах")
class HttpErrorEvent(BaseModel):
kind: Literal["error"] = Field(..., description="Тип события: Ошибка")
status: int = Field(..., description="HTTP статус 4xx/5xx")
path: str = Field(..., description="Запрошенный путь")
error_message: str = Field(..., description="Текст ошибки")
```
2. **Union**
```python
ApiEvent = Annotated[
Union[HttpOkEvent, HttpErrorEvent],
Field(discriminator="kind")
]
```
3. **Парсинг**
* Для каждой строки лога создаётся промпт, который задаёт задачу LLM: «Преобразуй строку в JSON, соответствующий `ApiEvent`».
* Используется `PydanticOutputParser` (или `with_structured_output`) для строгой валидации.
4. **Вывод**
* Список `ApiEvent` сериализуется через `model_dump()` и печатается в табличном формате (можно заменить на `tabulate` или `pandas`).
---
## 📌 Пример использования в коде
```python
from solution import parse_log, print_events
log_text = """
GET /api/v1/users 200 123ms
POST /api/v1/orders 404 Not Found
GET /api/v1/payments 500 Internal Server Error
"""
events = parse_log(log_text)
print_events(events)
```
---
## 🤝 Вклад
Если хотите улучшить скрипт (добавить поддержку новых форматов, улучшить промпт, добавить кэширование), создайте Pull Request. Убедитесь, что все тесты (если есть) проходят.
---
## 📄 Лицензия
MIT © 2026
---