titanocr
Deterministic, CPU-only OCR and document structure, with pixel-level provenance on every value.
TitanOCR turns any PDF or image — born-digital, scanned or phone-photographed — into a
Document IR: pages, blocks, lines and table cells, where every piece of text carries its
bounding box, a confidence score and its origin (digital, ocr or vlm). Nothing is a bare
string, and nothing below threshold is presented as certain: low-confidence content is flagged
for review instead of guessed.
Early preview (0.1.x). This package gives you the Document IR, the Markdown projection and the named-field lookup as a Python library. The OCR engine itself runs as a service today (see Running the OCR engine); running it in-process from
pip installis planned. There is no published accuracy claim yet — the evaluation harness exists and the human-labelled benchmark is being built. The API may change before 1.0.
Install
pip install titanocr
Requires Python 3.13+. One dependency is pinned to a pre-release (omegaconf==2.4.0.dev15, the
only build compatible with the OCR stack), which pip accepts as-is. With uv, allow it:
uv pip install titanocr --prerelease=allow
# or, in a uv project:
uv add titanocr --prerelease=allow
What you can do with the package
Load and validate a Document IR
The engine's output (GET /v1/documents/{id}/ir) is a JSON document validated by pydantic
models. Loading it gives you typed access and rejects anything that breaks the contract.
from pathlib import Path
from titanocr.ir import DocumentIR
ir = DocumentIR.model_validate_json(Path("ir.json").read_text())
print(ir.ir_version, ir.page_count)
Walk the text with its provenance
Blocks come in reading order; every line and table cell knows where it came from.
for page in ir.pages:
for block in sorted(page.blocks, key=lambda b: b.reading_order):
for line in block.lines or ():
# bbox: (x0, y0, x1, y1) in page pixels, origin top-left
print(page.page_no, line.origin.value, line.confidence, line.bbox, line.text)
if block.table:
for cell in block.table.cells:
print(cell.row, cell.col, cell.text)
Each page also carries its own confidence signals (page.confidence.mean_rec,
p10_rec, text_coverage, …) and the preprocessing it went through (page.prep), so a bbox
can be mapped back to the original upload.
Render Markdown
A deterministic projection for display, diffing or feeding an LLM. Markdown is a view of the IR — build extraction on the IR, not on the Markdown.
from titanocr.render_md import ir_to_markdown
print(ir_to_markdown(ir))
Look up named fields
A deterministic key → value lookup over a finished document (labelled pairs, table cells,
inline Label: value text). Every hit carries the rule that found it and its provenance; a miss
says why instead of guessing.
from titanocr.fields import available_labels, extract_fields
print(available_labels(ir)) # every label this document offers
result = extract_fields(ir, ["Invoice No", "Due Date"])
for hit in result.fields:
print(hit.name, "->", hit.value, hit.strategy, hit.reason)
payload = result.as_json() # JSON-ready, with provenance per field
Command-line tools
python -m titanocr.ir.validate ir.json # exit 0 if valid, prints each violation if not
python -m titanocr.ir.schema schema.json # export the IR as JSON Schema (for non-Python consumers)
Running the OCR engine
The engine — PDF text-layer extraction, image preparation, PP-OCRv5 detection and recognition on ONNX Runtime, layout, table reconstruction and triage — runs as an HTTP service with its models pinned and checksummed. Run it from the repository:
git clone https://github.com/Phantom-IN/titanocr && cd titanocr
make setup && make models # install, then fetch + verify the ONNX models
make dev # http://localhost:8000/demo
or as a container (make docker-build, then docker compose up). Upload a file, poll until it
is done, then fetch the IR:
curl -F file=@invoice.pdf http://localhost:8000/v1/documents # → {"doc_id": ...}
curl http://localhost:8000/v1/documents/<doc_id> # status + per-page review_required
curl http://localhost:8000/v1/documents/<doc_id>/ir -o ir.json # the Document IR
Design in one paragraph
Transcription (which characters are where) is done by OCR on CPU — deterministic, cheap, and
checkable against a bounding box. Understanding what the text means is left to you, on text.
Born-digital pages are exact by construction; scanned pages get accuracy-first OCR; anything
below threshold is flagged review_required. A vision model is never the default path: it is
an opt-in escalation for the cropped regions the engine could not read, and it is off unless an
operator configures it. Re-running the same document with the same models produces the same
bytes.
Links
- Source, design docs and roadmap: https://github.com/Phantom-IN/titanocr
- Document IR specification: https://github.com/Phantom-IN/titanocr/blob/main/docs/02-document-ir.md
- Issues: https://github.com/Phantom-IN/titanocr/issues
Licensed under MIT.
Metadata
Release files for titanocr 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| titanocr-0.1.3.tar.gz | 539.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| titanocr-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.1 MB
Release files / titanocr-0.1.3.tar.gz
| Download URL | titanocr-0.1.3.tar.gz |
|---|---|
| Size | 539.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6931b1bc33db23377bcbc95053f4210511c0fdba45017d48ec2ebc4457df2add
|
|
BLAKE2b-256 checksum How to use checksums |
8d89a9d8d7c2d167196b1ee6e152341aecd6c50be3ef93677d3bc09cd28e0bf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logRelease files / titanocr-0.1.3-py3-none-any.whl
| Download URL | titanocr-0.1.3-py3-none-any.whl |
|---|---|
| Size | 557.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e307f6a1631ac972779a7ecf731686173684c5b9be6971007760f9cbee4415d0
|
|
BLAKE2b-256 checksum How to use checksums |
4148f22b1d94a3f197b803f8e95663b4390fdbac13fd7eb03819de8c84ca050e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency log