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 (unencrypted MOBI with no compression or PalmDOC compression)

PyMuPDF is the Python binding of MuPDF. It opens MOBI files with the same Document API it uses for PDF and EPUB: the book is laid out into pages that you can read as text, render or convert to PDF.

MOBI support comes from MuPDF and has the same limits: no HUFF/CDIC-compressed books, no DRM, and the text records are read as one HTML document (MOBI 6 style), without KF8 reconstruction or EXTH metadata. For complete MOBI and AZW3 unpacking use mobi. 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: extract text from a MOBI file#

Python
import pymupdf

try:
    doc = pymupdf.open("book.mobi")
except Exception as e:  # e.g. unknown compression method (HUFF/CDIC)
    raise SystemExit(f"cannot open: {e}")

doc.layout(width=420, height=595, fontsize=11)
print(doc.metadata["format"], doc.page_count, "pages")
text = "\n".join(page.get_text() for page in doc)
with open("book.txt", "w", encoding="utf-8") as f:
    f.write(text)

How to open .azw or .azw3 files#

MuPDF recognizes MOBI by the BOOKMOBI signature, and lists only .mobi, .prc and .pdb as MOBI extensions. To be safe with .azw and .azw3 files, pass the type explicitly:

Python
doc = pymupdf.open("book.azw3", filetype="mobi")

How to convert MOBI to PDF#

Python
import pymupdf

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

How to render the first page to PNG#

Python
doc = pymupdf.open("book.mobi")
doc[0].get_pixmap(dpi=150).save("page1.png")

How to search for a word in a MOBI book#

Python
for page in doc:
    hits = page.search_for("whale")
    if hits:
        print(f"page {page.number + 1}: {len(hits)} hits")

Tips#