Skip to content

Latest commit

 

History

141 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RARUS Echo PHP SDK

Lint Tests License

PHP SDK для сервиса транскрибации RARUS Echo с использованием стандартов PSR и компонентов Symfony.

Статус проекта

beta - SDK покрывает текущую версию API.

Возможности

  • Асинхронная транскрибация аудио и видео файлов
  • Поддержка 13 языков и автоопределения языка
  • Различные типы транскрибации (обычная, с метками времени, с диаризацией)
  • PSR-совместимость (PSR-3, PSR-7, PSR-17, PSR-18)
  • Автоматическое обнаружение HTTP клиента (php-http/discovery)

Требования

  • PHP 8.4 или 8.5
  • Composer 2.x
  • Расширения: json, curl, mbstring, fileinfo

Установка

composer require mesilov/rarus-echo-php-sdk:^0.4

Быстрый старт

CLI через Docker image

Самый короткий happy-path не требует локальной установки PHP-пакета: запустите CLI из готового Docker image. Docker использует локально закешированный tag, если он уже загружен; добавьте --pull=always к docker run, если нужно принудительно получить актуальный опубликованный image.

docker run --rm ghcr.io/mesilov/rarus-echo-php-sdk:cli

Image использует rarus-echo как entrypoint, поэтому команды передаются сразу после имени image:

docker run --rm \
  -e RARUS_ECHO_API_KEY=your-api-key-uuid \
  -e RARUS_ECHO_USER_ID=your-user-id-uuid \
  ghcr.io/mesilov/rarus-echo-php-sdk:cli queue --json

docker run --rm \
  -e RARUS_ECHO_API_KEY=your-api-key-uuid \
  -e RARUS_ECHO_USER_ID=your-user-id-uuid \
  -v "$PWD/audio.ogg:/audio.ogg:ro" \
  ghcr.io/mesilov/rarus-echo-php-sdk:cli submit /audio.ogg \
    --task-type=diarization \
    --language=ru \
    --speakers-correction \
    --timestamps-extended \
    --wait \
    --json

docker run --rm \
  --env-file .env.local \
  -v "$PWD/audio.ogg:/audio.ogg:ro" \
  ghcr.io/mesilov/rarus-echo-php-sdk:cli submit /audio.ogg \
    --language=ru \
    --wait \
    --raw-result > transcript.txt

GitHub Actions собирает image для linux/amd64 и linux/arm64, проверяет сборку в pull request и публикует ghcr.io/mesilov/rarus-echo-php-sdk:cli при изменениях в dev, main или ручном запуске workflow.

Image собирается на официальной runtime-базе php:8.4-cli-alpine. По сравнению с прежней базой php:8.4-cli-bookworm это уменьшает опубликованный image примерно с 769MB до ~179MB по docker images и примерно со ~180MB до ~46MB по сжатому pull size. Поведение rarus-echo, расширения curl/fileinfo/mbstring, PHP-лимиты для локальных аудио-smoke и multi-arch публикация сохранены.

PHP SDK

<?php

declare(strict_types=1);

use Rarus\Echo\Services\ServiceFactory;
use Rarus\Echo\Core\Credentials;
use Rarus\Echo\Enum\Language;
use Rarus\Echo\Enum\TaskType;
use Rarus\Echo\Services\Transcription\Request\TranscriptionOptions;

// Создание credentials
$credentials = Credentials::fromString(
    apiKey: 'your-api-key-uuid',
    userId: 'your-user-id-uuid'
);

// Инициализация SDK
$factory = new ServiceFactory($credentials);

// Настройка опций транскрибации
$options = TranscriptionOptions::create()
    ->withTaskType(TaskType::DIARIZATION)  // С разбиением по говорящим
    ->withLanguage(Language::RU)            // Русский язык
    ->withCensor(true)                      // С цензурой
    ->build();

// Отправка файла на транскрибацию
$result = $factory->getTranscriptionService()->submit(
    files: ['/path/to/audio.mp3'],
    transcriptionOptions: $options
);

$fileIds = $result->getFileIds();
$fileId = $fileIds[0]; // Uuid объект
echo "Файл отправлен: {$fileId->toRfc4122()}\n";

