Skip to content

OpenCV Medical Document Service

Serwis do automatycznego skanowania i przetwarzania dokumentów medycznych (wyniki laboratoryjne, badania obrazowe) przy użyciu OpenCV i OCR.

Tech Stack

Backend & Framework:

  • Django 4.2.7
  • Django REST Framework 3.14.0
  • drf-spectacular 0.27.0 (OpenAPI/Swagger dokumentacja)
  • PostgreSQL (psycopg2-binary 2.9.9)
  • gunicorn 21.2.0 + whitenoise 6.6.0 (production serving)

Image & Document Processing:

  • opencv-python-headless 4.8.1.78 (przetwarzanie obrazów)
  • pytesseract 0.3.10 (OCR / rozpoznawanie tekstu)
  • pdf2image 1.16.3 + pymupdf 1.24.10 (konwersja PDF → obrazy)
  • Pillow 10.1.0 (manipulacja obrazami)
  • numpy 1.24.3

Utilities:

  • requests 2.31.0
  • python-dotenv 1.0.0
  • dj-database-url 2.1.0
  • coverage 7.6.0 (testowanie)

Funkcjonalności

  • Upload dokumentów medycznych przez REST API (PDF, JPEG, PNG, HEIC)
  • Automatyczne skanowanie dokumentów z użyciem OpenCV
  • OCR (rozpoznawanie tekstu) przez Tesseract
  • Ekstrakcja wyników laboratoryjnych z dokumentów (unverified — confirm with team: integracja z serwisem słowników)
  • Webhook notifications po zakończeniu przetwarzania (unverified — confirm with team)
  • Django Admin + dedykowana przeglądarka dokumentów (/browser/)
  • Swagger UI / ReDoc — pełna dokumentacja API
  • Token-based authentication (unverified — confirm with team: endpoint /api/auth/login/ wspomniany w README ale nie zweryfikowany w kodzie)

Instalacja i Setup

1. Wymagania systemowe

Tesseract OCR (required dla pytesseract):

bash
# macOS
brew install tesseract tesseract-lang

# Ubuntu/Debian
sudo apt-get install tesseract-ocr tesseract-ocr-pol

# Windows
# Pobierz instalator z: https://github.com/UB-Mannheim/tesseract/wiki

Poppler (required dla pdf2image):

bash
# macOS
brew install poppler

# Ubuntu/Debian
sudo apt-get install poppler-utils

# Windows
# Pobierz binaries z: https://github.com/oschwartz10612/poppler-windows/releases

2. Instalacja zależności Python

bash
pip install -r requirements.txt

3. Konfiguracja zmiennych środowiskowych

Utwórz plik .env w root katalogu:

env
SECRET_KEY=your-secret-key-here
DEBUG=True
DATABASE_URL=postgresql://user:password@localhost:5432/opencv_db
DICTIONARY_SERVICE_URL=http://localhost:8001

4. Migracje i setup bazy danych

bash
python manage.py migrate
python manage.py createsuperuser  # opcjonalnie, dla Django Admin

5. Uruchomienie serwera deweloperskiego

bash
python manage.py runserver

Aplikacja będzie dostępna pod:

API Endpoints

Autentykacja (unverified — confirm with team)

Login:

bash
POST /api/auth/login/
Content-Type: application/json

{
  "username": "your_username",
  "password": "your_password"
}

# Response:
{
  "token": "abc123...",
  "user_id": 1,
  "username": "your_username"
}

Używanie tokenu:

bash
Authorization: Token abc123...

Generowanie tokenu przez CLI:

bash
# Dla istniejącego użytkownika
python manage.py create_token username

# Utworzenie użytkownika + token
python manage.py create_token username --create-user --password haslo123

Upload dokumentu

bash
POST /api/documents/upload/
Content-Type: multipart/form-data
Authorization: Token abc123...  # opcjonalnie

file: [plik: PDF, JPG, PNG, HEIC]
webhook_url: [opcjonalny URL webhooka dla notyfikacji po zakończeniu]

Pobieranie dokumentu

bash
GET /api/documents/{document_id}/
Authorization: Token abc123...  # opcjonalnie

Lista dokumentów

bash
GET /api/documents/
Authorization: Token abc123...  # opcjonalnie

Pełna dokumentacja API: http://localhost:8000/api/docs/ (Swagger UI) — wszystkie endpointy można testować bezpośrednio z przeglądarki.

Interfejs Webowy

Przeglądarka dokumentów (/browser/) pozwala na:

  • Upload dokumentów przez formularz webowy
  • Przeglądanie wszystkich wgranych dokumentów
  • Wyświetlanie statusu przetwarzania (pending / completed / error)
  • Podgląd wyników skanowania i interpretacji OCR
  • Szczegóły każdego dokumentu (metadane, extracted data)

Deployment na Railway

Quick Start

  1. Połącz repozytorium GitHub z Railway
  2. Dodaj PostgreSQL database jako nowy service (Railway Marketplace)
  3. Dodaj Persistent Volume dla /app/media (storage dla uploadowanych dokumentów)
  4. Ustaw Environment Variables:
    SECRET_KEY=<wygeneruj bezpieczny klucz>
    DEBUG=False
    DICTIONARY_SERVICE_URL=<URL twojego serwisu słowników>
    DATABASE_URL=<automatycznie ustawione przez Railway Postgres>
  5. Ustaw Start Command (lub upewnij się że Procfile jest obecny):
    bash
    bash scripts/railway_start.sh
  6. Deploy — Railway automatycznie wykryje Python i zainstaluje dependencies

Railway Start Script

⚠️ WAŻNE: W produkcji kontener MUSI startować przez:

bash
bash scripts/railway_start.sh

