Ранее я уже рассказывал, что при разработке api2app вдохновлялся идеей Python-библиотеки Gradio. У этой библиотеки есть очень полезный функционал: можно запустить приложение на локальном компьютере в режиме share (поделиться), тогда будет сгенерирована публичная ссылка, по которой это приложение будет доступно на любом другом компьютере через Интернет.
В этой статье пошагово опишу свой способ. Есть свои плюсы и свои минусы, но в любом случае, думаю, альтернатива не будет лишней. Для примера создам онлайн-приложение для создания транскрипций аудио с помощью проекта whisper.cpp. Делаю всё на Ubuntu, но, думаю, на Windows это повторить будет не сложно.
Установка whisper.cpp
Клонирую репозиторий и перехожу в папку:
git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cppДелаю сборку:
cmake -B build
cmake --build build --config ReleaseСкачиваю модель medium (~1.5 GB):
bash ./models/download-ggml-model.sh mediumЕсли скачивание не сработало, можно попробовать в bash-скрипте заменить домен "huggingface.co" на "hf-mirror.com".
Проверяю работу:
./build/bin/whisper-cli --model ./models/ggml-medium.bin \
--language en \
--output-txt \
--file samples/jfk.wavВ папке "samples" должен появиться файл "jfk.wav.txt" с транскрипцией.
Создание обработчика запросов
Сначала нужно создать задачу в Менеджере задач. Открываю приложение: https://api2app.org/ru/apps/shared/666e778a-f6a5-11ef-861d-525400f8f94f

Заполняю поля, нажимаю кнопку "Создать задачу" - получаю идентификатор задачи и API-ключ.
Данное приложение использует API, исходный код которого можно найти здесь:
https://github.com/andchir/queue-manager
Клонирую репозиторий и перехожу в папку:
git clone https://github.com/andchir/queue-manager.git
cd queue-managerСоздаю виртуальное окружение Python и активирую его:
python3.12 -m venv venv
source venv/bin/activateЛокально мне не нужно устанавливать полностью это приложение, поэтому я устанавливаю только минимальное число зависимостей:
pip install -r requirements-min.txtСоздаю .env файл, в котором будут мои локальные настройки:
cp .env-dest .envВ этом файле мне нужно изменить домен API менеджера очередей:
APP_SERVER_NAME=queue.api2app.orgКлонирую дополнительный репозиторий с обработчиками запросов. Я их назвал воркерами (workers):
git clone https://github.com/andchir/api2app-workers.gitТут уже есть готовый воркер для whisper.cpp, но я опишу немного подробнее как я его создал. Создаю новый файл "whisper-cpp.py" в папке "api2app-workers" пока с таким содержанием:
import os
import sys
import subprocess
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.queue_manager import polling_queue, upload_queue_files, send_queue_error
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def processing(queue_item):
upload_dir_path = os.path.join(ROOT_DIR, 'uploads', 'whisper')
# Загрузка всех файлов в локальную папку
image_file_path, audio_file_path, video_file_path, image_file_path2 = upload_queue_files(queue_item, upload_dir_path)
print('Получена новая задача', queue_item['uuid'])
print('Аудио файл:', audio_file_path)
# Отправка ошибки выполнения
send_queue_error(queue_item['uuid'], 'Error.')
if __name__ == '__main__':
# Опрос на появление новых задач
polling_queue('ea474c9a-c631-4bac-9141-ba26b0ff56c5', processing)
Я думаю из этого кода вы поняли, что функция polling_queue делает периодические запросы к серверу, используя ID задачи, который я получил ранее. Если задача пришла, запускается функция processing.
Теперь мне нужно протестировать работу этого воркера. Я отправлю запрос для создания новой задачи. Нужно отправить аудио-файл, используя ID задачи и API ключ, которые я получил ранее на сайте api2app.org. Позже я создам графический интерфейс для этого, но пока могу отправить запрос с помощью curl:
curl -X POST \
-F "audio_file=@/path/to/audio.mp3" \
-F 'data={"language": "en", "output_type": "txt"}' \
-H "Accept: application/json" \
-H "API-KEY: 47688355-a431-4bc3-8913-35115b2da36c" \
"https://queue.api2app.org/queue/ea474c9a-c631-4bac-9141-ba26b0ff56c5"Запущу воркер:
python api2app-workers/whisper-cpp.pyЕсли всё в порядке, должен быть примерно такой вывод:
Waiting for a task...
Получена новая задача 1ab642f7-0c2c-4ff1-868a-a5d38c57d480
Аудио файл:
/path/to/queue-manager/uploads/whisper/962ff1aa-f6ec-11ef-be86-33f5f54d4fd6.mp3Полный код воркера с комментариями можно посмотреть здесь:
https://github.com/andchir/api2app-workers/blob/main/whisper-cpp.py
Этот воркер запускает "whisper-cli" из проекта whisper.cpp, который в свою очередь создает транскрипцию аудио-файла. Далее с помощью функции send_queue_result_dict результат отправляется менеджеру задач.
Скрипт для управления воркерами (только Linux)
Для более удобного управления воркерами есть bash-скрипт "worker-manager.sh". Для его использования нужно установить права на запуск:
chmod +x api2app-workers/worker-manager.shЕсли открыть его код, в самом начале можно увидеть настройки:
WORKERS=('api2app-workers/whisper-cpp.py')
WORKERS_NUM=(1)
QUEUE_SIZE_URLS=('https://queue.api2app.org/queue_size/ea474c9a-c631-4bac-9141-ba26b0ff56c5')здесь
WORKERS - массив воркеров, которые нужно запускать (разделяются пробелом).
WORKERS_NUM - массив с числами, сколько нужно запустить копий воркеров (будут выполняться параллельно).
QUEUE_SIZE_URLS - массив URL для проверки размера очереди.
Команды для использования:
./api2app-workers/worker-manager.sh status
./api2app-workers/worker-manager.sh start
./api2app-workers/worker-manager.sh stopВывод статуса примерно такой:
-----------------------------------------
STATUS
-----------------------------------------
- api2app-workers/whisper-cpp.py [1]
Queue size: 1Создание графического интерфейса для приложения
Теперь создам графический интерфейс для приложения, которое будет создавать транскрипции аудио файлов.
Иду на сайт api2app.org. Сначала нужно создать конфигурацию API (по примеру с кодом curl, который был выше). Иду в раздел "API", затем в подраздел "Мои API", нажимаю кнопку "Импортировать". Вставляю свою curl-команду и нажимаю кнопку "Импортировать".