// Проверка статуса
$status = $factory->getStatusService()->getByFileId($fileId);
echo "Статус: {$status->transcriptionStatus->value}\n";

// Получение результата после завершения
if ($status->isSuccessful()) {
    $transcript = $factory->getTranscriptionService()->getByFileId($fileId);
    echo "Результат:\n{$transcript->result}\n";
}

С обработкой ошибок

<?php

declare(strict_types=1);

use Rarus\Echo\Exception\FileException;
use Rarus\Echo\Exception\ValidationException;
use Rarus\Echo\Exception\AuthenticationException;
use Rarus\Echo\Exception\ApiException;

try {
    $result = $factory->getTranscriptionService()->submit($files, $options);
} catch (FileException $e) {
    // Ошибка файла (не найден, не читается, неверный формат)
    echo "Ошибка файла: {$e->getMessage()}\n";
} catch (ValidationException $e) {
    // Ошибка валидации (422)
    echo "Ошибка валидации: {$e->getMessage()}\n";
} catch (AuthenticationException $e) {
    // Ошибка аутентификации (401)
    echo "Ошибка аутентификации: {$e->getMessage()}\n";
} catch (ApiException $e) {
    // Общая ошибка API
    echo "Ошибка API: {$e->getMessage()}\n";
}

CLI

После установки через Composer доступен исполняемый файл:

vendor/bin/rarus-echo --help

CLI использует те же credentials, что и SDK:

export RARUS_ECHO_API_KEY=your-api-key-uuid
export RARUS_ECHO_USER_ID=your-user-id-uuid
export RARUS_ECHO_BASE_URL=https://production-ai-ui-api.ai.rarus-cloud.ru # опционально

Если в текущей рабочей директории есть .env, CLI загрузит значения из него перед выполнением сервисной команды.

Таймаут HTTP-клиента для больших файлов

При отправке больших файлов автоматически подобранный HTTP-клиент раньше обрывал загрузку с ошибкой Idle timeout reached ... (по умолчанию PHP default_socket_timeout ~60 с). Теперь SDK создаёт HTTP-клиент с idle timeout 600 секунд. Значение можно переопределить переменной окружения (положительное целое число секунд):

export RARUS_ECHO_HTTP_TIMEOUT=1200 # опционально, по умолчанию 600

В коде SDK то же самое задаётся через ApiClientFactory::withHttpTimeout(); при передаче собственного PSR-18 клиента через withHttpClient() таймаут становится ответственностью вызывающего.

Команды

vendor/bin/rarus-echo queue
vendor/bin/rarus-echo status 11111111-1111-1111-1111-111111111111
vendor/bin/rarus-echo transcript 11111111-1111-1111-1111-111111111111
vendor/bin/rarus-echo submit /path/to/audio.ogg --task-type=diarization --language=ru --timestamps-extended
vendor/bin/rarus-echo submit /path/to/audio.ogg --language=ru --wait

Для автоматизации добавьте --json:

vendor/bin/rarus-echo queue --json
vendor/bin/rarus-echo submit /path/to/audio.ogg --json
vendor/bin/rarus-echo submit /path/to/audio.ogg --wait --json

submit --wait после отправки файла опрашивает результат транскрибации до терминального статуса. Финальный JSON содержит file_ids и results, а прогресс вида submitted: ..., polling: ... и completed: ... пишется в stderr, поэтому stdout остается безопасным для jq, редиректа и пайпов.

При SIGINT (Ctrl+C) или SIGTERM во время долгого ожидания команда пишет в stderr сообщение о завершении по сигналу и возвращает ненулевой signal-aware код выхода.

Для сырого текста одного файла:

vendor/bin/rarus-echo submit /path/to/audio.ogg --language=ru --wait --raw-result > transcript.txt
vendor/bin/rarus-echo submit /path/to/audio.ogg --language=ru --wait --output=transcript.txt

Интервал и общий лимит ожидания задаются в секундах:

vendor/bin/rarus-echo submit /path/to/audio.ogg --wait --poll-interval=10 --timeout=3600 --json

