mesilov / rarus-echo-php-sdk
PHP SDK for Rarus Echo Transcription Service
Requires
- php: ^8.4||^8.5
- ext-curl: *
- ext-fileinfo: *
- ext-json: *
- ext-mbstring: *
- nesbot/carbon: ^2.72 || ^3.0
- nyholm/psr7: ^1.8
- php-http/discovery: ^1.19
- php-http/httplug: ^2.4
- php-http/message: ^1.16
- php-http/message-factory: ^1.1
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.0 || ^2.0
- psr/log: ^3.0
- symfony/console: ^6.4 || ^7.0 || 8.0.*
- symfony/dotenv: ^6 || ^7||^8.0
- symfony/filesystem: ^6.4 || ^7.0||^8.0
- symfony/http-client: ^6.4 || ^7.0||^8.0
- symfony/mime: ^6.4 || ^7.0||^8.0
- symfony/property-access: ^6.4 || ^7.0||^8.0
- symfony/property-info: ^6.4 || ^7.0||^8.0
- symfony/serializer: ^6.4 || ^7.0||^8.0
- symfony/uid: ^7.0 ||^8.0
- symfony/validator: ^6.4 || ^7.0||^8.0
Requires (Dev)
- fakerphp/faker: ^1.23
- friendsofphp/php-cs-fixer: ^3.48
- monolog/monolog: ^3.5
- php-http/mock-client: ^1.6
- phpstan/phpstan: ^1.10
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-symfony: ^1.3
- phpunit/phpunit: ^10.5 || ^11.0
- rector/rector: ^1.0
- symfony/var-dumper: ^6.4 || ^7.0|| ^8.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
- dev-dev
- dev-docs/46-align-openspec-changelog
- dev-docs/46-harden-cli-reference-generator
- dev-docs/46-cli-silent-and-lists
- dev-docs/46-cli-reference-review-fixes
- dev-docs/46-cli-option-reference
- dev-docs/34-ship-0-4-0-release
- dev-bugfix/43-http-client-timeout
- dev-docs/41-transcribe-docker-default
- dev-docs/39-plugin-install-cmd
- dev-feature/25-reduce-cli-docker-image-size
- dev-feature/29-parallel-worktree-tooling
- dev-docs/35-maintainer-release-templates
- dev-feature/26-rarus-echo-transcription-skill
- dev-docs/31-readme-ci-badges
- dev-docs/27-readme-pull-default
- dev-feature/24-submit-wait
- dev-feature/22-diarization-extended-timestamps
- dev-bugfix/19-cli-docker-image-psr-discovery
- dev-feature/12-ship-0-3-0-release
- dev-feature/2-local-integration-quick-start
- dev-feature/10-docker-image-build-pipeline
- dev-feature/11-cli-app
- dev-feature/9-maintainer-workflow-openspec
- dev-claude/split-github-workflow-y6vPO
- dev-bugfix/2-minor-fixes
- dev-claude/sdk-psr-symfony-012hqdwiZPuLyYMPviKixJw7
This package is auto-updated.
Last update: 2026-09-03 06:37:19 UTC
README
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- ошибка
Документация
- OpenAPI спецификация - официальная API документация
Разработка
Требования для разработки
- 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.
- Откройте или выберите issue и зафиксируйте ожидаемый результат.
- Создайте ветку от
dev:feature/<issue>-<slug>,bugfix/<issue>-<slug>илиdocs/<issue>-<slug>. - Для нетривиальных изменений публичного API, поведения SDK, архитектуры, CI или процесса поддержки создайте OpenSpec change в
openspec/changes/<change-id>/. - Для опечаток, обновлений зависимостей и небольших документационных правок OpenSpec можно не использовать, если отдельная спецификация не добавляет ясности.
- Перед PR запустите локальную проверку и откройте Pull Request в
dev. - Считайте 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.
Процесс разработки
- Fork репозитория
- Создайте feature branch от
dev - Внесите изменения
- Запустите тесты и линтеры:
make ci - Создайте Pull Request в
dev
Лицензия
MIT License. См. LICENSE для деталей.
Поддержка
Если у вас возникли вопросы или проблемы, пожалуйста, создайте Issue.