Skrypt zapewnia:

  1. python manage.py ensure_database_ready — uruchomienie migracji + walidacja tabel
  2. python manage.py load_lab_ontology — załadowanie ontologii medycznej (jeśli istnieje)
  3. gunicorn opencv_service.wsgi:application — start production servera

Bez tego skryptu: kontener może wystartować bez migracji → API zwraca 500 z błędem relation "documents_document" does not exist.

Troubleshooting: 500 na produkcji

Symptom: GET /api/documents/ zwraca 500, w logach: relation "documents_document" does not exist

Szybka diagnoza i fix:

bash
# 1) Link do Railway service (wykonaj raz)
railway link -p 6c8ab19f-bc63-4e84-a5ca-aa7e9dc7beb7 \
  -s 88a45096-0a30-4795-a85e-c5cf39bab6fe \
  -e 08f36d9a-680c-4d90-8eb1-2f417c67d951

# 2) Sprawdź status
railway status

# 3) Obejrzyj logi
railway logs --latest --lines 120

# 4) Awaryjne uruchomienie migracji w kontenerze
railway ssh 'export LD_LIBRARY_PATH=/nix/store/ybjcla5bhj8g1y84998pn4a2drfxybkv-gcc-13.3.0-lib/lib:/nix/store/s94fwp43xhzkvw8l8nqslskib99yifzi-gcc-13.3.0-lib/lib:$LD_LIBRARY_PATH && cd /app && /opt/venv/bin/python manage.py migrate --noinput'

# 5) Weryfikacja
curl -i https://opencv-production.up.railway.app/api/documents/
# Oczekiwane: HTTP 200 + JSON (np. [])

Sprawdź również:

  • DATABASE_URL w Railway Environment Variables (musi wskazywać właściwy Postgres)
  • Start Command faktycznie używa bash scripts/railway_start.sh
  • Volume dla /app/media jest zamountowany

Sprawdzanie logów Railway

bash
# Bezpośrednio przez Railway CLI (wymagane: npm i -g @railway/cli)
railway login
railway logs --service opencv --tail 50
railway logs --service opencv --follow  # real-time streaming

Alternatywnie użyj skryptu _tests/scripts/railway_logs.py (jeśli dostępny).

Architektura Projektu

opencv/
├── documents/              # Główna aplikacja Django
│   ├── models.py          # Model Document (status, file, metadata)
│   ├── services.py        # Logika przetwarzania OpenCV + OCR (unverified)
│   ├── views.py           # REST API endpoints (DRF ViewSets)
│   ├── admin.py           # Django Admin configuration
│   ├── management/        # Django management commands
│   │   └── commands/      # (np. load_lab_ontology, ensure_database_ready)
│   ├── migrations/        # Django database migrations
│   ├── tests/             # Unit tests
│   └── data/              # Static data (ontologie, słowniki)
├── opencv_service/         # Django project configuration
│   ├── settings.py        # Settings (env vars, DB, middleware)
│   ├── urls.py            # URL routing
│   └── wsgi.py            # WSGI entry point (dla gunicorn)
├── templates/              # Django HTML templates
│   └── admin/documents/   # Custom admin templates dla Document model
├── scripts/                # Deployment & utility scripts
│   └── railway_start.sh   # Production startup script (Railway)
├── _tests/                 # Test data & scripts
│   ├── wsady/             # Przykładowe PDFy wyników laboratoryjnych
│   ├── wsady/wyniki_lab/  # Real-world test documents (PDFs, HEICs)
│   └── scripts/           # Test utilities (coverage, log fetching)
├── media/                  # Upload storage (volume na Railway)
├── requirements.txt        # Python dependencies
├── Procfile                # Railway deployment config
└── README.md

Zmienne Środowiskowe

ZmiennaOpisDomyślnieWymagane
SECRET_KEYDjango secret key (użyj django.core.management.utils.get_random_secret_key())-✅ (prod)
DEBUGDebug mode (True/False)True
DATABASE_URLPostgreSQL connection string (format: postgresql://user:pass@host:port/db)sqlite (dev)✅ (prod)
DICTIONARY_SERVICE_URLURL zewnętrznego serwisu słowników medycznychhttp://localhost:8001❌ (unverified)
ALLOWED_HOSTSComma-separated list dozwolonych hostów (Railway auto-ustawia)localhost,127.0.0.1

Testowanie

bash
# Uruchomienie testów z coverage
python -m coverage run manage.py test documents
python -m coverage report

# Lub użyj skryptu (jeśli dostępny)
python _tests/scripts/run_coverage_and_save.py

Przykładowe dokumenty testowe znajdują się w _tests/wsady/ (wyniki laboratoryjne w formacie PDF, HEIC).

Status & Roadmap

Current status: Production-ready (deployed na Railway)

Known limitations / To verify:

  • Integracja z serwisem słowników (DICTIONARY_SERVICE_URL) — confirm implementation details
  • Webhook notifications — confirm endpoint i payload format
  • Token authentication endpoints — verify /api/auth/login/ i create_token command availability
  • Tesseract language packs — Railway może wymagać custom Nixpacks config dla tesseract-ocr-pol

Support

Dokumentacja Railway deployment: SERVICE_OWNER_GUIDE.md (jeśli dostępna w repo)

Test data & reprodukcja błędów: _tests/README.md

Railway Service IDs:

  • Project: 6c8ab19f-bc63-4e84-a5ca-aa7e9dc7beb7
  • Service: 88a45096-0a30-4795-a85e-c5cf39bab6fe
  • Environment (prod): 08f36d9a-680c-4d90-8eb1-2f417c67d951

Wellysa Consigliere — internal use only.