High-level PDF transformations backed by Apache PDFBox
Project description
py-pdftools
py-pdftools is a Python library for high-level PDF transformations backed by
Apache PDFBox and compiled to a native library with GraalVM Native Image.
The initial release adds invisible, searchable OCR text layers to existing PDFs without requiring Java at runtime. It accepts provider-independent OCR lines, maps normalized visible-page coordinates through crop boxes and page rotation, fits and embeds Unicode text, and returns a new PDF as bytes.
Self-contained wheels are available from
PyPI for all five
supported platforms. The complete implementation passes native, Python,
installation, and installed-wheel smoke tests. See
PROGRESS.md for
the release verification record.
Installation
python -m pip install tindtechnologies-py-pdftools
The PyPI distribution is named tindtechnologies-py-pdftools; the Python
import remains py_pdftools.
Runtime requirements
- Python 3.10 or newer.
- A platform wheel matching Linux x86-64/ARM64, macOS x86-64/ARM64, or Windows x86-64.
- No Java, JVM, Gradle, Maven, or GraalVM installation.
To build a wheel from source, use
BUILDING.md.
Add an OCR text layer
from pathlib import Path
from py_pdftools import (
NormalizedRect,
OcrDocument,
OcrLine,
OcrPage,
OcrTextLayerOptions,
add_ocr_text_layer,
)
source = Path("scan.pdf").read_bytes()
ocr = OcrDocument(
pages=(
OcrPage(
page_index=0,
orientation=0,
lines=(
OcrLine(
text="Example OCR text",
bounds=NormalizedRect(
left=0.10,
top=0.20,
width=0.40,
height=0.03,
),
confidence=98.4,
),
),
),
),
)
result = add_ocr_text_layer(
source,
ocr,
options=OcrTextLayerOptions(minimum_confidence=80.0),
)
Path("searchable.pdf").write_bytes(result)
OCR bounds use normalized coordinates relative to the visible crop box after
page rotation. The origin is at the visible top-left. orientation is the OCR
text direction in that same visible coordinate system and must be one of 0,
90, 180, or 270: 0 = right, 90 = down, 180 = left, and 270 = up.
By default the OCR document must contain every PDF page exactly once. Set
allow_partial_document=True to modify only supplied pages. Lines below
minimum_confidence are skipped; lines without confidence are retained.
debug_visible_text=True renders the inserted text for placement diagnostics.
Copied or extracted OCR text preserves the exact Unicode sequence supplied in
each OcrLine, including character sequences that a font could render as a
typographic ligature.
Inspect page geometry
from pathlib import Path
from py_pdftools import inspect_pdf
info = inspect_pdf(Path("scan.pdf").read_bytes())
for page in info.pages:
print(
page.page_index,
page.width_points,
page.height_points,
page.rotation,
page.crop_box,
)
Visible width and height reflect the crop box after page rotation. Box coordinates themselves remain in PDF user space.
Behavior and limits
- Existing page streams are preserved and the OCR layer is appended.
- Normal OCR text uses PDF rendering mode 3 (neither fill nor stroke), while remaining searchable and extractable.
- Noto Sans is subset and embedded. Unsupported characters raise
FontErrorinstead of being silently replaced. - Ordinary left-to-right text is supported. Advanced bidirectional and complex script shaping is not guaranteed in version 0.1.
- The library consumes OCR results; it does not render pages or run an OCR engine.
- Password input is not supported. PDFs requiring a password raise
PdfPasswordRequiredError, and modification restrictions raisePdfPermissionError.
All public failures derive from PdfToolsError. More specific exceptions
distinguish invalid PDFs, invalid OCR data, page mismatches, font coverage,
permissions, native loading, and PDF processing failures.
License
Project code is licensed under the Apache License 2.0. The bundled Noto Sans
font is licensed separately under the SIL Open Font License 1.1. See
LICENSE,
NOTICE, and the
bundled third-party license texts for details.
Project documentation
SPECS.md— version 0.1 behavior and acceptance contract.BUILDING.md— local builds, tests, and platform wheels.docs/textract-normalization.md— convert Textract-shaped mappings without adding boto3 to the package.docs/native-abi-v1.md— private Python/native protocol.docs/releasing.md— wheel and publication checklist.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tindtechnologies_py_pdftools-0.1.2-py3-none-win_amd64.whl.
File metadata
- Download URL: tindtechnologies_py_pdftools-0.1.2-py3-none-win_amd64.whl
- Upload date:
- Size: 14.7 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60eb60ba49a0560a156abb6da54c024712a4573f6addba84ce1b5114ff1b08eb
|
|
| MD5 |
dd7c43b76a3008abd26d102389e384d8
|
|
| BLAKE2b-256 |
96d49b47912f6cf66d7ebaf1c19a8babd360b9d50c81d041c187077ca171ea3b
|
Provenance
The following attestation bundles were made for tindtechnologies_py_pdftools-0.1.2-py3-none-win_amd64.whl:
Publisher:
publish.yml on tind/py-pdftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tindtechnologies_py_pdftools-0.1.2-py3-none-win_amd64.whl -
Subject digest:
60eb60ba49a0560a156abb6da54c024712a4573f6addba84ce1b5114ff1b08eb - Sigstore transparency entry: 2182681463
- Sigstore integration time:
-
Permalink:
tind/py-pdftools@23991d1a30337ec6091a1c78deb2425c057b4058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tind
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23991d1a30337ec6091a1c78deb2425c057b4058 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 14.8 MB
- Tags: Python 3, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ea4972b961db27e414c462e7980903bfd2d955cf0b81fee3889a4bcb0ba958b
|
|
| MD5 |
80cf906787aab49bdb787f4efe274cb5
|
|
| BLAKE2b-256 |
36340121b6b9874a94c23e12fea2dd9e60e1aaf58291b92e5432e958a14cc910
|
Provenance
The following attestation bundles were made for tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tind/py-pdftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_x86_64.whl -
Subject digest:
2ea4972b961db27e414c462e7980903bfd2d955cf0b81fee3889a4bcb0ba958b - Sigstore transparency entry: 2182681835
- Sigstore integration time:
-
Permalink:
tind/py-pdftools@23991d1a30337ec6091a1c78deb2425c057b4058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tind
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23991d1a30337ec6091a1c78deb2425c057b4058 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 14.4 MB
- Tags: Python 3, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f347d7dbb7f957d4d0d12f792b97ce00e59a693c166dc4af8c0bcb2763c2e70
|
|
| MD5 |
f49c4e94b4ecf8b04fa87465614b3088
|
|
| BLAKE2b-256 |
f96b9cf3fb64026a621cb6af28264c4c725dafd034b2ea6919c31fadb33e6c0a
|
Provenance
The following attestation bundles were made for tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_aarch64.whl:
Publisher:
publish.yml on tind/py-pdftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tindtechnologies_py_pdftools-0.1.2-py3-none-manylinux_2_28_aarch64.whl -
Subject digest:
3f347d7dbb7f957d4d0d12f792b97ce00e59a693c166dc4af8c0bcb2763c2e70 - Sigstore transparency entry: 2182681232
- Sigstore integration time:
-
Permalink:
tind/py-pdftools@23991d1a30337ec6091a1c78deb2425c057b4058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tind
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23991d1a30337ec6091a1c78deb2425c057b4058 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 12.7 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a219a0d4ae5e04cb5286e4689db7de52e8f09063fba6ad32a35ca8a2e3225131
|
|
| MD5 |
36af6f2ffd5b109300127e6d382d18d1
|
|
| BLAKE2b-256 |
ab7f056152c4fcdf3762dae22ca490711ac7dccce9606b01b56795a984ab0c11
|
Provenance
The following attestation bundles were made for tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tind/py-pdftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_11_0_arm64.whl -
Subject digest:
a219a0d4ae5e04cb5286e4689db7de52e8f09063fba6ad32a35ca8a2e3225131 - Sigstore transparency entry: 2182681003
- Sigstore integration time:
-
Permalink:
tind/py-pdftools@23991d1a30337ec6091a1c78deb2425c057b4058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tind
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23991d1a30337ec6091a1c78deb2425c057b4058 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_10_15_x86_64.whl.
File metadata
- Download URL: tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_10_15_x86_64.whl
- Upload date:
- Size: 12.7 MB
- Tags: Python 3, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55dad1378c2ce36dcd54b74bf5b493f5356f8ca4214635c6ba6988a95c71a186
|
|
| MD5 |
892391b3639ca4dfb05887488618b668
|
|
| BLAKE2b-256 |
77ab6a2c41899622f89b6a20180788738368f327d5e6935913352f48511b19f9
|
Provenance
The following attestation bundles were made for tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_10_15_x86_64.whl:
Publisher:
publish.yml on tind/py-pdftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tindtechnologies_py_pdftools-0.1.2-py3-none-macosx_10_15_x86_64.whl -
Subject digest:
55dad1378c2ce36dcd54b74bf5b493f5356f8ca4214635c6ba6988a95c71a186 - Sigstore transparency entry: 2182681643
- Sigstore integration time:
-
Permalink:
tind/py-pdftools@23991d1a30337ec6091a1c78deb2425c057b4058 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tind
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23991d1a30337ec6091a1c78deb2425c057b4058 -
Trigger Event:
release
-
Statement type: