- Python 90.6%
- Nix 5.5%
- Dockerfile 3.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github/workflows | ||
| packages | ||
| services | ||
| tests/infrastructure | ||
| .envrc | ||
| .gitignore | ||
| docker-compose.gpu.yaml | ||
| docker-compose.yaml | ||
| example.env | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| ruff.toml | ||
| taplo.toml | ||
| treefmt.toml | ||
| ty.toml | ||
| uv.lock | ||
Lectio
Платформа для извлечения текста из PDF, DOCX, PPTX, изображений и видео с конвертацией результата в Markdown.
Суть проекта
Сервис принимает файлы по HTTP API и возвращает task_id, по которому можно опросить статус и забрать результат обработки.
Микросервисная архитектура:
- API (FastAPI) - принимает файлы, валидирует конфигурацию обработки и ставит задачи в очередь Celery.
- Worker (Celery) - выполняет непосредственную обработку: OCR, извлечение текста, STT, сохраняет результаты. Существует в двух вариантах: CPU (по умолчанию) и GPU (для ускорения OCR/STT на CUDA).
Поддерживаемые сценарии
- Извлечение нативного текста из PDF, DOCX и PPTX.
- OCR PDF, встроенных изображений и отдельных картинок (PaddleOCR).
- Извлечение текста из видео по ключевым кадрам с дедупликацией повторов.
- Speech-to-Text для видео (GigaAM).
- Диаризация спикеров в видео (требуется
HF_TOKEN).
Стек
- Python 3.13
- FastAPI + Uvicorn
- Celery + Redis
- uv workspace
- PaddleOCR / PaddleX
- GigaAM
- PyMuPDF, python-pptx, pypandoc
- FFmpeg, LibreOffice, pandoc
- Docker Compose
- Локальное хранилище файлов (общий volume)
Структура репозитория
.
├── packages/
│ ├── lectio-config # общие настройки Celery, storage и т.д.
│ ├── lectio-config-models # Pydantic-модели конфигурации обработки
│ ├── lectio-domain-models # базовые абстракции Media, PDFConvertible и т.д.
│ └── lectio-storage # StorageClient для работы с файлами
├── services/
│ ├── api/ # FastAPI-шлюз
│ └── worker/ # Celery-воркер (CPU/GPU)
├── tests/ # инфраструктурные тесты
├── docker-compose.yaml # конфигурация для Docker Compose (CPU)
├── docker-compose.gpu.yaml # override для GPU worker
└── flake.nix # devShell для разработки с помощью Nix
Быстрый старт
# 1. Подготовить .env файлы
# - example.env - образы API и worker из registry (API_IMAGE, WORKER_IMAGE).
# Скопируйте его в .env и при необходимости укажите конкретную версию, например:
# WORKER_IMAGE=git.geekiot.tech/geekiot/lectio/worker:cpu-0.2.1
# - services/api/.env - настройки API.
# - services/worker/.env - настройки worker.
# Подробнее о переменных окружения в соответствующих README.
# 2. Запустить все сервисы (CPU, по умолчанию)
# Без --build Docker попытается скачать образ из registry,
# с --build соберёт его локально.
docker compose up -d --build
# 3. Проверить API
# Документация доступна по адресу /docs (Swagger UI) и /openapi.json
Для запуска GPU-версии worker используйте override:
docker compose -f docker-compose.yaml -f docker-compose.gpu.yaml up -d --build worker
GPU-версия требует NVIDIA Docker Runtime и видеокарту с поддержкой CUDA. В docker-compose.gpu.yaml по умолчанию используется образ worker:gpu-latest, его можно переопределить через переменную WORKER_IMAGE.
API
API доступно по префиксу /api/v1.
1. Загрузка файла
POST /api/v1/upload
Content-Type: multipart/form-data
files: <файл>
Ответ:
{
"files": [
{
"file_id": "...",
"filename": "document.pdf",
"size": 12345
}
]
}
2. Запуск обработки
POST /api/v1/process
Content-Type: application/json
{
"files": {
"<file_id>": {
"media_type": "pdf",
"ocr": false,
"ocr_full": true
}
}
}
Ответ:
{
"task_id": "...",
"status": "queued"
}
3. Проверка статуса
GET /api/v1/status/<task_id>
Ответ:
{
"task_id": "...",
"status": "SUCCESS",
"result": [
{
"filename": "document_0.md",
"path": "/var/lib/lectio/storage/results/<task_id>/document_0.md"
}
]
}
Конфигурация обработки
Конфигурация передаётся для каждого файла отдельно и валидируется по полю media_type.
| Тип | media_type |
Параметры |
|---|---|---|
pdf |
ocr, ocr_full |
|
| DOCX | docx |
ocr, ocr_full |
| PPTX | pptx |
ocr, ocr_full |
| Изображение | image |
- |
| Видео | video |
stt, ocr_video, use_diarization, scene_threshold, lev_threshold |
Флаги ocr / ocr_full для DOCX и PPTX означают конвертацию в PDF и последующий OCR.
Для видео должен быть включён хотя бы один из stt или ocr_video.
Хранение файлов
Вместо объектного хранилища используется общий Docker volume:
/var/lib/lectio/storage/
├── uploads/<file_id>.<ext>
└── results/<task_id>/
├── *.md
└── .attachments/
Исходные файлы удаляются из uploads/ после успешной обработки.
CI/CD
Workflow .github/workflows/ci.yml:
| Префикс в названии PR | Что запускается |
|---|---|
LINT |
lint |
BUILD |
lint + сборка Docker-образов (если push, то происходит публикация образов) |
TEST |
lint + запуск тестов |
При пуше в main запускается полный pipeline: lint, test, build (с публикацией), semantic-release, tag-images.
Сборка Docker-образов:
api- один образ;worker- два образа:cpuиgpu.
Теги образов worker:
| Вариант | latest | релиз |
|---|---|---|
| CPU | worker:cpu-latest |
worker:cpu-<version> |
| GPU | worker:gpu-latest |
worker:gpu-<version> |
Образ api сохраняет исходные теги: api:latest, api:<version>.
Локальная разработка
Требования: uv + Python 3.13 (или Nix с включённым flakes).
uv sync
Альтернативно через Nix devShell:
nix develop
Тесты
nix develop
uv run --directory services/api --group dev pytest -v
uv run --directory services/worker --group dev pytest -v
uv run --group dev pytest -v tests/infrastructure
Для запуска отдельных сервисов см. services/api/README.md и services/worker/README.md.