Skip to main content

pdfluent

Source on GitHub · Documentation · Report an issue

PDFluent for Python: a pure-Rust PDF SDK with no system dependencies, from a single pip install.

Render pages, extract text, fill forms, annotate, redact, encrypt, merge, and validate PDF/A — all from a single pip install.

Installation

pip install pdfluent

# Optional extras
pip install pdfluent[pillow]   # PIL Image support
pip install pdfluent[numpy]    # NumPy array support

Requires Python ≥ 3.8. Pre-built wheels for Linux (x86_64, aarch64), macOS (x86_64, arm64), and Windows (x86_64).

Quick Start

from pdfluent import Document

# Open, inspect, render
with Document("invoice.pdf") as doc:
    print(f"{doc.page_count} pages — {doc.metadata.title}")

    img = doc[0].render(dpi=150)
    img.save("page_0.png")          # requires Pillow

# Extract text
doc = Document("report.pdf")
for page in doc:
    print(page.extract_text())

# Fill a form field and save
doc = Document("form.pdf")
doc.set_form_field("Name", "Jane Doe")
# Multi-select list box: select several options at once
doc.set_multi_select("Languages", ["EN", "NL"])
doc.save("form_filled.pdf")

# Search-and-redact
doc = Document("contract.pdf")
report = doc.redact_text("Confidential")
print(f"Redacted {report.areas_redacted} areas on {report.pages_affected} pages")
doc.save("contract_redacted.pdf")

# PDF/A validation
from pdfluent import validate_pdfa

report = validate_pdfa("archive.pdf")
if report.is_compliant:
    print(f"✓ {report.pdfa_level} compliant")
else:
    for issue in report.issues:
        print(f"[{issue.severity}] {issue.rule}: {issue.message}")

# Merge PDFs
from pdfluent import merge_pdfs
merge_pdfs(["a.pdf", "b.pdf", "c.pdf"], "merged.pdf")

# Encrypt / decrypt
doc = Document("sensitive.pdf")
doc.encrypt("sensitive_enc.pdf", password="s3cr3t")

from pdfluent import decrypt_pdf
decrypt_pdf("sensitive_enc.pdf", "sensitive_dec.pdf", password="s3cr3t")

Features

Feature Description
Render Pages to RGBA pixels, PIL Images, or NumPy arrays at any DPI
Text extraction Plain text or structured TextBlock/TextSpan with position
Text search Find pages containing a query string
Forms (AcroForm) Read and fill text, checkbox, radio, combo/list fields; multi-select list boxes (set_multi_select); hierarchical names; appearance-stream regeneration
Annotations Read existing annotations; add highlights and free-text notes
Redaction Search-and-redact: black-box all occurrences of a string
Encryption AES-256 (PDF 2.0) encrypt/decrypt with user + owner passwords
Merge / split Merge multiple PDFs; split into individual pages (via page slicing)
PDF/A validation Validate against PDF/A-1B, 2B, 3B with issue-level reporting. Validation only: PDF/A conversion is not exposed here, and where it is exposed it delivers 1B, 2B and 3B
Metadata Read title, author, subject, keywords, creator, producer
Bookmarks Traverse the document outline tree
Thumbnails Fast downscaled preview images

API Overview

Document(source, password=None)

Opens a PDF from a file path (str) or raw bytes.

doc = Document("file.pdf")             # from path
doc = Document(open("file.pdf","rb").read())  # from bytes
doc = Document("encrypted.pdf", password="pw")

Methods: render_all(dpi), search(query), extract_text(page_num), save(path), get_form_fields(), set_form_field(name, value), get_annotations(page), add_annotation(page, type, rect, content), redact_text(term, page=None), encrypt(path, password), decrypt(path, password)
Protocols: len(doc), doc[0], for page in doc, with Document(...) as doc

AcroForm fill behaviour

set_form_field(name, value) supports text, checkbox, radio, and choice (combo/list) fields. Hierarchical names ("parent.child") are resolved through /Kids recursion. Every call keeps /V, /AS, and /AP consistent so the fill is visible in all PDF viewers without needing /NeedAppearances processing.

doc.set_form_field("Name", "Jane Doe")          # text field
doc.set_form_field("Agree", "On")               # checkbox — pass on-state name
doc.set_form_field("Country", "NL")             # radio group — export value
doc.set_form_field("Category", "Urgent")        # combo / list — option value
doc.save("form_filled.pdf")

Read-only fields raise PdfluentError.

Page

Properties: index, width, height, rotation, geometry
Methods: render(dpi, width, height, background), thumbnail(max_dimension), extract_text(), extract_text_blocks()

RenderedImage

Properties: width, height, pixels (raw RGBA bytes)
Methods: to_pil(), to_numpy(), save(path)

TextSpan

Structured text with position data.

Properties: text, x, y, font_size
Font metadata (optional): font_name, is_bold, is_italic, color

These fields return None in the current release. They are typed as Optional so downstream code handles the None case correctly today and will receive data once font-metadata extraction lands.

for block in page.extract_text_blocks():
    for span in block.spans:
        if span.font_name is not None:
            print(f"{span.font_name} {'bold' if span.is_bold else ''}")
        print(f"  '{span.text}' @ ({span.x:.1f}, {span.y:.1f})")

Quality tiers

Document.extract_markdown runs in the fast tier by default and takes quality="balanced" for the preview model tier, with model_dir= and table_model_dir= pointing it at directories outside the default. See Quality tiers.

Module-level functions

Function Description
open_pdf(path, password=None) Alias for Document(path)
merge_pdfs(paths, output) Merge a list of PDFs
validate_pdfa(path) → ComplianceReport Run PDF/A validation
decrypt_pdf(input, output, password) Decrypt to a new file

Exception Hierarchy

Every pdfluent-specific error derives from PdfluentError, so a single except PdfluentError: clause catches all library errors:

from pdfluent import PdfluentError, PdfluentParseError, PdfluentEncryptedError

try:
    with Document("broken.pdf") as doc:
        doc.render_all()
except PdfluentParseError as exc:
    print(f"Not a valid PDF: {exc}")
except PdfluentEncryptedError:
    print("PDF is password-protected")
except PdfluentError as exc:
    print(f"PDF error: {exc}")

Full hierarchy:

PdfluentError                 — base; catch all pdfluent errors
├── PdfluentParseError        — corrupt / non-PDF bytes
├── PdfluentValidationError   — schema / compliance failures
├── PdfluentRenderError       — rendering and XFA flatten failures
├── PdfluentEncryptedError    — operation blocked by encryption
├── PdfluentPageRangeError    — page index out of range
├── PdfluentIoError           — file-system I/O errors
├── PdfluentGeometryError     — invalid page geometry
└── PdfluentLimitError        — processing-limit exceeded

Typing Support

pdfluent ships with hand-written .pyi stub files for IDE completion and mypy --strict compatibility:

  • pdfluent/__init__.pyi — full public API stubs
  • pdfluent/_native.pyi — native extension stubs (for mypy without a build)

Verifying with mypy

pip install mypy
cd crates/pdf-python
mypy --strict --python-path python tests/test_pdfluent_typing.py

Example with typed annotations

from __future__ import annotations
from typing import Optional
from pdfluent import Document, TextSpan, PdfluentError

def get_font(span: TextSpan) -> Optional[str]:
    """Return the font name if available."""
    return span.font_name   # Optional[str] — mypy knows this may be None

def safe_open(path: str) -> Optional[Document]:
    try:
        return Document(path)
    except PdfluentError:
        return None

Licence

AGPL-3.0 or a commercial licence, at your option. The AGPL is the default and the complete product: there is no licence key, no activation call and no tier, and every feature works in every build. If you cannot accept the copyleft obligation, the commercial licence is sold yearly and self-service at pdfluent.com/sdk/pricing, in four options: Commercial (per organisation), OEM Startup and OEM (per product), and Priority support (an add-on). The two texts are LICENSE and LICENSE-COMMERCIAL in this crate.

Building from Source

Requires a Rust toolchain and maturin.

pip install maturin
cd crates/pdf-python
maturin develop --release          # install in current venv
maturin build --release            # build wheel in ./dist/

Metadata

Release files for pdfluent 1.2.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 pdfluent 1.2.0
File Size Uploaded Provenance
pdfluent-1.2.0.tar.gz 13.2 MB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for pdfluent 1.2.0
File
pdfluent-1.2.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
pdfluent-1.2.0-cp38-abi3-musllinux_1_2_x86_64.whl CPython 3.8 abi3 Linux musl 1.2+ x86-64 Details
pdfluent-1.2.0-cp38-abi3-musllinux_1_2_aarch64.whl CPython 3.8 abi3 Linux musl 1.2+ ARM64 Details
pdfluent-1.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
pdfluent-1.2.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
pdfluent-1.2.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
pdfluent-1.2.0-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 140.2 MB

Release files / pdfluent-1.2.0.tar.gz

Download URL pdfluent-1.2.0.tar.gz
Size 13.2 MB
Tags Source
SHA-256 checksum
How to use checksums
be6da1b0d58998e43cbf023a077eba78526b3d282eb1260505b629b176514399
BLAKE2b-256 checksum
How to use checksums
b25cc090c15edb652d69e73dfe206c3f6e44fbbd9a5bdc852d5a9f9a052052e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-win_amd64.whl

Download URL pdfluent-1.2.0-cp38-abi3-win_amd64.whl
Size 18.6 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
2c8329dfb13792186c69bab703bbf60decc376e2e6708fd42f1394fb5a7200be
BLAKE2b-256 checksum
How to use checksums
c832f57610fff4c993d404137fe4560953188d0bc46315440c7a0d94d177e4ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-musllinux_1_2_x86_64.whl

Download URL pdfluent-1.2.0-cp38-abi3-musllinux_1_2_x86_64.whl
Size 19.1 MB
Tags CPython 3.8 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
00a17def2c9f3b2d420fafcd096e3bdd8e9eff67e4fe23275ebca804de7e0159
BLAKE2b-256 checksum
How to use checksums
e2f633551b405f969b2051d19b16c8ac1f4ec4bf5c5447bce228cddd70166350
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-musllinux_1_2_aarch64.whl

Download URL pdfluent-1.2.0-cp38-abi3-musllinux_1_2_aarch64.whl
Size 17.5 MB
Tags CPython 3.8 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
24a9ba30bfbf246881ce34157083ca1593136602abbc76d2a771d4dc6b36a471
BLAKE2b-256 checksum
How to use checksums
4cd118a98e304ea46a831d593ee3f0cf904e778b6db37a1c70b7d4d996cb9907
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pdfluent-1.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 19.1 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
ac45648f67a38a481520f0d459613269ad2ca26c1c780c48fbc26d044f9e4093
BLAKE2b-256 checksum
How to use checksums
b1b8be36eb8da647d8647375996b39bb047b919047e479108e82e1fbc7512c3b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pdfluent-1.2.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 17.5 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
6cc083f454bccc22377a00dd23063d6f8f032708ebffd452d33c89e05876c717
BLAKE2b-256 checksum
How to use checksums
8c23a72e8156ef6014a87d05b82f04802f9c1dc9626758241096557bdba78523
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL pdfluent-1.2.0-cp38-abi3-macosx_11_0_arm64.whl
Size 17.2 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6b4d78225e19863108a67aea25199a6454ae67aa6a4fc709a3f2b0e9d3562c6a
BLAKE2b-256 checksum
How to use checksums
38d8fe7af4bd4148165e612cae62ba949c7339acd6b20f68cc75c086a45252e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / pdfluent-1.2.0-cp38-abi3-macosx_10_12_x86_64.whl

Download URL pdfluent-1.2.0-cp38-abi3-macosx_10_12_x86_64.whl
Size 18.1 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
7cceaf905b44796d1d9d69f3c7ef29fa100039e52ec71691985002652d2382ee
BLAKE2b-256 checksum
How to use checksums
d05babdd5a3796f37a5174dfcef4299564e353590c891698322d2b8f582143b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for pdfluent 1.2.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