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.1.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.1.0
File Size Uploaded Provenance
pdfluent-1.1.0.tar.gz 12.2 MB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for pdfluent 1.1.0
File
pdfluent-1.1.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
pdfluent-1.1.0-cp38-abi3-musllinux_1_2_x86_64.whl CPython 3.8 abi3 Linux musl 1.2+ x86-64 Details
pdfluent-1.1.0-cp38-abi3-musllinux_1_2_aarch64.whl CPython 3.8 abi3 Linux musl 1.2+ ARM64 Details
pdfluent-1.1.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.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
pdfluent-1.1.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
pdfluent-1.1.0-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 137.2 MB

Release files / pdfluent-1.1.0.tar.gz

Download URL pdfluent-1.1.0.tar.gz
Size 12.2 MB
Tags Source
SHA-256 checksum
How to use checksums
3efe8cd524171cb3dc9ff742635137f87fe45a832b1788c3ecb2839d1d271674
BLAKE2b-256 checksum
How to use checksums
bcb221a987b06f24cad3db99fd213743a0a877050b7d73bb2fe05825bc9e50f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

Download URL pdfluent-1.1.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
26cba856a9773da1b10ba0de52248fa3582f6a0ec6277126ad3a4b63f876fe26
BLAKE2b-256 checksum
How to use checksums
d6bf045f67f6c8eacdc9583eeeab7d4205449a304e25e639e53c0400302ee291
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

Download URL pdfluent-1.1.0-cp38-abi3-musllinux_1_2_x86_64.whl
Size 18.7 MB
Tags CPython 3.8 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
7805953e641fe3a3244fd710d8d4e673a83bbe85882aab75bc8f24b54fd623f0
BLAKE2b-256 checksum
How to use checksums
e55cf1ee9a485216f766760ec3d26849857c7adecd4fcb342393bb0bfb951b6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

Download URL pdfluent-1.1.0-cp38-abi3-musllinux_1_2_aarch64.whl
Size 17.1 MB
Tags CPython 3.8 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
ab3be6e0088db88a17d58993956be4b42d5da85fe95599154ec910c2683b929a
BLAKE2b-256 checksum
How to use checksums
39fecc6f25d7802b58796ced3e72cd101013ac7c365c646ea73e1dc2d14e2526
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

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

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

Download URL pdfluent-1.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 17.1 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
ee273ac65762f743d3d5fb72652bdcbbd48a8080bfa76cbaa4143a5763227da2
BLAKE2b-256 checksum
How to use checksums
45cd2206bccb1296d160cbc1a61b3913ca5226c60499b289e87c938f9e5048ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

Download URL pdfluent-1.1.0-cp38-abi3-macosx_11_0_arm64.whl
Size 16.8 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3b352fbf644aa3abad66a0d2c0609305737ed5b316e0091b1a6f4a0af5e9baa9
BLAKE2b-256 checksum
How to use checksums
db06efcab1905820cb559831c0322478273b426da31cbc2dda2d1fe8a05b4dfe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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

Download URL pdfluent-1.1.0-cp38-abi3-macosx_10_12_x86_64.whl
Size 17.8 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
16caa79d0bf27560a4ec6c50a724e34c4a891a40902e10630c41fbd3bf906232
BLAKE2b-256 checksum
How to use checksums
9881bff5226c84167b3c59ce8b980edbea70c7c96c78c8e05d82c09578779b61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

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