All formats

pikepdf

LanguagePython 3.11+ (C++ extension)
LicenseMPL-2.0
Repositorygithub.com/pikepdf/pikepdf
Documentationpikepdf.readthedocs.io
Depends onQPDF (bundled in the wheels), lxml, Pillow, packaging
Read / writeyes / yes: pages, objects, metadata (Info and XMP), encryption, attachments, outlines, repair; no text extraction or rendering

pikepdf wraps the QPDF C++ library: it opens a PDF as a tree of Python objects (pikepdf.Dictionary, Array, Name, Stream) that you can read and change directly, and writes the result with QPDF’s writer. That makes it reliable for structural work on real-world files: merging, splitting, reordering and rotating pages, encrypting with AES-256 and decrypting, editing XMP metadata, managing attachments, linearizing and compressing. Opening and saving a damaged file with pikepdf often repairs it. OCRmyPDF uses it.

pikepdf doesn’t extract text or render pages; combine it with pdfminer.six, pdfplumber or pypdfium2 for that.

Installation#

Shell
pip install pikepdf

Basic usage: merge PDF files#

Python
from pikepdf import Pdf

out = Pdf.new()
for path in ["a.pdf", "b.pdf"]:
    src = Pdf.open(path)
    out.pages.extend(src.pages)
out.save("merged.pdf")

Keep the source Pdf objects open until save(): pages copied from them are read lazily.

How to split a PDF into pages#

Python
from pikepdf import Pdf

with Pdf.open("in.pdf") as pdf:
    for n, page in enumerate(pdf.pages):
        dst = Pdf.new()
        dst.pages.append(page)
        dst.save(f"page-{n + 1}.pdf")

How to rotate and delete pages#

Python
from pikepdf import Pdf

with Pdf.open("in.pdf") as pdf:
    for page in pdf.pages:
        page.rotate(90, relative=True)
    del pdf.pages[-1]  # remove the last page
    pdf.save("out.pdf")

How to encrypt and decrypt a PDF#

Python
import pikepdf
from pikepdf import Pdf

with Pdf.open("in.pdf") as pdf:
    pdf.save("encrypted.pdf", encryption=pikepdf.Encryption(
        owner="owner", user="user", R=6,  # R=6 is AES-256
        allow=pikepdf.Permissions(extract=False)))

with Pdf.open("encrypted.pdf", password="owner") as pdf:
    pdf.save("decrypted.pdf")  # saved without encryption by default

How to read and edit PDF metadata#

Python
from pikepdf import Pdf

with Pdf.open("in.pdf", allow_overwriting_input=True) as pdf:
    print(pdf.pdf_version, len(pdf.pages), pdf.is_encrypted)
    print(pdf.docinfo.get("/Title"), pdf.docinfo.get("/Producer"))

    with pdf.open_metadata() as meta:  # XMP; also updates the Info dictionary
        meta["dc:title"] = "New title"
    pdf.save("in.pdf")

How to inspect PDF objects#

Python
from pikepdf import Pdf

with Pdf.open("in.pdf") as pdf:
    page = pdf.pages[0]
    print(page.mediabox)                  # [0, 0, 595.27, 841.89]
    print(page.obj.keys())                # raw page dictionary keys
    print(pdf.Root.keys())                # the catalog
    print(pdf.trailer.get("/ID"))
    for name, image in page.get_images().items():
        print(name, image.Width, image.Height, image.get("/Filter"))

Tips#