Add README.md
This commit is contained in:
@@ -0,0 +1,282 @@
|
||||
# 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` (не очищает).
|
||||
Reference in New Issue
Block a user