Skip to main content

obliq-ocr

CI PyPI Python 3.10 | 3.11 | 3.12 License: MIT

Pulls the text out of PDFs and scans, one page at a time. Pages that already have digital text are read straight from the PDF in milliseconds; scanned pages go through OCR (RapidOCR, PP-OCRv4 on ONNX Runtime). A file that mixes both is handled without any settings.

It was built at OBLIQ for the documents CA firms get from their clients: tax invoices, bills, challans, e-way bills and compiled PDFs. It's for Python developers who need that text as plain strings or JSON, and its output is meant to be checked by a person before it's used.

Install

pip install obliq-ocr
  • Python 3.10, 3.11 or 3.12. The OCR engine doesn't install on 3.13 yet.
  • Linux and Windows are tested. macOS should work but isn't tested.
  • Runs on CPU. For an NVIDIA GPU, see GPU.

The first release isn't on PyPI yet. Until it is, install from GitHub:

pip install "git+https://github.com/OBLIQ-in/obliq-OCR.git"

Quickstart

from obliq_ocr import parse_document, save_result

result = parse_document("invoice.pdf")  # a PDF or an image

for page in result.pages:
    print(page.page, page.method, page.confidence)

print(result.full_text())
save_result(result, out_dir="outputs")  # outputs/invoice.json and outputs/invoice.txt

parse_document prints one progress line per page; pass verbose=False to turn that off.

Supported files

Type Extensions Notes
PDF .pdf Digital, scanned or mixed. Password-protected PDFs raise ValueError.
Images .jpg .jpeg .png .bmp .tif .tiff .webp Each frame of a multi-page TIFF is a page. Phone photos are turned upright using their EXIF data.

Sample output

save_result writes this JSON (the same as result.to_dict()). This is the real output for a two-page test PDF where page 1 is digital and page 2 is a scan:

{
  "source": "invoice.pdf",
  "device": "CPU",
  "pages": [
    {
      "page": 1,
      "method": "text_layer",
      "reason": "97 chars, image cover 0%",
      "text": "Mixed document digital page.\nThis page contains native text layer elements.\nIt should be extracted via text layer.",
      "n_chars": 114,
      "confidence": null,
      "seconds": 0.018
    },
    {
      "page": 2,
      "method": "ocr",
      "reason": "only 0 text chars",
      "text": "Mixed document scanned page.",
      "n_chars": 28,
      "confidence": 1.0,
      "seconds": 0.516
    }
  ]
}

method is text_layer, ocr or blank. confidence is the average OCR score from 0 to 1, and null for pages that weren't OCR'd. Every field and error is explained in the architecture doc.

Command line

obliq-ocr invoice.pdf                                   # writes outputs/invoice.json and .txt
obliq-ocr scan.pdf --output-dir results --device cpu    # choose folder and device
obliq-ocr scan.pdf --quiet                              # no per-page progress
python -m obliq_ocr invoice.pdf                         # same thing, as a module

GPU

pip uninstall -y onnxruntime
pip install "obliq-ocr[gpu]"

The CPU and GPU builds of ONNX Runtime can't be installed together, which is why the first command is needed. obliq-ocr uses CUDA when it's available; set OBLIQ_OCR_DEVICE=cpu or cuda, or pass force_device="cpu" or "cuda", to choose.

Limitations

The model card has the measurements. In short:

  • Scanned pages can't produce ₹ or Hindi and other Indian scripts. Digital PDFs keep them.
  • Handwriting isn't supported.
  • Low-resolution or skewed scans can change digits and drop whole lines.
  • A high confidence doesn't mean the text is right: check key values.
  • The output has no coordinates yet (#71).

Documentation

Contributing

git clone https://github.com/OBLIQ-in/obliq-OCR.git
cd obliq-OCR
python -m venv .venv            # Python 3.10 to 3.12
source .venv/bin/activate       # Windows: .venv\Scripts\activate
pip install -e ".[dev,test]"
pre-commit install
python tests/scripts/generate_fixtures.py   # synthetic test PDFs
pytest
  • Branch off main and open a PR. PR titles follow Conventional Commits (docs: …, fix: …, feat: …). If the PR has a single commit, its message must follow the same format.
  • CI runs ruff, mypy, the tests on Python 3.10 to 3.12, an accuracy gate and a link check.
  • Never commit real client documents or anything with personal data. Test files must be synthetic or fully anonymised.

Questions and bugs go to GitHub issues.

License

MIT

Metadata

Release files for obliq-ocr 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for obliq-ocr 0.1.1
File Size Uploaded Provenance Actions
obliq_ocr-0.1.1.tar.gz 61.1 kB Without provenance Details for obliq_ocr-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for obliq-ocr 0.1.1
File Interpreter ABI Platform Actions
obliq_ocr-0.1.1-py3-none-any.whl Python 3 none any Details for obliq_ocr-0.1.1-py3-none-any.whl

Total release size: 79.5 kB

Release files / obliq_ocr-0.1.1.tar.gz

Download URL obliq_ocr-0.1.1.tar.gz
Size 61.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ed9b8db6bce640a8f1565506594d38241e258846961a9623d5c11e8502765bc5
BLAKE2b-256 checksum
How to use checksums
2fe929548b044bb10d0a15495c3462d61fc7f73d386cf538cea16be436a9dc4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / obliq_ocr-0.1.1-py3-none-any.whl

Download URL obliq_ocr-0.1.1-py3-none-any.whl
Size 18.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81ffd0b12bb4795439c3111c830930e0d0728edbbdfaa3d8fd8593e597788420
BLAKE2b-256 checksum
How to use checksums
b796e63ac71092c0812952331657d1ad16e75696aaead4db156e16410925180a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for obliq-ocr 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page