The Problem
Businesses that need to ingest scanned contracts, tax forms, or handwritten notes still spend hours manually correcting OCR output. Existing engines either drop layout (tables, checkboxes) or fail on non‑Latin scripts, forcing downstream pipelines to reconstruct structure from noisy text.
What This Does
chandra ships a Python package that runs a single‑stage OCR model capable of preserving full document layout—including tables, forms, math, and handwriting—while supporting 90+ languages. The core inference logic lives in chandra/model/:
hf.py wraps a HuggingFace transformer pipeline (method hf in the CLI). vllm.py contacts a remote vLLM server for low‑latency inference (method vllm). schema.py defines the output JSON/HTML schema used by chandra/output.py to render markdown, HTML, or raw JSON.
The command‑line front‑ends are chandra/scripts/cli.py (exposed as the chandra console script) and chandra/scripts/app.py (the Streamlit UI installed with the optional [app] extra). A lightweight wrapper script chandra/scripts/runapp.py starts the UI, while screenshotapp.py provides a demo page for visual debugging.
How To Use It
Install the base package (no heavy torch deps)
pip install chandra-ocr
Recommended: start a remote vLLM server (see docs) and use the lightweight client chandravllm # installs the vLLM helper script chandra input.pdf ./output # runs default vLLM inference, writes ./output/
If you prefer a local HuggingFace model (requires torch) pip install "chandra-ocr[hf]" chandra input.pdf ./output --method hf
Optional: launch the interactive Streamlit UI
pip install "chandra-ocr[app]" chandraapp # runs chandra/scripts/runapp.py
Setup – The package metadata is in pyproject.toml; installation is standard pip. No Dockerfile or Makefile is provided. Configuration – No environment files are required for local runs; remote mode expects the CHANDRAVLLMENDPOINT variable (referenced in chandra/model/vllm.py). Running – The entry point is the console script chandra defined in pyproject.toml, which invokes chandra/scripts/cli.py. For the UI, chandraapp calls chandra/scripts/runapp.py.
Real‑World Use
A fintech firm can embed the OCR step into its document‑ingestion pipeline:
from chandra.input import Document from chandra.output import StructuredDocument
doc = Document.frompath("contracts/2025Q3.pdf") structured = doc.process(method="vllm") # uses remote vLLM endpoint jsonpayload = StructuredDocument(structured).tojson() push jsonpayload to downstream validation service
The model returns a JSON object with bounding‑box coordinates, enabling the firm to map checkboxes directly to database fields.
Code Health & Issues
Low – Missing lockfile for reproducible builds – pyproject.toml declares deps but the CI does not enforce uv.lock (present but unused). Medium – Limited test coverage – Only two integration tests (tests/integration/testimageinference.py) exist; core utilities (chandra/model/util.py, chandra/output.py) lack unit tests. Low – No secret handling – The remote vLLM client reads CHANDRAVLLMENDPOINT directly; no validation or fallback is implemented. Low – Documentation gaps – README covers CLI usage but does not document required environment variables for vLLM or the expected model directory for HuggingFace mode. Low – CI only runs integration workflow – No linting or type‑checking steps; adding ruff/mypy would improve maintainability.
Overall the repository is well‑structured, with clear module separation and a functional CI pipeline (.github/workflows). The presence of a lockfile (uv.lock) suggests the authors are aware of reproducibility, even if the CI does not enforce it.
The Bottom Line
chandra delivers a ready‑to‑use OCR engine that maintains complex layout and multilingual support, making it a solid fit for enterprises that need high‑fidelity document digitization. The codebase is organized and functional, but teams should add a lockfile‑enforced CI step and expand unit tests before deploying in production‑critical environments.