Полный список ключей всех команд — в разделе Справочник команд и опций. Основной результат пишется в stdout, прогресс и ошибки — в stderr, успешные команды завершаются с кодом 0.

Справочник команд и опций

Ниже перечислены все ключи CLI. Каноническим источником является структура команд в src/Infrastructure/Console/Command/.

Глобальные опции

Доступны для всех команд RARUS Echo (queue, submit, status, transcript):

Опция Значение Описание
--json флаг Вывести результат команды в формате JSON.
-h, --help флаг Показать справку по команде.
--silent флаг Полностью подавить вывод (никаких сообщений). Доступна только с Symfony Console ≥ 7.2.
-q, --quiet флаг Выводить только ошибки, остальной вывод подавляется.
-v, -vv, -vvv, --verbose флаг Уровень детализации вывода (1 — обычный, 2 — подробный, 3 — отладка).
-V, --version флаг Показать версию приложения.
--ansi, --no-ansi флаг Принудительно включить/выключить ANSI-раскраску.
-n, --no-interaction флаг Не задавать интерактивных вопросов.

--json добавляется командами RARUS Echo и недоступна во встроенных командах Symfony (list, help). Остальные ключи — глобальные опции Symfony Console и доступны во всех командах приложения. --silent появился в Symfony Console 7.2; в опубликованном Docker image он есть, но при установке SDK как библиотеки с более старой разрешённой версией symfony/console (^6.4 || ^7.0) этого ключа не будет.

queue

Показать агрегированную информацию по очереди транскрибации. Аргументов и собственных опций, кроме глобальных, нет.

vendor/bin/rarus-echo queue [--json]

submit

Отправить один или несколько файлов на транскрибацию.

vendor/bin/rarus-echo submit [опции] [--] <files>...

Аргумент:

Аргумент Обязательный Несколько Описание
files да да Пути к файлам для отправки.

Опции (помимо глобальных):

Опция Значение По умолчанию Описание
--task-type обязательно transcription Тип задачи: transcription, timestamps, diarization, raw_transcription.
--language обязательно auto Код языка: auto, ru, en, de, fr, es, pt, hy, ja, tr, ar, zh, he, vi.
--censor флаг Включить цензуру.
--speakers-correction флаг Включить коррекцию говорящих.
--timestamps-extended флаг Включить расширенные таймкоды для диаризации.
--no-store-file флаг Не хранить отправленные файлы после обработки.
--low-priority флаг Отправить с низким приоритетом обработки.
--request-source обязательно Необязательный заголовок источника запроса.
--wait флаг Опрашивать результат до терминального статуса.
--poll-interval обязательно 30 Интервал опроса в секундах при --wait.
--timeout обязательно 7200 Максимальное время ожидания в секундах при --wait.
--raw-result флаг С --wait: писать в stdout только сам transcript (ровно один файл).
--output обязательно С --wait: записать transcript в файл (ровно один файл).

--raw-result и --output требуют --wait и поддерживают только один отправляемый файл.

status

Показать статус транскрибации одного файла.

vendor/bin/rarus-echo status [--json] [--] <file-id>

Аргумент:

Аргумент Обязательный Несколько Описание
file-id да нет UUID файла RARUS Echo.

transcript

Показать результат транскрибации одного файла.

vendor/bin/rarus-echo transcript [--json] [--] <file-id>

Аргумент:

Аргумент Обязательный Несколько Описание
file-id да нет UUID файла RARUS Echo.

Agent skill для транскрибации

В репозитории есть skills-only plugin rarus-echo-transcription для Claude Code и Codex-compatible hosts. Он описывает безопасный workflow поверх существующего CLI: проверить очередь, отправить один или несколько локальных аудиофайлов, получить file_id, проверить статус, дождаться результата через submit --wait и забрать transcript без вывода credentials.

Исходники plugin:

.agent-plugins/rarus-echo-transcription/

Claude Code может загрузить plugin напрямую из checkout на одну сессию:

claude --plugin-dir ./.agent-plugins/rarus-echo-transcription

Или поставить через repo-local marketplace из корня репозитория:

