PrettyPipeline
Turn PDFs into structured JSON. Text comes from embedded PDF content or local OCR. Figures are segregated and sent directly to GPT-5.4 — never the whole PDF as one image. Export to CSV and common LLM fine-tuning formats.
Architecture
┌─────────────────────────────────────┐
│ PDF input │
└─────────────────┬───────────────────┘
│
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Embedded text │ │ Embedded figures │ │ Scan-only pages │
│ (digital PDF) │ │ (PyMuPDF crop) │ │ (low-res fallback│
└───────┬────────┘ └────────┬─────────┘ │ 120 DPI max) │
│ │ └────────┬─────────┘
│ │ │
│ ┌────────────┴────────────┐ │
│ │ NOT full-page images │ │
│ │ detail=low by default │ │
│ └────────────┬────────────┘ │
│ │ │
└───────────────────────────┼────────────────────────────┘
│
▼
┌────────────────────────┐
│ Embedded PDF text │
└───────────┬────────────┘
│ merge (dedupe)
┌───────────▼────────────┐
│ Baidu Unlimited-OCR │ ← default: always runs ([ocr] extra)
│ (full document) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Combined document text │
│ + segregated figures │──► GPT-5.4 nano
└────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────────┐ ┌──────────────┐
│ JSON │ │needs_review │ │Export formats│
│ + _meta │ │ flags │ │ csv alpaca… │
└─────────┘ └─────────────┘ └──────────────┘
Local OCR (Unlimited-OCR) runs on every document by default (requires [ocr] extra),
merged with embedded PDF text so nothing is missed — text in images, stamps, scan layers.
Use --embedded-only to skip OCR (faster). Use --force-ocr for OCR-only.
Why this is cheap
- Digital PDFs — embedded text is free and accurate; no GPU needed.
- Figures only — segregated embedded images go to GPT vision at
detail=low(not full-page raster). - Baidu OCR + merge — full-document OCR merged with embedded text by default (
[ocr]extra). - GPT-5.4 nano — ~$0.20 / 1M input tokens for structuring (pricing).
Install
Python 3.10–3.13 (3.12 recommended).
# Digital PDFs + GPT vision (smallest install)
pip install prettypipeline-ocr
# + local OCR for scans
pip install prettypipeline-ocr[ocr]
From this repo:
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[ocr,dev]"
NVIDIA Linux:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
pip install prettypipeline-ocr[ocr]
Docker (CUDA): see Dockerfile.cuda.
Quick start
export OPENAI_API_KEY=sk-...
# Extract JSON (text + segregated figures → GPT)
prettypipeline run invoice.pdf --schema examples/invoice.schema.json
# Also export fine-tuning formats
prettypipeline run invoice.pdf --schema examples/invoice.schema.json \
-o out.json --export csv,alpaca,sharegpt,openai,qa
# Convert existing JSON to a training file
prettypipeline export out.json --schema examples/invoice.schema.json \
--format sharegpt -o train.jsonl
Demo invoice:
prettypipeline run tests/fixtures/sample_invoice.pdf \
--schema examples/invoice.schema.json -o out.json
Figure segregation (vision)
PrettyPipeline does not rasterize entire PDF pages for GPT unless a page is scan-only with no embedded figures.
| Page type | Text source | Vision sent to GPT |
|---|---|---|
| Digital + figures | Embedded PDF text | Embedded figures only (detail=low) |
| Digital, no figures | Embedded PDF text | Nothing |
| Scan, no figures | Local OCR or low-res page | One low-res page image (120 DPI) |
--no-vision |
Same as above | Disabled |
Images are visual context only — no CSV or table dump is generated from figures.
Export formats (LLM training)
| Format | File | Use case |
|---|---|---|
csv |
.csv |
Spreadsheets, flat field/value |
alpaca |
.alpaca.jsonl |
Instruction tuning (LLaMA-Factory, Axolotl) |
sharegpt |
.sharegpt.jsonl |
Multi-turn chat fine-tuning |
openai |
.openai.jsonl |
OpenAI fine-tuning messages format |
qa |
.qa.jsonl |
Simple question/answer pairs |
ShareGPT and OpenAI JSONL are preferred for chat models in 2026; Alpaca for single-turn extraction tasks.
Schema examples
| File | Use case |
|---|---|
examples/invoice.schema.json |
Invoices |
examples/receipt.schema.json |
Receipts |
examples/purchase_order.schema.json |
Purchase orders |
CLI
prettypipeline run FILE.pdf --schema SCHEMA.json
-o, --output PATH JSON output (also printed)
--export csv,alpaca,... comma-separated training exports
--no-vision skip figure images to GPT
--image-detail low|auto|high vision token budget (default: low)
--embedded-only skip Baidu OCR supplement (embedded text only)
--force-ocr OCR only — ignore embedded text
--model, --base-url LLM settings
prettypipeline batch FILES... --schema SCHEMA.json --output-dir DIR
prettypipeline export RESULT.json --schema SCHEMA.json --format FORMAT -o OUT
Environment: OPENAI_API_KEY, PRETTYPIPELINE_MODEL, PRETTYPIPELINE_BASE_URL.
Output
{
"data": { "invoice_number": "INV-3337", "total": 93.5 },
"needs_review": [],
"source": "pdf_text",
"_meta": {
"version": "0.4.1",
"elapsed_ms": 3200,
"pages": 1,
"vision_images": 1,
"segments": { "text_chars": 842, "figures": 1 },
"token_usage": { "prompt_tokens": 1100, "completion_tokens": 95, "total_tokens": 1195 }
}
}
Programmatic use
from prettypipeline import run, segment_pdf, to_csv
result = run("invoice.pdf", "examples/invoice.schema.json", export_formats=["alpaca"], export_stem=Path("out.json"))
seg = segment_pdf("invoice.pdf") # inspect text vs figures before calling GPT
Hardware
| Device | Role |
|---|---|
| NVIDIA CUDA | Recommended for local OCR ([ocr] extra) |
| Apple Silicon MPS | OCR supported; --force-ocr may degrade |
| CPU | OCR works, slow |
| None | Digital PDFs + GPT vision work without GPU |
Development
pip install -e ".[ocr,dev]"
pytest
python -m build && twine check dist/*
License
MIT. Unlimited-OCR is also MIT.
Fixtures: Sliced Invoices sample, IRS Form W-9.
Metadata
Release files for prettypipeline-ocr 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| prettypipeline_ocr-0.4.1.tar.gz | 22.8 kB | Without provenance | Details for prettypipeline_ocr-0.4.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| prettypipeline_ocr-0.4.1-py3-none-any.whl | Python 3 | none | any | Details for prettypipeline_ocr-0.4.1-py3-none-any.whl |
Total release size: 43.8 kB
Release files / prettypipeline_ocr-0.4.1.tar.gz
| Download URL | prettypipeline_ocr-0.4.1.tar.gz |
|---|---|
| Size | 22.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d409b4774c0423e36e913bd30726ab39759673c5373f4e987edc633582e7cf8b
|
|
BLAKE2b-256 checksum How to use checksums |
7d59af18cf0c992566885010039c6c892ce6aabffa6e07ac14240a32414e0f01
|
| 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.4.1-py3-none-any.whl
| Download URL | prettypipeline_ocr-0.4.1-py3-none-any.whl |
|---|---|
| Size | 21.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cb69b3cf6db621c320a878637748fd170c7d2163340622e8232b026382ea1c05
|
|
BLAKE2b-256 checksum How to use checksums |
8e8f73751c76f3ac4a804e94e696001ac7c9a7e260dd2606d9037448f8c1a5c3
|
| 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.4.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.