REST API для работы с переводами Библии, озвучкой и аномалиями.
API использует двухуровневую систему авторизации:
- Статичный API ключ (
X-API-Key) - для публичных GET эндпоинтов - JWT токены (
Authorization: Bearer) - для административных операций (24 часа)
# Публичные эндпоинты
curl -H "X-API-Key: bible-api-key-2024" http://localhost/translations
# Административные эндпоинты
TOKEN=$(curl -X POST http://localhost/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}' | jq -r '.access_token')
curl -H "Authorization: Bearer $TOKEN" http://localhost/voices/1/anomalies📖 Документация: docs/AUTHENTICATION.md
🧪 Тестирование: python tests/test_auth.py
detected- ошибка выявлена автоматически (по умолчанию)confirmed- ошибка подтверждена при проверкеdisproved- ошибка опровергнута, не подтверждена проверкойcorrected- выполнена ручная коррекцияalready_resolved- уже исправлена ранее (только для системного использования)
Получение списка аномалий для голоса с возможностью фильтрации по статусу.
Параметры:
voice_code(path) - код голосаstatus(query, optional) - фильтр по статусу аномалии
Пример запроса:
GET /voices/1/anomalies?status=detected
Обновление статуса аномалии с возможностью корректировки временных меток.
Параметры:
anomaly_code(path) - код аномалии
Тело запроса:
{
"status": "detected|confirmed|disproved|corrected",
"begin": 10.5, // только для статуса "corrected"
"end": 12.0 // только для статуса "corrected"
}Правила валидации:
- Для статуса
correctedполяbeginиendобязательны - Для других статусов поля
beginиendнедопустимы beginдолжно быть меньшеend- Статус
already_resolvedнельзя устанавливать вручную - Нельзя изменить статус с
correctedнаconfirmed
Примеры запросов:
- Подтверждение аномалии:
{
"status": "confirmed"
}- Опровержение аномалии:
{
"status": "disproved"
}- Коррекция с новыми временными метками:
{
"status": "corrected",
"begin": 10.5,
"end": 12.0
}Создание новой аномалии озвучки.
Тело запроса:
{
"voice": 1,
"translation": 1,
"book_number": 1,
"chapter_number": 1,
"verse_number": 1,
"word": "слово", // опционально
"position_in_verse": 5, // опционально
"position_from_end": 3, // опционально
"duration": 1.5, // опционально
"speed": 2.0, // опционально
"ratio": 1.8, // обязательно, должно быть > 0
"anomaly_type": "manual", // по умолчанию "manual"
"status": "detected" // по умолчанию "detected"
}Типы аномалий:
fast- быстрое произношениеslow- медленное произношениеlong- длинная паузаshort- короткая паузаmanual- добавлена вручную (по умолчанию)
Правила валидации:
- Поле
ratioобязательно и должно быть положительным числом - Поля
voice,translation,book_number,chapter_number,verse_numberобязательны - Система проверяет существование указанного голоса, перевода и стиха
- Тип аномалии должен быть одним из допустимых значений
Пример успешного ответа:
{
"code": 123,
"voice": 1,
"translation": 1,
"book_number": 1,
"chapter_number": 1,
"verse_number": 1,
"word": "слово",
"position_in_verse": 5,
"position_from_end": 3,
"duration": 1.5,
"speed": 2.0,
"ratio": 1.8,
"anomaly_type": "manual",
"status": "detected",
"verse_start_time": 10.0,
"verse_end_time": 12.0,
"verse_text": "Текст стиха"
}При обновлении статуса аномалии система автоматически управляет таблицей voice_manual_fixes:
- Создается или обновляется запись в
voice_manual_fixes - Для
DISPROVED: используются оригинальные временные метки изvoice_alignments - Для
CORRECTED: используются переданные в запросеbeginиend
- Если есть запись в
voice_manual_fixesс совпадающими временными метками - она удаляется - Если временные метки не совпадают - возвращается ошибка 422
- Если записи нет - никаких действий не выполняется
Это позволяет отслеживать стихи, которые были вручную проверены, чтобы при перепарсинге не создавать для них новые аномалии.
Метод получения отрывков Библии с временными метками озвучки теперь автоматически учитывает корректировки из таблицы voice_manual_fixes.
Логика работы:
- Если для стиха есть запись в
voice_manual_fixes- используются скорректированные временные метки - Если записи нет - используются оригинальные временные метки из
voice_alignments - Реализовано через SQL COALESCE:
COALESCE(vmf.begin, a.begin)иCOALESCE(vmf.end, a.end)
Пример запроса:
GET /excerpt_with_alignment?translation=16&excerpt=jhn 3:16-17&voice=1
В ответе поля begin и end для каждого стиха будут содержать актуальные временные метки с учетом всех корректировок.
Аудио-файлы хранятся в структуре:
Где берется из БД () и заполняется плейсхолдерами по аналогии с .
Скрипт скачивания находится в и берёт активные голоса из БД:
Запуск (внутри контейнера ):
По умолчанию файлы пишутся в (обычно внутри контейнера).
# Установить основные зависимости
pip install mysql-connector-python fastapi uvicorn pydantic
# Для разработки (опционально, может потребовать Python 3.12 или ниже)
pip install pytest requests
# Полная установка (может не работать с Python 3.13)
# pip install -r requirements.txt- Создайте runtime-переменные окружения для контейнера:
cp .env.example .env-
Отредактируйте
.env(DB_, API_KEY, JWT_, ADMIN_*). ДляADMIN_PASSWORD_HASHиспользуйте формат с$$(например$$2b$$12$$...). -
Выполните миграции:
docker compose exec bible-api python3 migrate.py migrateПримечание: Миграции для рефакторинга voice_alignments уже выполнены:
- ✅ Добавлены поля
book_number,chapter_number,verse_number - ✅ Созданы индексы для оптимизации производительности
- ✅ Заполнены данные из связанных таблиц
- ✅ Обновлен код для использования новых полей
# Запуск в фоне (production mode)
docker compose up -d --build
# Проверить статус
docker compose ps
# Просмотр логов
docker logs bible-api
# Остановить
docker compose downСервер будет доступен на: http://localhost
# Запуск с override (development mode + bind mounts)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
# Остановить
docker compose -f docker-compose.yml -f docker-compose.dev.yml down# Swagger UI (Docker)
curl http://localhost/docs
# Swagger UI (локальный запуск)
curl http://localhost:8001/docs# Установить pytest если еще не установлен
pip install pytest
# ✅ Безопасно - только unit тесты (НЕ пишут в БД)
PYTHONPATH=/root/cep/bible-api/app pytest tests/ -k "not integration" -v
# ⚠️ ОПАСНО - все тесты (integration тесты ПИШУТ в БД!)
PYTHONPATH=/root/cep/bible-api/app pytest tests/ -vСистема использует собственный механизм миграций для управления схемой базы данных. Рекомендуется запускать миграции внутри Docker-контейнера.
Tip
Вместо migrate.py можно также использовать migrations/migration_manager.py, но migrate.py короче и удобнее.
# Выполнить все ожидающие миграции
docker compose exec bible-api python3 migrate.py migrate
# Создать новую миграцию
docker compose exec bible-api python3 migrate.py create "migration_name"
# Показать статус миграций
docker compose exec bible-api python3 migrate.py status
# Откатить миграцию (только отметить как не выполненную)
docker compose exec bible-api python3 migrate.py rollback "migration_file.sql"
# Отметить миграцию как выполненную без запуска
docker compose exec bible-api python3 migrate.py mark-executed "migration_file.sql"Для локального запуска (если у вас настроено окружение):
python3 migrate.py migrateПодробнее см. migrations/README.md
- docs/DEVELOPMENT.md - Docker команды, структура проекта, ключевые таблицы БД
- docs/REVERSE_PROXY_SETUP.md - схема портов, Nginx reverse proxy и маршрутизация yourdomain.com/api.yourdomain.com
- docs/SECURITY.md - таблица защиты всех эндпоинтов, примеры авторизации
- docs/TESTING.md -
⚠️ запуск тестов (ВАЖНО! integration тесты используют БД)
Аудио-файлы хранятся в структуре:
<MP3_FILES_PATH>/<translation_alias>/<voice_alias>/mp3/<book_zerofill>/<chapter_zerofill>.mp3
Где link_template берется из БД (voices.link_template) и заполняется плейсхолдерами по аналогии с /root/cep/php-parser/include.php:get_chapter_audio_url.
Скрипт скачивания: scripts/download_audio.py.
Он скачивает mp3 для всех активных голосов из БД:
voices.active = 1translations.active = 1
Запуск (внутри контейнера bible-api):
# посмотреть, что будет скачиваться (без скачивания)
docker exec bible-api python3 /code/scripts/download_audio.py --dry-run
# скачать всё (может быть десятки ГБ)
docker exec bible-api python3 /code/scripts/download_audio.py --yes --max-workers 8
# скачать только один перевод/голос
docker exec bible-api python3 /code/scripts/download_audio.py --yes --translation-alias syn --voice-alias bondarenko
# NPU (npu/npu_uk): источник open.bible, там аудио в ZIP-архивах по книгам
docker exec bible-api python3 /code/scripts/download_audio.py --yes --translation-alias npu --voice-alias npu_ukПо умолчанию файлы пишутся в MP3_FILES_PATH (обычно /audio внутри контейнера).
docker-compose.yml uses host bind mounts and expects these variables in .env:
AUDIO_DIR(required): host directory with downloaded mp3 files. It will be mounted into the API container as/audio.SITE_DIR(optional): host directory with static files for the root website. Used only by thewebservice. Defaults to./site(inside this repo).
If you do not need the static site, you can run only the API:
docker compose up -d bible-api