Данные успешно импортировались. Теперь нужно только немного подправить и протестировать:

Нажимаю кнопку "Тест", вижу ответ сервера, сохраняю.
Возвращаюсь в подраздел "Мои API", нажимаю кнопку "Поделиться" -> "Сделать публичным" -> "Скрыть".

API добавления задания отдает нам идентификатор задания и URL для получения результата, поэтому нужно ещё создать конфигурацию API для этого (авторизация здесь не нужна):

Так же, как с предыдущим, делаю это API публичным и скрытым.
Приступаю к созданию графического интерфейса. Перехожу в раздел "Приложения" -> "Мои приложения", нажимаю кнопку "Создать приложение".
Сначала нужно добавить поле для загрузки аудио-файлов:

После добавления поля нажимаю кнопку "Параметры". В поле "Принимать типы файлов" ввожу "audio/*" для фильтрации файлов по типу при выборе с устройства.

Далее добавляю поле с типом "Выбор (select)" для выбора языка. Язык может быть определен автоматически, поэтому по умолчанию будет значение "auto":

Теперь нужно добавить поле для выбора формата транскрипции (txt, json, srt и т.д.):

Добавляю кнопку с текстом "Создать транскрипцию". На этом шаге у меня получился такой интерфейс в редакторе:

API возвращает идентификатор задачи, по которому потом можно получить результат, для этого мне нужно создать скрытое поле и элемент "Прогресс операции".
У скрытого поля в параметрах нужно обязательно включить опцию "Хранить значение поля". Для элемента "Прогресс операции" нужно указать среднее время выполнения операции - параметр "Время выполнения операции (в секундах)", остальные значения можно не менять.

Добавляю элемент "Текст", в нём будет выводиться результат. Устанавливаю такие параметры:

В параметрах первого блока включаю опцию "Очищать после отправки".

Результат у меня будет появляться во второй колонке. Также я добавил ещё текстовую информацию:

Теперь нужно связать все поля с ранее созданными конфигурациями API.
Поле файла служит для ввода данных (выбора файла), поэтому нужно указать Действие ввода - какое поле API использовать. Нажимаю кнопку "Действие ввода" у этого поля:

Нахожу конфигурацию API для добавления задания, которое создал ранее, выбираю поле "audio_file", сохраняю.

Для выбора языка тоже выбираю это API в окне "Действие ввода" и поле "data.language" (поле из JSON).

То же самое делаю для поля "Формат транскрипции", только выбираю поле "data.output_type".
Действие ввода для кнопки только одно - "Отправить". Выбираю его и сохраняю.

Теперь нужно установить действие вывода для текстового элемента. Здесь уже нужно использовать API получения результата. Выбираю поле "result_data.result":

Для скрытого поля нудно выбрать действие вывода - откуда поле получает значение. Выбираю API добавления задания и поле "uuid".

Действие ввода - получение результата. Значение используется в URL запроса:

Для получения результата я не добавлял кнопку, поэтому запрос будет отправлен автоматически после того как скрытое поле получит значение (ID задания).
Последним добавлю действие вывода для элемента "Прогресс операции":


Для элемента нужны все данные, которые отдаёт API, поэтому выбираю поле "value".
На этом создание графического интерфейса окончено. Результат можно увидеть и протестировать по ссылке:
https://api2app.org/ru/apps/shared/dc6481f4-f778-11ef-9fb8-525400f8f94f

Таким образом с минимальным программированием можно создавать более сложные приложения. Пока на сайте нет возможности монетизировать такие приложения (планируется), но есть возможность скачивания всех файлов приложения. Кроме того, Вы можете давать ссылку ��а приложение за плату.
Предупреждение:
Всё описанное Вы можете повторить на свой страх и риск, безопасность пока под вопросом.
