# 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` (не очищает).