git clone
PayDoc AI — сервис для автоматической обработки платёжных документов. В основе лежат FastAPI, Celery и EasyOCR. Сервис умеет распознавать текст, извлекать банковские реквизиты, проводить проверку данных и готовить результат для дальнейшей интеграции с учётными системами.
- Возможности
- Архитектура и стек
- Быстрый старт (Docker)
- Работа с API
- Синхронная обработка (демо)
- Тестовые данные
- Мониторинг и управление
- Разработка и тестирование
- Устранение неполадок
- Распознавание текстов в PDF и изображениях (EasyOCR).
- Извлечение ключевых реквизитов: ИНН, КПП, БИК, расчётный счёт, сумма, дата платежа, назначение.
- Проверка форматов и контрольных сумм через Pydantic и кастомные валидаторы.
- Отправка документов в асинхронную очередь Celery и fallback на ручную обработку.
- Интеграция с внешней учётной системой (mock server в docker-compose).
- Prometheus/Grafana для наблюдаемости, структурированные логи и rate limiting.
- FastAPI — REST API.
- Celery + Redis — асинхронная обработка.
- PostgreSQL — хранение документов и результатов.
- EasyOCR + OpenCV — OCR обработка.
- Prometheus / Grafana — мониторинг.
- Docker Compose — запуск всех сервисов.
Все сервисы поднимаются одной командой и взаимодействуют внутри сети paydoc-network.
- Установите Docker и Docker Compose.
- Клонируйте репозиторий и перейдите в каталог проекта:
git clone <repository-url> cd PayDoc_AI
- Поднимите инфраструктуру:
Скрипт пересоберёт образы, создаст сеть и запустит контейнеры (
./start.sh
app,worker,postgres,redis,mock-accounting,prometheus,grafana). - Проверьте живость приложения:
curl http://localhost:8000/health/live
- Swagger UI доступен по адресу
http://localhost:8000/docs(доступно, потому что переменнаяDEBUG=true). - Для остановки используйте:
./stop.sh
Базовый префикс — /v1.
| Метод | Путь | Описание |
|---|---|---|
POST |
/documents |
Загрузить документ. Возвращает DocumentResponse со статусом pending. |
GET |
/documents/{id} |
Получить текущий статус и результат обработки. |
GET |
/documents/{id}/view |
Скачать/просмотреть оригинальный файл. |
POST |
/documents/{id}/process |
Принудительно запустить синхронную обработку (для демонстрации). |
Дополнительно доступны /health/live, /health/ready, /metrics (Prometheus).
# Загрузка документа
curl -X POST http://localhost:8000/v1/documents \
-F "file=@test_inputs/demo_invoice_02.jpg"
# Синхронная обработка (когда Celery недоступен или требуется демо)
curl -X POST http://localhost:8000/v1/documents/<document_id>/process
# Получение статуса
curl http://localhost:8000/v1/documents/<document_id>
# Просмотр изображения (вернёт бинарные данные)
curl -o out.jpg http://localhost:8000/v1/documents/<document_id>/view- При загрузке вычисляется SHA-256 хеш файла. Если документ уже был загружен, вернётся
409 Conflictс ID оригинала. - Асинхронная обработка выполняется Celery worker-ами; статус меняется с
pending→processing→success|failed|manual_review. - Валидация использует строгие правила: некорректный ИНН, БИК или другие поля приводят к ошибкам валидации. В синхронном режиме исключения возвращаются сразу.
Эндпоинт POST /v1/documents/{id}/process обрабатывает документ в одном запросе. Это полезно для демонстрации или отладки, когда Celery ещё не настроен. Проход этапов:
- Обновление статуса документа на
processing. - Вызов OCR (
get_ocr_service().extract_payment_data). - Валидация через
DocumentValidator(проверка контрольных сумм, форматов и правил). - Сохранение результатов в БД с сериализацией Decimal → JSON.
- Возврат
DocumentResponseс заполненными полями.
При ошибке валидации сервис возвращает 500 с пояснением (например, Неверная контрольная сумма ИНН). Это поведение можно адаптировать под нужды (например, вместо 500 отдавать 422 и переводить документ в manual_review).
Каталог test_inputs/ содержит подготовленные изображения:
| Файл | Назначение |
|---|---|
demo_invoice_01.jpg |
Нарушенная контрольная сумма ИНН — демонстрирует отрицательный сценарий. |
demo_invoice_02.jpg |
Корректный документ — приводит к статусу success. |
Если требуется новый документ, можно сгенерировать его прямо в контейнере приложения (Pillow уже включён в образ):
docker exec paydoc-app python - <<'PY'
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
path = Path('/app/test_inputs/demo_invoice_valid.jpg')
path.parent.mkdir(parents=True, exist_ok=True)
lines = [
'ООО "Корректные данные"',
'ИНН 7707083893 КПП 770701001',
'БИК 044525225',
'Р/с 40702810900000000011',
'Назначение: Оплата по договору №102',
'Сумма: 21500.75 RUB',
'Дата: 01.11.2025',
]
img = Image.new('RGB', (1200, 800), 'white')
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype('DejaVuSans.ttf', 36)
except OSError:
font = ImageFont.load_default()
y = 80
for line in lines:
draw.text((80, y), line, fill='black', font=font)
y += 70
img.save(path, quality=95)
print('Generated:', path)
PY- Grafana:
http://localhost:3000(логин/парольadmin/admin). Подключены дашборды с метриками по HTTP и Celery. - Prometheus:
http://localhost:9090. Основные метрики:http_requests_totalhttp_request_duration_secondsdocuments_processed_totaldocument_processing_seconds
- Логи приложения и воркеров:
docker compose logs app,docker compose logs worker.
app/
├── api/v1/ # Эндпоинты FastAPI
├── core/ # OCR, валидаторы, конфигурация
├── dependencies/ # Интеграция с БД и Celery
├── models/ # SQLAlchemy ORM
├── schemas/ # Pydantic модели и ответы
└── tasks/ # Celery задания
tests/
├── unit/
├── integration/
└── performance/
- Для локальной разработки без Docker используйте Poetry:
poetry install poetry run uvicorn app.main:app --reload
- Тесты запускаются утилитой
run_tests.py:python run_tests.py all # полный прогон python run_tests.py quick # быстрые unit-тесты python run_tests.py coverage # отчёт покрытия
- Дополнительные профили docker-compose (
infra,monitoring) позволяют запускать только нужную часть стеков.
- 409 Duplicate document — файл уже лежит в базе. Возьмите другой файл или удалите запись из БД.
- 500 Validation error — OCR извлек некорректные данные (например, неверная контрольная сумма ИНН). Исправьте исходный документ или адаптируйте логику валидации.
- EasyOCR PermissionError — убедитесь, что переменная
HOMEв контейнере установлена в/app(уже задано вdocker-compose.yml) и томuploads_dataдоступен для записи. - Mock accounting unhealthy — сервис заглушки может быть в состоянии
unhealthy, но на демо это не влияет. При необходимости перезапустите контейнер:docker compose restart mock-accounting. - База/Redis не поднимаются — убедитесь, что порт 5432/6379 не занят на хосте. Можно изменить порт в
docker-compose.yml.
PayDoc AI — готовая платформа для цифровизации платёжных документов.