The Problem

Manual review of credit‑application PDFs is slow, error‑prone, and costly. Teams need a repeatable way to extract structured financial fields from scanned documents without sending data to external APIs.

What This Does

The repository implements a self‑contained OCR pipeline that runs entirely on‑premise. Core code lives under src/:

src/ocr/easyocrclient.py – wraps EasyOCR, returns raw text and bounding boxes. src/llm/fieldextractor.py – feeds OCR output to a local LLM (served by Ollama) to produce key‑value pairs. src/tasks/pipelinetasks.py and src/celeryapp.py – define Celery workers that orchestrate OCR → LLM → validation asynchronously.

The Flask API (src/api/main.py) exposes endpoints for document upload and status queries, while src/visualization/ocrvisualization.py creates overlay images for human review. Configuration files (config/credit-ocr-system.conf, config/documenttypes.conf) drive document‑type rules and storage paths.

How To Use It

Prepare the environment # Copy the template and edit as needed cp .env.template .env # Edit .env to set POSTGRES, REDIS, AZURITE, and Ollama connection strings

The .env values are consumed by docker-compose.yml and by the Flask app via src/api/config.py. Build and start the stack docker compose up --build -d

Dockerfile builds the Python image used by the api service. compose.yml defines PostgreSQL, Redis, Azurite (Azure Blob emulator), Ollama, and the API container. Run the API locally (optional) If you prefer a direct Python launch: uv pip install -r <(uv pip compile pyproject.toml) # installs declared deps python runapi.py # starts Flask on port 5000 Upload a document Send a POST request to http://localhost:5000/upload with a PDF file. The API stores the blob in Azurite, creates a Celery job, and returns a job ID. Check processing status curl http://localhost:5000/status/<jobid>

When completed, the response includes extracted fields, confidence scores, and a URL to the visual overlay image.

All notebooks under notebooks/ (e.g., 02ocrtextextraction.ipynb) demonstrate each stage step‑by‑step and can be used as reference implementations.

Real‑World Use

A loan‑origination service can embed the API behind its existing web portal:

import requests

files = {'file': open('loanapplication.pdf', 'rb')} resp = requests.post('https://ocr.mycompany.com/upload', files=files) jobid = resp.json()['jobid']

poll until done while True: status = requests.get(f'https://ocr.mycompany.com/status/{jobid}').json() if status['state'] == 'COMPLETED': break time.sleep(2)

print(status['extractedfields'])

The workflow runs entirely on internal infrastructure, preserving data privacy while delivering sub‑10‑minute turnaround.

Code Health & Issues

SeverityIssueLocation
MediumNo CI/CD pipeline (no .github/, GitLab CI, etc.) – builds and tests are not gated automatically.Root
MediumNo LICENSE file – downstream users cannot be sure of redistribution rights.Root
LowDependencies are declared only in pyproject.toml; there is no lockfile (uv.lock exists but is not referenced in CI).pyproject.toml, uv.lock
Low.env.template contains placeholder secrets; production deployment relies on manual editing, increasing risk of accidental commit of real credentials..env.template
LowCelery tasks (src/tasks/pipelinetasks.py) lack explicit retry/back‑off policies, which could cause lost work under transient failures.src/tasks/pipelinetasks.py
LowAPI input validation is minimal – uploaded files are accepted without size/type checks.src/api/routes.py
LowDocumentation is extensive (README, notebooks, docs/), but the quick‑start section in the README is truncated, leaving the exact start command ambiguous.README.md

Overall the test suite (tests/) covers API routes, DMS integration, and the full pipeline, indicating reasonable functional coverage.

The Bottom Line

The repo provides a complete, on‑premise OCR‑LLM pipeline with Docker‑compose orchestration, suitable for organizations that must keep credit‑application data internal. Code quality is solid, but the lack of CI, a license, and automated dependency locking means additional operational effort is required before production adoption. Teams with in‑house DevOps resources will find it a practical foundation; smaller teams may need to add the missing governance pieces.