All formats

PyMuPDF

LanguagePython 3.11+
LicenseAGPL-3.0 or commercial license from Artifex
Repositorygithub.com/pymupdf/PyMuPDF
Documentationpymupdf.readthedocs.io
Depends onMuPDF (bundled in the wheels)
Read / writeyes / no (.fb2)

PyMuPDF is the Python binding of MuPDF. It opens FB2 files with the same Document API it uses for PDF and EPUB: the book is laid out into pages with its cover, section titles, poems and notes styled, and every page can be read as text, searched, rendered or converted. The metadata gives the title, the authors and the annotation from title-info, and the table of contents comes from the section titles.

PyMuPDF doesn’t expose the FB2 XML and can’t write FB2; use the FB2 package to create books. Unzip .fb2.zip files first. The AGPL license requires you to publish your source code if you distribute your program or run it as a network service.

Installation#

Shell
pip install pymupdf

Basic usage: open an FB2 file and extract text#

Python
import pymupdf

doc = pymupdf.open("book.fb2")
doc.layout(width=420, height=595, fontsize=11)  # A5 page in points

meta = doc.metadata
print(meta["title"], "by", meta["author"])
print(doc.page_count, "pages")

with open("book.txt", "w", encoding="utf-8") as f:
    for page in doc:
        f.write(page.get_text())

How to read the table of contents#

Python
for level, title, page in doc.get_toc():
    print("  " * (level - 1) + f"{title} ... {page}")

How to open an FB2 from a .fb2.zip archive#

Python
import zipfile
import pymupdf

with zipfile.ZipFile("book.fb2.zip") as z:
    name = next(n for n in z.namelist() if n.lower().endswith(".fb2"))
    data = z.read(name)
doc = pymupdf.open(stream=data, filetype="fb2")

How to convert FB2 to PDF#

Python
doc = pymupdf.open("book.fb2")
doc.layout(width=420, height=595, fontsize=11)
pdf = pymupdf.open("pdf", doc.convert_to_pdf())
pdf.set_toc(doc.get_toc())
pdf.save("book.pdf", garbage=3, deflate=True)

How to save the cover as PNG#

The first page shows the coverpage image:

Python
doc[0].get_pixmap(dpi=150).save("cover.png")

Tips#