Datagrunt 3.1.0: A Permissively-Licensed PDF Engine by Default
Datagrunt 3.0.0 introduced PDF parsing. With 3.1.0, the engine underneath it changes: PDFium is now the default, and it is permissively licensed.
Why the change
The 3.0.0 PDF stack was built on PyMuPDF — a capable library, but one licensed under AGPL-3.0 (or a commercial license from Artifex). AGPL’s copyleft terms are a real obstacle for a lot of teams, especially anyone embedding Datagrunt in a proprietary product or a hosted service.
So 3.1.0 moves the default to PDFium — Google’s PDF library, used via pypdfium2 — which is licensed under BSD-3 / Apache-2.0. Permissive, no copyleft, no commercial-license question.
| Engine | License |
|---|---|
PDFium (pypdfium2) — new default |
BSD-3 / Apache-2.0 |
| PyMuPDF — still available | AGPL-3.0 / commercial |
It’s a drop-in
The important part: your code doesn’t change. PDFReader and PDFWriter still return the same unified document schema they always have — same keys, same DataFrame columns, same JSON shape. Only the engine producing it is different (and permissive).
from datagrunt import PDFReader
# Same call as before — now powered by PDFium.
reader = PDFReader('report.pdf')
document = reader.to_dicts()
df = reader.to_dataframe()We verified this with a cross-engine parity test suite over real-world documents: identical page counts, byte-identical table content (table extraction runs through pdfplumber on both engines), matching image counts, and equal-or-better text completeness. On dense, graphically-complex PDFs, PDFium actually recovers more text than the old default.
A new lean mode
PDFium also unlocks a fast path. When you only need text and images — not reconstructed tables — pass native=True:
# Lean schema: full page text, positioned text objects, and images.
reader = PDFReader('report.pdf', native=True)This skips table detection entirely and is roughly 20-80x faster on multi-page documents. For a directory of single-page datasheets it parses in milliseconds each. Use the default mode when you want structured tables; use native=True when you just need the content fast.
OCR still works the same way — image-only and scanned pages fall back to Tesseract automatically, on either engine.
PyMuPDF is still here
Nothing was removed. If you specifically want PyMuPDF, ask for it:
reader = PDFReader('report.pdf', engine='pymupdf')Upgrading
uv pip install --upgrade "datagrunt[pdf]"
# or
pip install --upgrade "datagrunt[pdf]"The pdf extra now installs pypdfium2 alongside the existing dependencies. Existing PDF code keeps working unchanged — you just get a permissively-licensed engine by default, and a faster option when you want it.