claude plugin marketplace add ./ --scope user
claude plugin install rarus-echo-transcription@rarus-echo-plugins

После установки в Claude Code namespaced invocation выглядит так:

/rarus-echo-transcription:transcribe downloads/audio.ogg --language=ru --task-type=diarization --speakers-correction

Repo-local marketplace files:

.claude-plugin/marketplace.json
.agents/plugins/marketplace.json

Codex-compatible hosts читают общий skill из skills/transcribe/SKILL.md; точный синтаксис invocation зависит от host и использует имя skill, например:

codex plugin marketplace add .
codex plugin add rarus-echo-transcription@rarus-echo-plugins
$transcribe downloads/audio.ogg --language=ru --task-type=diarization --speakers-correction

CLI reference для skill генерируется из structured metadata текущего CLI и проверяется на drift. Проверка фиксирует только project-owned команды и опции, без framework-provided Symfony options:

.agent-plugins/rarus-echo-transcription/scripts/update-cli-reference.sh
make lint-agent-plugins

Примеры PHP SDK

Очередь транскрибации

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Rarus\Echo\Services\ServiceFactory;

$factory = ServiceFactory::fromEnvironment();
$queue = $factory->getQueueService()->getQueueInfo();

printf(
    "В очереди: %d файлов, %d MB, %d минут\n",
    $queue->filesCount,
    $queue->filesSize,
    $queue->filesDuration
);

Отправка файла и проверка статуса

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Rarus\Echo\Enum\Language;
use Rarus\Echo\Enum\TaskType;
use Rarus\Echo\Services\ServiceFactory;
use Rarus\Echo\Services\Transcription\Request\TranscriptionOptions;

$factory = ServiceFactory::fromEnvironment();

$options = TranscriptionOptions::create()
    ->withTaskType(TaskType::DIARIZATION)
    ->withLanguage(Language::RU)
    ->withSpeakersCorrection()
    ->withTimestampsExtended()
    ->build();

$submitResult = $factory->getTranscriptionService()->submit(
    files: ['/path/to/audio.ogg'],
    transcriptionOptions: $options
);

$fileId = $submitResult->getFileIds()[0];
$status = $factory->getStatusService()->getByFileId($fileId);

printf(
    "file_id=%s status=%s\n",
    $fileId->toRfc4122(),
    $status->transcriptionStatus->value
);

Проверка списка статусов

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Rarus\Echo\Core\Pagination;
use Rarus\Echo\Services\ServiceFactory;
use Symfony\Component\Uid\Uuid;

$factory = ServiceFactory::fromEnvironment();
$fileIds = [
    Uuid::fromString('11111111-1111-1111-1111-111111111111'),
    Uuid::fromString('22222222-2222-2222-2222-222222222222'),
];

$statusList = $factory->getStatusService()->getList(
    fileIds: $fileIds,
    pagination: new Pagination(page: 1, perPage: 10)
);

foreach ($statusList->getResults() as $status) {
    printf(
        "file_id=%s status=%s\n",
        $status->fileId->toRfc4122(),
        $status->transcriptionStatus->value
    );
}

printf(
    "page=%d per_page=%d total_pages=%d\n",
    $statusList->pagination->page,
    $statusList->pagination->perPage,
    $statusList->pagination->total
);

Получение результата

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Rarus\Echo\Services\ServiceFactory;
use Symfony\Component\Uid\Uuid;

$factory = ServiceFactory::fromEnvironment();
$fileId = Uuid::fromString('11111111-1111-1111-1111-111111111111');

$transcript = $factory->getTranscriptionService()->getByFileId($fileId);

if ($transcript->isSuccessful()) {
    echo $transcript->result ?? '';
}

Поддерживаемые возможности API

Типы транскрибации

  • transcription - обычная транскрипция
  • timestamps - с метками времени
  • diarization - с разбиением по говорящим
  • raw_transcription - сырой текст

Для диаризации с расширенными таймкодами используйте task-type=diarization вместе с опцией timestamps-extended=1: в SDK это withTimestampsExtended(), в CLI - --timestamps-extended.

Языки

ru, en, de, fr, es, pt, hy, ja, tr, ar, zh, he, vi, auto

Статусы

  • waiting - ожидает в очереди
  • processing - обрабатывается
  • success - завершено успешно
  • failure - ошибка

Документация

Разработка

Требования для разработки

  • Docker & Docker Compose
  • Make
  • Node.js 20.19+ или 24+
  • OpenSpec CLI 1.3.1 для OpenSpec workflow:
    npm install -g @fission-ai/openspec@1.3.1
    openspec --version

Первоначальная настройка

make docker-init      # Инициализация Docker окружения и установка зависимостей
make docker-up        # Запуск контейнеров
make dev-php-bash     # Войти в контейнер

Основные команды

make lint-all         # Запуск всех линтеров
make lint-openspec    # Проверка OpenSpec артефактов
make lint-agent-plugins # Проверка agent plugin и CLI reference
make lint-php         # Запуск PHP-линтеров
make lint-cs-fixer-fix # Исправление стиля кода
make lint-phpstan     # Статический анализ
make test-unit        # Юнит-тесты
make test-integration # Интеграционные тесты
make test-all         # Все тесты
make ci               # Полный CI pipeline локально

Полный список команд: make help

Интеграционные тесты

Integration tests делают реальные API-запросы и загружают короткие аудиофайлы из tests/Assets/ru/. Для локального запуска добавьте credentials в .env.local; файл уже игнорируется Git:

RARUS_ECHO_API_KEY=your-api-key-uuid
RARUS_ECHO_USER_ID=your-user-id-uuid
RARUS_ECHO_BASE_URL=https://production-ai-ui-api.ai.rarus-cloud.ru

Если credentials не заданы или в .env остались placeholder-значения, integration tests будут пропущены.

make test-integration
make test-integration-core
make test-integration-queue
make test-integration-status
make test-integration-transcription

Workflow поддержки

Поддержка проекта идет от GitHub issue к Pull Request в ветку dev.

  1. Откройте или выберите issue и зафиксируйте ожидаемый результат.
  2. Создайте ветку от dev: feature/<issue>-<slug>, bugfix/<issue>-<slug> или docs/<issue>-<slug>.
  3. Для нетривиальных изменений публичного API, поведения SDK, архитектуры, CI или процесса поддержки создайте OpenSpec change в openspec/changes/<change-id>/.
  4. Для опечаток, обновлений зависимостей и небольших документационных правок OpenSpec можно не использовать, если отдельная спецификация не добавляет ясности.
  5. Перед PR запустите локальную проверку и откройте Pull Request в dev.
  6. Считайте issue завершенным только после зеленого CI в Pull Request.

OpenSpec change обычно содержит:

  • proposal.md - зачем нужно изменение и что меняется;
  • design.md - технические решения, если они нужны;
  • specs/<capability>/spec.md - требования и сценарии;
  • tasks.md - чеклист реализации.

Основные команды для OpenSpec:

openspec list
openspec list --specs
make lint-openspec

OpenSpec CLI генерирует repo-local commands/skills для Claude Code и Codex. После обновления CLI синхронизируйте эти файлы командой:

openspec update --force

После merge связанного PR завершенный change архивируется командой:

openspec archive <change-id> --yes

Для agent-assisted поддержки используйте repo-local skill. Claude Code и Codex читают один общий русский skill через свои стандартные entrypoint-пути:

  • Claude Code: .claude/skills/rarus-echo-maintainer/SKILL.md
  • Codex: .codex/skills/rarus-echo-maintainer/SKILL.md

Вклад в проект

Мы приветствуем вклад в развитие проекта! Пожалуйста, ознакомьтесь с CONTRIBUTING.md.

Процесс разработки

  1. Fork репозитория
  2. Создайте feature branch от dev
  3. Внесите изменения
  4. Запустите тесты и линтеры: make ci
  5. Создайте Pull Request в dev

Лицензия

MIT License. См. LICENSE для деталей.

Поддержка

Если у вас возникли вопросы или проблемы, пожалуйста, создайте Issue.

About

Сервис транскрибации

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages