pypdfium2

ABI-level Python bindings to PDFium for fast, liberal-licensed PDF rendering and manipulation.

Library
PyPI
v5.13.0
809stars
Apache-2.0 OR BSD-3-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
85/100Excellent
Development Activity100
Maintenance100
Community44
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture82
Code Quality75
Innovation85
Learning Curve85

pypdfium2 is an ABI-level Python 3 binding to PDFium, Google’s PDF rendering engine, built with a custom ctypesgen fork and distributed with pre-built platform binaries covering nearly all common OSes and architectures. It combines a low-level raw ctypes API with a Pythonic “support model” of helper classes for opening documents, rendering pages to bitmaps, extracting and searching text, walking the table of contents, editing page content, and creating new PDFs from scratch.

Because PDFium and pypdfium2’s own code are liberally licensed (Apache-2.0/BSD-3-Clause), pypdfium2 is one of the few Python PDF-rendering libraries not encumbered by strong copyleft licensing, making it a common choice for both open-source and closed-source projects that need to rasterize, inspect, or generate PDFs without licensing friction.

What You Get

  • A high-level PdfDocument/PdfPage API for opening, rendering, editing, and saving PDFs without touching ctypes directly
  • Pre-built PDFium binaries for a wide range of platforms (including musl, Android, and V8/XFA-enabled builds), so most installs need no compiler
  • Raw, ABI-level access to the full PDFium C API via pypdfium2.raw for anything the helpers don’t cover yet
  • A bundled pypdfium2 command-line tool for rendering, text/image extraction, TOC inspection, and page arrangement from the shell

Common Use Cases

  • Rendering PDF pages to raster images (PIL or NumPy arrays) for previews, thumbnails, or OCR pipelines
  • Extracting and searching text content from PDFs for indexing or data-extraction workflows
  • Programmatically assembling or editing PDFs, e.g. inserting images/pages or adjusting page rotation
  • Batch PDF inspection and processing from the command line using the bundled CLI

Under The Hood

Architecture pypdfium2 is layered into three packages under src/: pypdfium2_raw holds the ctypes bindings generated directly from PDFium’s C headers by a pypdfium2-team fork of ctypesgen, pypdfium2 wraps those raw bindings in a Pythonic “support model” (src/pypdfium2/_helpers/{document,page,bitmap,textpage,pageobjects,attachment,matrix}.py), and pypdfium2_cli exposes the same functionality as command-line subcommands (render, extract-text, extract-images, toc, arrange, tile, pageobjects, attachments, pdfinfo). Library lifecycle is centralized in _library_scope.py, which calls FPDF_InitLibraryWithConfig() on import and registers an atexit handler that walks a weakref-based ObjectTracker (internal/bases.py) to force-close any PdfDocument, PdfPage, or PdfBitmap objects the caller forgot to close before FPDF_DestroyLibrary() runs, avoiding native memory leaks and use-after-free crashes at process exit.

Tech Stack The package has no mandatory runtime dependencies beyond Python itself and a bundled PDFium shared library fetched from bblanchon/pdfium-binaries; optional Pillow, NumPy, and opencv-python are imported lazily for bitmap/image conversion helpers and CLI image output, and tabulate improves CLI table formatting. Building from source uses a dynamic setup.py (rather than static pyproject.toml metadata, since the package name itself varies per platform target) plus the pypdfium2-team ctypesgen fork and packaging as declared setup-group dependencies; a justfile and PLATFORMS.csv drive a cross-platform wheel matrix (20+ platform targets including musl, Android/Termux, and V8/XFA-enabled builds), with cibuildwheel used in CI.

Code Quality Testing lives under tests/ with 14 pytest modules covering document opening (test_opener.py), page and text extraction (test_page.py, test_textpage.py), rendering (test_rendering.py), page-object introspection (test_pageobjects.py), attachments, saving, table-of-contents parsing, and the CLI itself (test_cli.py), run via python -m pytest tests/ or just test, with coverage tooling (just coverage). Source files carry extensive reStructuredText/Sphinx-style docstrings with typed parameter descriptions, though the codebase relies on ctypes rather than static type hints for the raw bindings layer. Error handling is explicit — PdfiumError wraps PDFium’s own error codes and a PdfiumWarning class flags recoverable issues — and every source file carries an SPDX license header enforced via the REUSE.toml manifest and reuse tooling in CI.

API Design The support-model API is deliberately ergonomic: PdfDocument supports list-index access to load pages, len() for page counts, iteration, and with-block context management for deterministic cleanup, while helper objects transparently resolve to their underlying raw ctypes handles when passed into raw PDFium calls (pdfium_c.FPDF_GetDocPermission(pdf) works without an explicit .raw access). This lets callers start with three lines of code (pdfium.PdfDocument(path), pdf[0], page.render()) and progressively drop down to the raw PDFium API via pypdfium2.raw for anything the helpers don’t yet cover, without switching libraries. The bundled CLI mirrors the Python API’s capabilities for quick shell-based PDF inspection and batch processing, and extensive README examples (image extraction, TOC walking, PDF creation) lower the barrier for both entry points.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search