All formats

PyMuPDF

LanguagePython 3.11+ (current 2.x releases)
LicenseAGPL-3.0 or commercial from Artifex
Repositorygithub.com/pymupdf/PyMuPDF
Documentationpymupdf.readthedocs.io
Depends onMuPDF (included in the wheels)
Read / writeyes / yes: text, images, rendering, tables, merge, split, rotate, create, annotations, forms, redaction, encryption

PyMuPDF exposes MuPDF to Python. It extracts text faster than any pure-Python library, with several output formats (plain text, blocks, words with coordinates, a dict/JSON tree with fonts and spans), renders pages to images without other dependencies, finds tables, and edits documents: insert and delete pages, insert text and images, annotations, form fields, redactions, metadata, encryption. It also opens XPS, EPUB, MOBI, CBZ and images. The import name is pymupdf (the old name fitz still works but is deprecated).

PyMuPDF is AGPL-3.0: if you distribute your application or run it as a network service, you must release its source under the AGPL, or buy a commercial license from Artifex. The pages are numbered from 0.

Installation#

Shell
pip install pymupdf

Wheels with MuPDF built in are available for Windows, macOS and Linux.

Basic usage: extract text from a PDF#

Python
import pymupdf

doc = pymupdf.open("in.pdf")
print(doc.page_count, "pages")
for page in doc:
    print(f"--- page {page.number + 1} ---")
    print(page.get_text())
doc.close()

page.get_text("words") returns (x0, y0, x1, y1, word, block, line, word_no) tuples; page.get_text("dict") returns blocks, lines and spans with fonts, sizes and colors.

How to render a PDF page to an image#

Python
import pymupdf

doc = pymupdf.open("in.pdf")
pix = doc[0].get_pixmap(dpi=150)
pix.save("page1.png")

How to merge and split PDFs#

Python
import pymupdf

out = pymupdf.open()  # new, empty PDF
for path in ["a.pdf", "b.pdf"]:
    with pymupdf.open(path) as src:
        out.insert_pdf(src)
out.save("merged.pdf")

src = pymupdf.open("merged.pdf")
for i in range(src.page_count):
    single = pymupdf.open()
    single.insert_pdf(src, from_page=i, to_page=i)
    single.save(f"page-{i + 1}.pdf")

doc.select([0, 2, 4]) keeps only the listed pages, in that order.

How to create a PDF with text#

Python
import pymupdf

doc = pymupdf.open()
page = doc.new_page(width=595, height=842)  # A4 in points
page.insert_text((72, 72), "Hello, PDF!", fontsize=24, fontname="helv")  # origin is top-left
rect = pymupdf.Rect(72, 100, 523, 300)
page.insert_textbox(rect, "A longer paragraph that wraps inside the rectangle. " * 5, fontsize=11)
doc.set_metadata({"title": "Hello", "author": "Me"})
doc.save("hello.pdf")

How to rotate pages and read metadata#

Python
import pymupdf

doc = pymupdf.open("in.pdf")
print(doc.metadata)  # {'format': 'PDF 1.7', 'title': ..., 'author': ..., 'producer': ..., ...}
for page in doc:
    page.set_rotation((page.rotation + 90) % 360)
doc.save("rotated.pdf")

How to fill a PDF form#

Python
import pymupdf

doc = pymupdf.open("form.pdf")
for page in doc:
    for widget in page.widgets():
        print(widget.field_name, widget.field_type_string, widget.field_value)
        if widget.field_name == "name":
            widget.field_value = "Jane Doe"
            widget.update()
doc.save("filled.pdf")

How to encrypt and decrypt a PDF#

Python
import pymupdf

doc = pymupdf.open("in.pdf")
doc.save("encrypted.pdf",
         encryption=pymupdf.PDF_ENCRYPT_AES_256,
         owner_pw="owner", user_pw="user",
         permissions=pymupdf.PDF_PERM_PRINT | pymupdf.PDF_PERM_COPY)

doc = pymupdf.open("encrypted.pdf")
if doc.needs_pass:
    doc.authenticate("owner")
doc.save("decrypted.pdf", encryption=pymupdf.PDF_ENCRYPT_NONE)

Tips#