PyMuPDF
| Language | Python 3.11+ (current 2.x releases) |
|---|---|
| License | AGPL-3.0 or commercial from Artifex |
| Repository | github.com/pymupdf/PyMuPDF |
| Documentation | pymupdf.readthedocs.io |
| Depends on | MuPDF (included in the wheels) |
| Read / write | yes / 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#
pip install pymupdf
Wheels with MuPDF built in are available for Windows, macOS and Linux.
Basic usage: extract text from a PDF#
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#
import pymupdf
doc = pymupdf.open("in.pdf")
pix = doc[0].get_pixmap(dpi=150)
pix.save("page1.png")
How to merge and split PDFs#
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#
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#
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#
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#
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#
page.find_tables()detects tables;table.extract()returns rows andtable.to_pandas()a DataFrame.page.search_for("text")returns the rectangles of every match; combine withpage.add_redact_annot(rect)andpage.apply_redactions()to remove content permanently.doc.save(path, garbage=4, deflate=True)removes unused and duplicate objects and compresses streams.- For text extraction optimized for LLM pipelines (Markdown output), see the separate
pymupdf4llmpackage.