Files
2026-09-02 16:40:56 +03:00

283 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# selectel-ml-tui
TUI-приложение (Python 3.10+) для отображения потребления **ИИ-роутера Selectel**
прямо в терминале. Работает на Ubuntu (22.04+/24.04) и macOS (12+).
## Возможности
- Дашборд потребления за месяц (сумма, запросы, input/output/cache токены)
- Метрики за 24 часа (доступность, TTFT, задержка) — общие и по моделям
- Бюджет роутера (лимит/расход/остаток) и лимиты по API-ключам
- История потребления по дням с Unicode-бар-графиком (локальный SQLite-кэш)
- Детализация метрик конкретной модели (Enter в таблице моделей)
- Офлайн-режим: при недоступности API показывает последние данные из кэша
- Автообновление по интервалу из конфигурации (по умолчанию 60 с)
- Экспорт истории в CSV/JSON, диагностика окружения (`doctor`)
## Интерфейс
```
┌─ Selectel ML Tokens ──────────────── online · 1 186,73 ₽ ───────┐
│ ┌─ Потребление за месяц ─┐ ┌─ Метрики за 24 часа ──────────────┐ │
│ │ Сумма: 1 186,73 ₽ │ │ Доступность: 100,0% │ │
│ │ Запросы: 1 096 │ │ TTFT: 3 670,0 мс │ │
│ │ Токены: 482 749 246 │ │ Запросы: 1 097 │ │
│ │ Input: 244 004 716 │ │ Input/Output/Cache: … │ │
│ │ Output/Cache: … │ └───────────────────────────────────┘ │
│ │ Бюджет: 2 000 ₽ │ │
│ └────────────────────────┘ │
│ По моделям │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Модель │ Запросы │ Доступность │ TTFT, мс │ Задержка, мс │ │
│ │ deepseek-v4-pro │ 1028 │ 100,0% │ 3,69 │ 12,29 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ r — обновить h — история k — ключи s — настройки q — выход │
└──────────────────────────────────────────────────────────────────┘
```
Экран **История** (**h**): бар-график стоимости по дням + таблица
(период 7/30/90 дней — кнопками). Экран **Ключи** (**k**): лимиты и расход по
API-ключам. Экран **Настройки** (**s**): интервал обновления, «Очистить кэш»,
пути и маскированный токен. **Esc** — назад.
## Горячие клавиши
| Клавиша | Действие |
|---|---|
| `r` | Обновить данные |
| `h` | История потребления |
| `k` | API-ключи и лимиты |
| `s` | Настройки |
| `q` | Выход |
| `Esc` | Назад (с экрана истории/настроек/модели) |
| `Enter` / клик | Детализация метрик модели (в таблице «По моделям») |
На macOS горячие клавиши — обычные символьные (`r/h/s/q`); Option/Command
зарезервированы системой и не используются.
## Требования
- Python 3.10+
- Ubuntu 22.04+/24.04, macOS 12+
- Терминал с поддержкой цвета и UTF-8 (GNOME Terminal, Konsole, tmux,
Terminal.app, iTerm2)
## Источники данных
- **Billing Statistics API** (`https://api.selectel.ru`, заголовок `X-Token`):
стоимость потребления ИИ-роутера (провайдер `aig`) по дням/часам. Параметры
`start`/`end` принимаются в полном ISO-формате (`YYYY-MM-DDTHH:MM:SS.000`),
короткие даты дополняются клиентом автоматически. Значение `value` в копейках.
- **Gateway API ИИ-роутера** (`/aig/gateway/v1/*`, IAM-токен проекта + `X-Project-Id`):
токены, метрики, каталог моделей.
- **IAM-авторизация**: `POST https://cloud.api.selcloud.ru/identity/v3/auth/tokens`
(логин/пароль сервисного пользователя, scope project, TTL 24 ч, кэш с
автообновлением за 5 минут до истечения).
## Получение токенов (панель Selectel)
- **Статический токен** (billing-метрики): панель `my.selectel.ru` → профиль →
**Доступ****API-ключи**. Вставьте токен в мастер настройки.
- **IAM-токен** (gateway: сумма/токены/модели/ключи): нужен **сервисный
пользователь**. Создайте его в `my.selectel.ru`**IAM** → **Сервисные
пользователи** (имя без email, например `ml-monitor`), назначьте роль на
нужный ML-проект. Затем в `selectel-ml-tui config` укажите имя сервисного
пользователя, его пароль, `project_id` и `domain_id` (номер аккаунта).
Без сервисного пользователя доступна только стоимость из billing.
Подробнее об API: [Selectel ML / управление роутером](https://selectel.ru/services/ml/) —
внутренние API панели и документация по биллингу.
## Установка
```bash
make install # Ubuntu/macOS
# или
./scripts/install_ubuntu.sh # Ubuntu
./scripts/install_macos.sh # macOS
# или make install-ubuntu / make install-macos
```
Всё сводится к двум командам на каждой ОС:
```bash
# Ubuntu
sudo apt-get update && sudo apt-get install -y python3 python3-venv python3-pip
pip install --user . # или ./scripts/install_ubuntu.sh
```
```bash
# macOS
brew install python@3.11 # или ./scripts/install_macos.sh
pip install --user .
```
## Запуск
```bash
make run
# или
.venv/bin/selectel-ml-tui run
# или (с корректным TERM/LANG, подходит для tmux/ssh)
./scripts/run.sh run
```
CLI-точка входа: `selectel-ml-tui` (console_scripts), а также `python -m selectel_ml_tui`.
При первом запуске без настроенных учётных данных выводится подсказка
(`selectel-ml-tui config`); `selectel-ml-tui doctor` предупреждает, что токен
не настроен.
TUI-дашборд:
- **Dashboard**: потребление за месяц (сумма, токены), метрики за 24 часа,
таблица «По моделям»; статус в заголовке — `online`/`offline`
- **r** — обновить, **h** — история, **s** — настройки, **q** — выход
- Автообновление по интервалу из конфигурации (по умолчанию 60 с)
- При недоступности API показывает последние данные из кэша (офлайн)
- **История** (**h**): таблица по дням из кэша + Unicode-бар-график стоимости,
выбор периода 7/30/90 дней (кнопки)
- **Модель** (Enter/клик в таблице моделей): детализация метрик конкретной модели
- **Настройки** (**s**): изменение интервала обновления (сохранение в конфиг),
«Очистить кэш», пути к конфигу/БД, маскированный токен
- Навигация: **Esc** — назад
## Конфигурация
```bash
selectel-ml-tui config # интерактивный мастер настройки
selectel-ml-tui config --path # показать пути конфигурации
selectel-ml-tui config --show # показать текущие настройки (секреты маскируются)
```
Настройки хранятся в `config.toml`, учётные данные (пароль сервисного
пользователя, статический токен) — в `credentials.json` в каталоге конфигурации
(права 0600). Каталог: Linux — `~/.config/selectel-ml-tui`, macOS —
`~/Library/Application Support/selectel-ml-tui`.
Переменные окружения имеют приоритет над файлом конфигурации:
- `SELCTEL_API_URL` — базовый URL API (вместо `api_base_url`)
- `SELCTEL_TOKEN` — статический токен (вместо `static_token`)
- `SELCTEL_SERVICE_USER`, `SELCTEL_PASSWORD` — сервисный пользователь
- `SELCTEL_PROJECT_ID`, `SELCTEL_DOMAIN_ID` — проект и аккаунт
- остальные поля: `SELCTEL_API_BASE_URL`, `SELCTEL_REFRESH_INTERVAL`, `SELCTEL_ROUTER_ID`, …
## Локальный кэш и история
Данные сохраняются в SQLite-базу (`cache.db`) в каталоге данных платформы
(Linux: `~/.local/share/selectel-ml-tui`, macOS:
`~/Library/Application Support/selectel-ml-tui`) при каждом успешном обновлении:
- `consumption_snapshots` — снимки потребления (сумма, токены)
- `metrics_snapshots` — снимки общих метрик
- `model_metrics` — метрики по моделям
- `history` — точки истории по периодам (upsert, без дублей)
При недоступности API TUI показывает «офлайн» и последние данные из кэша.
Старые записи удаляются автоматически (TTL 180 дней).
Экспорт истории: `selectel-ml-tui export --format json|csv -o <файл>`.
## Платформы (Ubuntu и macOS)
Диагностика окружения: `selectel-ml-tui doctor` — проверяет Python (>=3.10),
`TERM`, `LANG`, кодировку UTF-8, выводит пути к конфигурации и данным.
Отличия платформ:
| | Ubuntu 22.04+/24.04 | macOS 12+ |
|---|---|---|
| Python | python3.10+ (apt: `python3 python3-venv python3-pip`) | Homebrew `python@3.11`+ |
| Каталог конфигурации | `~/.config/selectel-ml-tui` | `~/Library/Application Support/selectel-ml-tui` |
| Каталог данных | `~/.local/share/selectel-ml-tui` | `~/Library/Application Support/selectel-ml-tui` |
| Права доступа | 0700/0600 (по умолчанию) | то же; доступ на чтение к `Application Support` |
| Терминалы | GNOME Terminal, Konsole, tmux | Terminal.app, iTerm2 |
| Клавиши | — | hotkeys через Ctrl/символы (r/h/s/q); Option/Command зарезервированы системой |
Требования к окружению терминала:
- `TERM` должен указывать на цветной терминал (`xterm-256color`, `tmux-256color`).
В `tmux`/`screen` задаётся автоматически; `scripts/run.sh` подставляет
`xterm-256color`, если переменная не задана.
- `LANG`/`locale` должны быть UTF-8 (`ru_RU.UTF-8`, `en_US.UTF-8`), иначе
возможны сбои отображения русского текста и граничных символов (▌▀█).
CI: GitHub Actions (`ubuntu-latest` + `macos-latest`, Python 3.11/3.12) — ruff,
mypy, pytest+coverage, doctor.
## Упаковка (однофайловый исполняемый файл)
Опционально: сборка автономного бинарника через PyInstaller.
```bash
make build # или ./scripts/build_ubuntu.sh / build_macos.sh
./dist/selectel-ml-tui doctor # проверка
```
Артефакт не зависит от установленного Python и venv (собирается на целевой ОС).
История версий: [CHANGELOG.md](CHANGELOG.md). Финальный чек-лист тестирования:
[docs/FINAL_CHECKLIST.md](docs/FINAL_CHECKLIST.md).
## Разработка
```bash
make test # pytest + coverage (порог 80%)
make lint # ruff (flake8/isort/format)
make typecheck # mypy (strict)
make format # ruff format
```
- Unit-тесты: config (приоритет env), storage, models (парсинг/форматирование),
API-клиент (httpx.MockTransport: успех, 401, 429, 500, timeout, сетевые ошибки)
- Интеграционный smoke-тест TUI: headless-запуск приложения через `App.run_test()`
- Статический анализ настроен в `pyproject.toml` (`[tool.ruff]`, `[tool.mypy]`,
`fail_under = 80`).
## FAQ и troubleshooting
**«Учётные данные не настроены» при запуске**
Выполните `selectel-ml-tui config` — мастер настройки запросит токен
(и опционально сервисного пользователя для метрик моделей). Проверка:
`selectel-ml-tui doctor``[OK] token`.
**Ошибки авторизации (401 / 403)**
- Статический токен истёк или неверен — получите новый в панели Selectel
(профиль → API-токены) и обновите через `selectel-ml-tui config`.
- IAM-доступ: сервисный пользователь должен иметь роль *reader* на нужном
ML-проекте; проверьте `project_id` и `domain_id` (аккаунт). У IAM-токена
TTL 24 ч — приложение обновляет его автоматически (за 5 минут до истечения).
**В дашборде нет метрик по моделям (Input/Output/Cache отсутствуют)**
Gateway-данные (токены по моделям, каталог моделей) требуют IAM-токена
сервисного пользователя. Если сервисный пользователь не создан, доступна
только стоимость (billing) — на дашборде выводится пояснение
«Токены и модели — только через IAM». Создать сервисного пользователя:
my.selectel.ru → IAM → Сервисные пользователи (с областью доступа на нужный
проект), затем `selectel-ml-tui config`.
**PermissionError при запуске (`credentials.json` не читается)**
Файлы конфигурации должны принадлежать текущему пользователю (права 0600).
Если запускать приложение от `root`/`sudo`, файлы создаются с владельцем root,
и обычный запуск падает. Исправление (macOS/Linux):
`sudo chown -R $USER ~/Library/Application\ Support/selectel-ml-tui`
(на Linux путь `~/.config/selectel-ml-tui`). Не запускайте приложение от root.
**Ошибка 422 при запросе данных**
API принимает только полные ISO-таймстампы (`YYYY-MM-DDTHH:MM:SS.000`).
Приложение формирует их самостоятельно; если ошибка повторяется — проверьте
часовой пояс (`doctor``LANG`/`locale`).
**«Краказябры»/битые символы в терминале**
`LANG`/`locale` должны быть UTF-8 (`ru_RU.UTF-8`, `en_US.UTF-8`), `TERM`
цветной (`xterm-256color`). Запуск через `./scripts/run.sh run` подставит
значения автоматически (полезно в tmux/ssh).
**Офлайн-режим**
При недоступности API в заголовке появляется `offline`, а дашборд показывает
последние снимки из SQLite-кэша. Данные обновятся автоматически при
восстановлении сети (клавиша `r` — вручную).
**«Нет данных для графика» в истории**
Кэш пуст — данные появляются после первого успешного обновления (каждая
загрузка сохраняет точку за день). Очистить кэш можно в экране «Настройки»
или через `export` (не очищает).