Skip to main content

PrettyPipeline

PyPI Python License: MIT

Turn PDFs into structured JSON. OCR runs on your GPU when needed. Field extraction uses a cheap cloud LLM. You define the schema.

PDF  →  embedded text (digital PDFs) or Unlimited-OCR (scans)
                              ↓
        GPT-5.4 nano (OpenAI)  →  JSON + needs_review + _meta

Why this is cheap

Cloud OCR APIs charge per page. PrettyPipeline does vision work locally with baidu/Unlimited-OCR (MIT, 3B params, 32K context) when a page has no usable embedded text.

The only paid call is GPT-5.4 nano on document text (~$0.20 / 1M input tokens), prompted with your JSON schema.

Digital PDFs use embedded text automatically (fast, accurate). OCR runs per-page only for scans, or for everything with --force-ocr.

Nulls, uncertain fields, values not found in source text, and garbled OCR are flagged in needs_review (one reason per field).

Install

Python 3.10–3.13 (3.12 recommended).

Digital PDFs only (no local OCR, smallest install):

pip install prettypipeline-ocr

Full install (local OCR for scans and --force-ocr):

pip install prettypipeline-ocr[ocr]

The CLI is prettypipeline. From this repo:

python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[ocr,dev]"

NVIDIA Linux — install a CUDA PyTorch wheel first if needed:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
pip install prettypipeline-ocr[ocr]

The first OCR run downloads baidu/Unlimited-OCR from Hugging Face (~6GB).

Docker (CUDA):

docker build -f Dockerfile.cuda -t prettypipeline:cuda .
docker run --gpus all -e OPENAI_API_KEY=sk-... \
  -v "$PWD/data:/data" prettypipeline:cuda \
  run /data/invoice.pdf --schema /data/schema.json -o /data/out.json

Quick start

export OPENAI_API_KEY=sk-...

prettypipeline run invoice.pdf --schema examples/invoice.schema.json
prettypipeline run invoice.pdf --schema examples/invoice.schema.json -o out.json
prettypipeline run invoice.pdf --schema examples/invoice.schema.json --ocr-only

Demo invoice in this repo:

prettypipeline run tests/fixtures/sample_invoice.pdf \
  --schema examples/invoice.schema.json -o out.json

Batch:

prettypipeline batch ./invoices/*.pdf \
  --schema examples/invoice.schema.json \
  --output-dir ./out/ \
  --summary ./out/summary.json

Schema examples

File Use case
examples/invoice.schema.json Invoices
examples/receipt.schema.json Receipts
examples/purchase_order.schema.json Purchase orders

--schema is any JSON Schema — swap the file to extract a different document type.

CLI

prettypipeline run FILE.pdf --schema SCHEMA.json
  -o, --output PATH           write JSON (also printed)
  --ocr-only                  skip OpenAI step
  --force-ocr                 always OCR (skip embedded text)
  --include-ocr-text          include raw text in output
  --device cuda|mps|cpu       override auto-detect
  --dpi N                     PDF raster DPI (default 300)
  --max-length N              OCR cap (8192 MPS, 32768 CUDA/CPU)
  --model NAME                LLM model (default gpt-5.4-nano)
  --base-url URL              OpenAI-compatible API endpoint

prettypipeline batch FILES... --schema SCHEMA.json --output-dir DIR
  --summary PATH              optional batch summary JSON

Environment variables:

Variable Purpose
OPENAI_API_KEY Required unless --ocr-only
PRETTYPIPELINE_MODEL Default LLM model
PRETTYPIPELINE_BASE_URL OpenAI-compatible base URL

Output

{
  "data": {
    "date": "January 25, 2016",
    "vendor": "DEMO - Sliced Invoices",
    "invoice_number": "INV-3337",
    "total": 93.5
  },
  "needs_review": [],
  "source": "pdf_text",
  "_meta": {
    "version": "0.3.0",
    "elapsed_ms": 4200,
    "pages": 1,
    "device": "mps",
    "model": "gpt-5.4-nano",
    "token_usage": {
      "prompt_tokens": 1200,
      "completion_tokens": 180,
      "total_tokens": 1380
    }
  }
}
source meaning
pdf_text all pages used embedded text
ocr all pages OCR'd
mixed some pages embedded, some OCR
needs_review reason meaning
null model returned null
uncertain model flagged low confidence
garbled_ocr value or nearby OCR looks corrupted
not_in_source value not found in document text

Programmatic use

from prettypipeline import run

result = run(
    "invoice.pdf",
    "examples/invoice.schema.json",
)
print(result.data)
print(result.needs_review)
print(result.meta)

Lower-level imports: extract_text, structure, needs_review.

Hardware

Device Support
NVIDIA CUDA Native. Recommended for OCR.
Apple Silicon (MPS) Supported with CUDA-call patching. --force-ocr may produce garbled output; digital PDFs are unaffected.
CPU Works, slow.

On MPS, default --max-length is 8192 (input + generation). CUDA/CPU default is 32768.

Development

pip install -e ".[ocr,dev]"
pytest
python -m build && twine check dist/*

License

MIT. Unlimited-OCR is also MIT.

Sample invoice: Sliced Invoices.

Metadata

Release files for prettypipeline-ocr 0.3.0

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

Source distribution (sdist)

Source distribution for prettypipeline-ocr 0.3.0
File Size Uploaded Provenance Actions
prettypipeline_ocr-0.3.0.tar.gz 16.4 kB Without provenance Details for prettypipeline_ocr-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for prettypipeline-ocr 0.3.0
File Interpreter ABI Platform Actions
prettypipeline_ocr-0.3.0-py3-none-any.whl Python 3 none any Details for prettypipeline_ocr-0.3.0-py3-none-any.whl

Total release size: 31.0 kB

Release files / prettypipeline_ocr-0.3.0.tar.gz

Download URL prettypipeline_ocr-0.3.0.tar.gz
Size 16.4 kB
Tags Source
SHA-256 checksum
How to use checksums
469615e3de1cd5ee29daaa86f2d4701bbe67b30cecf95916e998c25c20400124
BLAKE2b-256 checksum
How to use checksums
282ffa5fe0e629534e271d991eb465fcb52cf80b8649d649df93c706ae211fe6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.9

Release files / prettypipeline_ocr-0.3.0-py3-none-any.whl

Download URL prettypipeline_ocr-0.3.0-py3-none-any.whl
Size 14.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c780acf5a55590ce3d298569ea033fce0eb88196aeb16fde8859afb370c5a7e5
BLAKE2b-256 checksum
How to use checksums
f79d70f42f74c5f24494bbd72df55fba71b289797df1c890972d91136c4b89b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.9

Security for prettypipeline-ocr 0.3.0

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