feat: add psagentai agent with deployment and configuration
Initial project setup including the main agent script, configuration files, profile JSON state, systemd service unit, startup script, deployment documentation, and Python dependencies. Includes .env, venv/, and __pycache__/ which should likely be excluded via .gitignore to avoid committing secrets and artifacts.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Dual Licensed - GNU AFFERO GPL 3.0 or Artifex Commercial License
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,806 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pymupdf
|
||||
Version: 1.28.0
|
||||
Summary: A high performance Python library for data extraction, analysis, conversion & manipulation of PDF (and other) documents.
|
||||
Description-Content-Type: text/markdown
|
||||
Author: Artifex
|
||||
Author-email: support@artifex.com
|
||||
License: Dual Licensed - GNU AFFERO GPL 3.0 or Artifex Commercial License
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Intended Audience :: Information Technology
|
||||
Classifier: Operating System :: MacOS
|
||||
Classifier: Operating System :: Microsoft :: Windows
|
||||
Classifier: Operating System :: POSIX :: Linux
|
||||
Classifier: Programming Language :: C
|
||||
Classifier: Programming Language :: C++
|
||||
Classifier: Programming Language :: Python :: 3 :: Only
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Topic :: Utilities
|
||||
Classifier: Topic :: Multimedia :: Graphics
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Requires-Python: >=3.10
|
||||
Project-URL: Documentation, https://pymupdf.readthedocs.io/
|
||||
Project-URL: Source, https://github.com/pymupdf/pymupdf
|
||||
Project-URL: Tracker, https://github.com/pymupdf/PyMuPDF/issues
|
||||
Project-URL: Changelog, https://pymupdf.readthedocs.io/en/latest/changes.html
|
||||
|
||||
<p align="center">
|
||||
<a href="https://pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=logo&utm_term=website">
|
||||
<img loading="lazy" alt="PyMuPDF" src="https://pymupdf.pro/images/py-mupdf-github-icon.png" width="96px" alt="PyMuPDF logo"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# PyMuPDF
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/11536" target="_blank"><img src="https://trendshift.io/api/badge/repositories/11536" alt="pymupdf%2FPyMuPDF | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
</p>
|
||||
|
||||
[](https://pymupdf.readthedocs.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=docs)
|
||||
[](https://pypi.org/project/PyMuPDF/)
|
||||
[](https://pypi.org/project/pymupdf/)
|
||||
[](https://github.com/pymupdf/PyMuPDF/blob/master/COPYING)
|
||||
[](https://pepy.tech/projects/pymupdf)
|
||||
[](https://github.com/pymupdf/PyMuPDF/stargazers)
|
||||
[](https://artifex.com/discord/artifex?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=discord)
|
||||
[](https://forum.mupdf.com/c/general/4?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=forum)
|
||||
[](https://x.com/pymupdf4llm)
|
||||
[](https://huggingface.co/artifex-software)
|
||||
[](https://demo.pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=demo)
|
||||
|
||||
**The PDF engine behind over 50 million monthly downloads, powering AI pipelines worldwide.**
|
||||
|
||||
**PyMuPDF is a high-performance Python library for data extraction, analysis, conversion, rendering and manipulation of PDF (and other) documents.** Built on top of MuPDF — a lightweight, fast C engine — PyMuPDF gives you precise, low-level control over documents alongside high-level convenience APIs. No mandatory external dependencies.
|
||||
|
||||
[](https://github.com/pymupdf/PyMuPDF/)
|
||||
|
||||
---
|
||||
|
||||
## Why PyMuPDF?
|
||||
|
||||
- **Fast** — powered by [MuPDF](https://mupdf.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=mupdf), a best-in-class C rendering engine
|
||||
- **Accurate** — pixel-perfect text extraction with font, color, and position metadata
|
||||
- **Versatile** — read, write, annotate, redact, merge, split, and convert documents
|
||||
- **LLM-ready** — native Markdown output via [PyMuPDF4LLM](https://pdf4llm.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=pymupdf4llm) for RAG and AI pipelines
|
||||
- **No mandatory dependencies** — `pip install pymupdf` and you're done
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install pymupdf
|
||||
```
|
||||
|
||||
Wheels are available for **Windows**, **macOS**, and **Linux** on Python 3.10–3.14. If no pre-built wheel exists for your platform, pip will compile from source (requires a C/C++ toolchain).
|
||||
|
||||
### Optional extras
|
||||
|
||||
| Package | Purpose |
|
||||
|---|---|
|
||||
| `pymupdf-fonts` | Extended font collection for text output |
|
||||
| `pymupdf4llm` | LLM/RAG-optimised Markdown and JSON extraction |
|
||||
| `pymupdfpro` | Adds Office document support |
|
||||
| `tesseract-ocr` | OCR for scanned pages and images (separate install) |
|
||||
|
||||
```bash
|
||||
# More fonts
|
||||
pip install pymupdf-fonts
|
||||
|
||||
# LLM-ready extraction
|
||||
pip install pymupdf4llm
|
||||
|
||||
# Office support
|
||||
pip install pymupdfpro
|
||||
|
||||
# OCR (Tesseract must be installed separately)
|
||||
# macOS
|
||||
brew install tesseract
|
||||
|
||||
# Ubuntu / Debian
|
||||
sudo apt install tesseract-ocr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Supported File Formats
|
||||
|
||||
### Input
|
||||
|
||||
| Category | Formats |
|
||||
|---|---|
|
||||
| PDF & derivatives | PDF, XPS, EPUB, CBZ, MOBI, FB2, SVG, TXT, MD |
|
||||
| Images | PNG, JPEG, BMP, TIFF, GIF, and more |
|
||||
| Microsoft Office *(Pro)* | DOC, DOCX, XLS, XLSX, PPT, PPTX |
|
||||
| Korean Office *(Pro)* | HWP, HWPX |
|
||||
|
||||
### Output
|
||||
|
||||
| Format | Notes |
|
||||
|---|---|
|
||||
| PDF | Full fidelity conversion from Office formats |
|
||||
| SVG | Vector page rendering |
|
||||
| Image (PNG, JPEG, …) | Page rasterisation at any DPI |
|
||||
| Markdown | Structure-aware, LLM-ready |
|
||||
| JSON | Bounding boxes, layout data, per-element detail |
|
||||
| Plain text | Fast, lightweight extraction |
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
### Extract text
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for page in doc:
|
||||
print(page.get_text())
|
||||
```
|
||||
|
||||
### Extract text with layout metadata
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
page = doc[0]
|
||||
|
||||
blocks = page.get_text("dict")["blocks"]
|
||||
for block in blocks:
|
||||
if block["type"] == 0: # text block
|
||||
for line in block["lines"]:
|
||||
for span in line["spans"]:
|
||||
print(f"{span['text']!r} font={span['font']} size={span['size']:.1f}")
|
||||
```
|
||||
|
||||
### Extract tables
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("spreadsheet.pdf")
|
||||
page = doc[0]
|
||||
|
||||
tables = page.find_tables()
|
||||
for table in tables:
|
||||
print(table.to_markdown())
|
||||
|
||||
# or get as Pandas DataFrame
|
||||
df = table.to_pandas()
|
||||
```
|
||||
|
||||
### Render a page to an image
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
page = doc[0]
|
||||
|
||||
pixmap = page.get_pixmap(dpi=150)
|
||||
pixmap.save("page_0.png")
|
||||
```
|
||||
|
||||
### OCR a scanned document
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("scanned.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Requires Tesseract installed and on PATH
|
||||
text = page.get_textpage_ocr(language="eng").extractText()
|
||||
print(text)
|
||||
```
|
||||
|
||||
### Convert Markdown to PDF
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
md_doc = pymupdf.open("example.md")
|
||||
md_doc.save("example.pdf")
|
||||
```
|
||||
|
||||
### Convert to Markdown for LLMs
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
|
||||
md = pymupdf4llm.to_markdown("report.pdf")
|
||||
# Pass directly to your LLM or vector store
|
||||
print(md)
|
||||
```
|
||||
|
||||
### Annotate and redact
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("contract.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Add a highlight annotation
|
||||
rect = pymupdf.Rect(72, 100, 400, 120)
|
||||
page.add_highlight_annot(rect)
|
||||
|
||||
# Add a redaction and apply it
|
||||
page.add_redact_annot(rect)
|
||||
page.apply_redactions()
|
||||
|
||||
doc.save("contract_redacted.pdf")
|
||||
```
|
||||
|
||||
### Merge PDFs
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
merger = pymupdf.open()
|
||||
for path in ["part1.pdf", "part2.pdf", "part3.pdf"]:
|
||||
merger.insert_pdf(pymupdf.open(path))
|
||||
|
||||
merger.save("merged.pdf")
|
||||
```
|
||||
|
||||
### Convert an Office document to PDF
|
||||
|
||||
```python
|
||||
import pymupdf.pro
|
||||
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
doc = pymupdf.open("presentation.pptx")
|
||||
pdf_bytes = doc.convert_to_pdf()
|
||||
|
||||
with open("output.pdf", "wb") as f:
|
||||
f.write(pdf_bytes)
|
||||
```
|
||||
|
||||
### Extract LLM-ready Markdown from a Word document
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
import pymupdf.pro
|
||||
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
md = pymupdf4llm.to_markdown("document.docx")
|
||||
print(md)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
### Core capabilities
|
||||
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| **Text extraction** | Plain text, rich dict (font, size, color, bbox), HTML, XML, raw blocks |
|
||||
| **Table detection** | `find_tables()` — locate, extract, and export tables as Markdown or structured data |
|
||||
| **Image extraction** | Extract embedded images and render any page to a high-resolution `Pixmap` |
|
||||
| **Rendering** | Render PDF pages to images or `Pixmap` data for use in UI or other workflows |
|
||||
| **OCR** | Tesseract integration — full-page or partial OCR, configurable language |
|
||||
| **Annotations** | Read and write highlights, underlines, squiggly lines, sticky notes, free text, ink, stamps |
|
||||
| **Redaction** | Add and permanently apply redaction annotations |
|
||||
| **Forms** | Read and fill PDF AcroForm fields |
|
||||
| **PDF creation** | Create PDFs directly with the API or quickly convert from Markdown files |
|
||||
| **PDF editing** | Insert, delete, and reorder pages; set metadata; merge and split documents |
|
||||
| **Drawing** | Draw lines, curves, rectangles, and circles; insert HTML boxes |
|
||||
| **Encryption** | Open password-protected PDFs; save with RC4 or AES encryption |
|
||||
| **Links** | Extract hyperlinks, internal cross-references, and URI targets |
|
||||
| **Bookmarks** | Read and write the outline / table of contents tree |
|
||||
| **Metadata** | Title, author, creation date, producer, subject, and custom entries |
|
||||
| **Color spaces** | RGB, CMYK, greyscale; color space conversion |
|
||||
|
||||
### LLM & AI output (via PyMuPDF4LLM)
|
||||
|
||||
| Output | API |
|
||||
|---|---|
|
||||
| Markdown | `pymupdf4llm.to_markdown(path)` |
|
||||
| JSON | `pymupdf4llm.to_json(path)` |
|
||||
| Plain text | `pymupdf4llm.to_text(path)` |
|
||||
|
||||
Supports multi-column layouts, natural reading order and page chunking.
|
||||
|
||||
|
||||
[](https://demo.pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=demo)
|
||||
|
||||
---
|
||||
|
||||
## Supported Python versions
|
||||
|
||||
Python **3.10 – 3.14** (as of v1.27.x). Wheels ship for:
|
||||
|
||||
- `manylinux` x86\_64 and aarch64
|
||||
- `musllinux` x86\_64
|
||||
- macOS x86\_64 and arm64
|
||||
- Windows x86 and x86\_64
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
PyMuPDF is built on MuPDF — one of the fastest PDF rendering engines available. Typical benchmarks against pure-Python PDF libraries show **10–50× speed improvements** for text extraction and **100× or more** for page rendering, with a minimal memory footprint.
|
||||
|
||||
For AI workloads, PyMuPDF4LLM processes documents **without a GPU**, cutting infrastructure costs significantly compared to vision-based LLM approaches.
|
||||
|
||||
---
|
||||
|
||||
## Recipes
|
||||
|
||||
<details>
|
||||
<summary>Extract all images from a PDF</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
from pathlib import Path
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
out = Path("images")
|
||||
out.mkdir(exist_ok=True)
|
||||
|
||||
for page_index, page in enumerate(doc):
|
||||
for img_index, img in enumerate(page.get_images()):
|
||||
xref = img[0]
|
||||
pix = pymupdf.Pixmap(doc, xref)
|
||||
if pix.n > 4: # convert CMYK
|
||||
pix = pymupdf.Pixmap(pymupdf.csRGB, pix)
|
||||
pix.save(out / f"page{page_index}_img{img_index}.png")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Search for text across a document</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
needle = "confidential"
|
||||
|
||||
for page in doc:
|
||||
hits = page.search_for(needle)
|
||||
if hits:
|
||||
print(f"Page {page.number}: {len(hits)} occurrence(s)")
|
||||
for rect in hits:
|
||||
page.add_highlight_annot(rect)
|
||||
|
||||
doc.save("highlighted.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Split a PDF into individual pages</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for i, page in enumerate(doc):
|
||||
out = pymupdf.open()
|
||||
out.insert_pdf(doc, from_page=i, to_page=i)
|
||||
out.save(f"page_{i + 1}.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Insert a watermark on every page</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for page in doc:
|
||||
page.insert_text(
|
||||
point=pymupdf.Point(72, page.rect.height / 2),
|
||||
text="DRAFT",
|
||||
fontsize=72,
|
||||
color=(0.8, 0.8, 0.8),
|
||||
rotate=45,
|
||||
)
|
||||
|
||||
doc.save("watermarked.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Office Document Processing
|
||||
|
||||
PyMuPDF can be extended with PyMuPDF Pro. This adds a conversion layer that handles Microsoft and Korean Office formats natively — no Office installation, no COM interop, no LibreOffice subprocess.
|
||||
|
||||
Once unlocked, `pymupdf.open()` accepts Office files exactly like PDFs:
|
||||
|
||||
```python
|
||||
import pymupdf.pro
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
# Works identically regardless of format
|
||||
for fmt in ["contract.docx", "data.xlsx", "deck.pptx", "report.hwpx"]:
|
||||
doc = pymupdf.open(fmt)
|
||||
for page in doc:
|
||||
print(page.get_text())
|
||||
```
|
||||
|
||||
[Get a trial license key for PyMuPDF Pro](https://pymupdf.pro/try-pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=pymupdf_pro)
|
||||
|
||||
**What you can do with Office documents:**
|
||||
|
||||
- Extract text and images page-by-page
|
||||
- Convert to PDF with `doc.convert_to_pdf()`
|
||||
- Rasterise pages to PNG/JPEG for visual inspection
|
||||
- Feed directly into PyMuPDF4LLM for AI-ready output
|
||||
|
||||
|
||||
|
||||
### Restrictions Without a License Key
|
||||
|
||||
When `pymupdf.pro.unlock()` is called **without** a key, the following restrictions apply:
|
||||
|
||||
| Restriction | Detail |
|
||||
|---|---|
|
||||
| Page limit | Only the **first 3 pages** of any document are accessible |
|
||||
| Time limit | Evaluation period — functionality expires after a set duration |
|
||||
|
||||
All other Pro features work normally within these constraints, making it straightforward to prototype before purchasing a license.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### Can I use PyMuPDF, PyMuPDF4LLM and PyMuPDF Pro without sending data to the cloud?
|
||||
|
||||
Yes, absolutely — and this is one of PyMuPDF's most significant advantages.
|
||||
|
||||
PyMuPDF runs entirely locally. It is a native Python library built on top of the MuPDF C engine. When you call `pymupdf.open()`, `page.get_text()`, `page.find_tables()`, or any other method, everything executes in-process on your own machine. No data is transmitted anywhere.
|
||||
|
||||
|
||||
There are no telemetry calls, no licence validation callbacks, no cloud dependencies of any kind in the open-source AGPL build or the commercial build. Once the package is installed, it works fully air-gapped.
|
||||
|
||||
This makes PyMuPDF well-suited for:
|
||||
|
||||
- Regulated industries — healthcare (HIPAA), finance, legal, government, where documents cannot leave a controlled environment
|
||||
- On-premise deployments — servers with no outbound internet access
|
||||
- Air-gapped systems — classified or sensitive environments
|
||||
- Self-hosted RAG pipelines — processing confidential documents locally before feeding an on-premise LLM
|
||||
- Saving on token costs for document pre-processing before sending data to your LLM
|
||||
|
||||
The only thing you need an internet connection for is the initial `pip install`. After that, the package and all its capabilities are entirely self-contained.
|
||||
|
||||
|
||||
### Should I `import pymupdf` or `import fitz`?
|
||||
|
||||
Use `import pymupdf`. The `fitz` name is a legacy alias that still works as of v1.24.0+, but `import pymupdf` is the recommended and future-proof approach. The two are interchangeable in existing code:
|
||||
|
||||
```python
|
||||
import pymupdf # recommended
|
||||
# import fitz # legacy alias — still works but avoid for new code
|
||||
```
|
||||
|
||||
### Does PyMuPDF work with Korean, Japanese, or Chinese documents?
|
||||
|
||||
Yes — PyMuPDF has solid CJK support
|
||||
|
||||
### How do I extract Markdown from PDF for LLM?
|
||||
|
||||
Let PyMuPDF4LLM do everything (recommended for RAG).
|
||||
|
||||
PyMuPDF4LLM is a high-level wrapper that outputs standard text and table content together in an integrated Markdown-formatted string across all document pages PyMuPDF — tables are detected, converted to GitHub-compatible Markdown, and interleaved with surrounding text in the correct reading order. This is the best starting point for feeding an LLM or building a RAG pipeline.
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
|
||||
md = pymupdf4llm.to_markdown("report.pdf")
|
||||
print(md)
|
||||
# Tables appear as Markdown | col1 | col2 | ... inline with the text
|
||||
```
|
||||
|
||||
|
||||
### Text extraction returns garbled characters or empty output. Why?
|
||||
|
||||
This usually means the PDF uses custom font encodings without a proper character map (CMAP). The font's glyphs are present but cannot be mapped back to Unicode. In these cases:
|
||||
|
||||
- Use OCR as a fallback (`page.get_textpage_ocr()`)
|
||||
- Consider that scanned PDFs will always need OCR — text extraction on scans returns nothing
|
||||
|
||||
|
||||
|
||||
### How do I extract text from a specific area of a page?
|
||||
|
||||
Pass a `clip` rectangle to `get_text()`:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Define the area you want (x0, y0, x1, y1) in points
|
||||
clip = pymupdf.Rect(50, 100, 400, 300)
|
||||
text = page.get_text("text", clip=clip)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How do I search for text and find its location on the page?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Returns a list of Rect objects surrounding each match
|
||||
locations = page.search_for("invoice number")
|
||||
for rect in locations:
|
||||
print(rect) # e.g. Rect(72.0, 120.5, 210.0, 134.0)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### `get_images` shows no images but I can clearly see charts in the PDF. Why?
|
||||
|
||||
Charts and diagrams created by tools like matplotlib, Excel, or R are typically rendered as vector graphics (PDF drawing commands), not raster images. `get_images` only lists embedded raster image objects and will not detect vector graphics. To capture these, rasterise the entire page with `page.get_pixmap()`.
|
||||
|
||||
|
||||
|
||||
### How does OCR work in PyMuPDF? Does it require a separate Tesseract installation?
|
||||
|
||||
PyMuPDF uses MuPDF's built-in Tesseract-based OCR support, so there is no Python-level `pytesseract` dependency. However, PyMuPDF still needs access to the **Tesseract language data files** (`tessdata`), and automatic tessdata discovery may invoke the `tesseract` executable (for example, to list available languages) if you do not explicitly provide a tessdata path. In practice, the recommended setup is to either install Tesseract so discovery works automatically, or configure the tessdata location yourself via the `tessdata` parameter or the `TESSDATA_PREFIX` environment variable. Over 100 languages are supported.
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("scanned.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Get a text page using OCR
|
||||
tp = page.get_textpage_ocr(language="eng")
|
||||
text = page.get_text(textpage=tp)
|
||||
print(text)
|
||||
```
|
||||
|
||||
|
||||
### How do I run OCR on a standalone image file (not a PDF)?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
pix = pymupdf.Pixmap("image.png")
|
||||
if pix.alpha:
|
||||
pix = pymupdf.Pixmap(pix, 0) # remove alpha channel — required for OCR
|
||||
|
||||
# Wrap in a 1-page PDF and OCR it
|
||||
doc = pymupdf.open()
|
||||
page = doc.new_page(width=pix.width, height=pix.height)
|
||||
page.insert_image(page.rect, pixmap=pix)
|
||||
tp = page.get_textpage_ocr()
|
||||
text = page.get_text(textpage=tp)
|
||||
```
|
||||
|
||||
|
||||
### How do I highlight text in a PDF?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Use quads=True for accurate highlights on non-horizontal text
|
||||
quads = page.search_for("important term", quads=True)
|
||||
page.add_highlight_annot(quads)
|
||||
|
||||
doc.save("highlighted.pdf")
|
||||
```
|
||||
|
||||
PyMuPDF supports all standard PDF text markers: highlight, underline, strikeout, and squiggly.
|
||||
|
||||
|
||||
|
||||
### How do I permanently redact (remove) content from a PDF?
|
||||
|
||||
Redaction is a deliberate two-step process so you can review before committing:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Step 1: Mark the area(s) to redact
|
||||
rect = page.search_for("confidential")[0]
|
||||
page.add_redact_annot(rect, fill=(1, 1, 1)) # white fill
|
||||
|
||||
# Step 2: Apply — permanently removes the underlying content
|
||||
page.apply_redactions()
|
||||
|
||||
doc.save("redacted.pdf")
|
||||
```
|
||||
|
||||
After `apply_redactions()`, the original content is gone. It cannot be recovered from the saved file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### How do I read form field values from a PDF?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("form.pdf")
|
||||
page = doc[0]
|
||||
|
||||
for field in page.widgets():
|
||||
print(f"{field.field_name}: {field.field_value}")
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How do I fill in a PDF form programmatically?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("form.pdf")
|
||||
page = doc[0]
|
||||
|
||||
for field in page.widgets():
|
||||
if field.field_name == "First Name":
|
||||
field.field_value = "Ada"
|
||||
field.update()
|
||||
|
||||
doc.save("filled_form.pdf")
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Can I use multithreading with PyMuPDF?
|
||||
|
||||
No. PyMuPDF does not support multithreaded use, even with Python's newer free-threading mode. The underlying MuPDF library only provides partial thread safety, and a fully thread-safe PyMuPDF implementation would still impose a single-threaded overhead — negating the benefit.
|
||||
|
||||
**Use multiprocessing instead.** Each process opens the file independently and works on its own page range:
|
||||
|
||||
```python
|
||||
from multiprocessing import Pool
|
||||
import pymupdf
|
||||
|
||||
def process_pages(args):
|
||||
path, start, end = args
|
||||
doc = pymupdf.open(path) # each process opens its own handle
|
||||
results = []
|
||||
for i in range(start, end):
|
||||
results.append(doc[i].get_text())
|
||||
return results
|
||||
|
||||
with Pool(4) as pool:
|
||||
chunks = [("input.pdf", 0, 25), ("input.pdf", 25, 50), ...]
|
||||
all_results = pool.map(process_pages, chunks)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How can I speed up repeated text extraction on the same page?
|
||||
|
||||
Reuse a `TextPage` object. Creating a `TextPage` is the expensive part — once created, switching between extraction formats is cheap:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
page = doc[0]
|
||||
tp = page.get_textpage() # create once
|
||||
|
||||
text = page.get_text("text", textpage=tp)
|
||||
words = page.get_text("words", textpage=tp)
|
||||
data = page.get_text("dict", textpage=tp)
|
||||
```
|
||||
|
||||
This can reduce execution time by 50–95% for repeated extractions on the same page.
|
||||
|
||||
|
||||
|
||||
|
||||
### How do I read and write PDF metadata?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
|
||||
# Read
|
||||
print(doc.metadata)
|
||||
# {'title': '...', 'author': '...', 'subject': '...', 'keywords': '...', ...}
|
||||
|
||||
# Write
|
||||
doc.set_metadata({
|
||||
"title": "Annual Report 2025",
|
||||
"author": "Finance Team",
|
||||
"keywords": "annual, finance, 2025"
|
||||
})
|
||||
doc.save("output.pdf")
|
||||
```
|
||||
|
||||
|
||||
### How do I read or set the table of contents / bookmarks?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
|
||||
# Read — returns a list of [level, title, page_number] entries
|
||||
toc = doc.get_toc()
|
||||
for level, title, page in toc:
|
||||
print(" " * level, title, "→ page", page)
|
||||
|
||||
# Write
|
||||
new_toc = [
|
||||
[1, "Introduction", 1],
|
||||
[1, "Methods", 5],
|
||||
[2, "Data sources", 6],
|
||||
]
|
||||
doc.set_toc(new_toc)
|
||||
doc.save("output.pdf")
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
Full installation guide, API reference, cookbook, and tutorial at **[pymupdf.readthedocs.io](https://pymupdf.readthedocs.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=docs)**.
|
||||
|
||||
- [Installation guide](https://pymupdf.readthedocs.io/en/latest/installation.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=installation)
|
||||
- [API reference](https://pymupdf.readthedocs.io/en/latest/classes.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=classes)
|
||||
- [Cookbook](https://pymupdf.readthedocs.io/en/latest/the-basics.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=the_basics)
|
||||
- [Tutorial](https://pymupdf.readthedocs.io/en/latest/tutorial.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=tutorial)
|
||||
- [Changelog](https://pymupdf.readthedocs.io/en/latest/changes.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=changelog)
|
||||
- [PyMuPDF4LLM docs](https://docs.pdf4llm.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=docs)
|
||||
- [PyMuPDF Pro docs](https://pymupdf.readthedocs.io/en/latest/pymupdf-pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=pymupdf_pro)
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Related projects
|
||||
|
||||
| Project | Description |
|
||||
|---|---|
|
||||
| [PyMuPDF4LLM](https://github.com/pymupdf/pymupdf4llm) | LLM/RAG-optimised Markdown and JSON extraction |
|
||||
| [PyMuPDF Pro](https://pymupdf.io/pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=related_projects&utm_term=pymupdf_pro) | Adds Office and HWP document support |
|
||||
| [pymupdf-fonts](https://pypi.org/project/pymupdf-fonts/) | Extended font collection for PyMuPDF text output |
|
||||
|
||||
---
|
||||
|
||||
## Licensing
|
||||
|
||||
PyMuPDF and MuPDF are maintained by [Artifex Software, Inc.](https://artifex.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=website)
|
||||
|
||||
- **Open source** — [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.html). Free for open-source projects.
|
||||
- **Commercial** — separate commercial licences available from [Artifex](https://artifex.com/licensing?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=licensing) for proprietary applications.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. Please open an issue before submitting large pull requests.
|
||||
|
||||
- [Issue tracker](https://github.com/pymupdf/PyMuPDF/issues)
|
||||
- [Discord community](https://artifex.com/discord/artifex?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=discord)
|
||||
|
||||
## ⭐ Support this project
|
||||
|
||||
If you find this useful, please consider giving it a star — it helps others discover it!
|
||||
|
||||
[](https://github.com/pymupdf/PyMuPDF/)
|
||||
@@ -0,0 +1,779 @@
|
||||
<p align="center">
|
||||
<a href="https://pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=logo&utm_term=website">
|
||||
<img loading="lazy" alt="PyMuPDF" src="https://pymupdf.pro/images/py-mupdf-github-icon.png" width="96px" alt="PyMuPDF logo"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# PyMuPDF
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/11536" target="_blank"><img src="https://trendshift.io/api/badge/repositories/11536" alt="pymupdf%2FPyMuPDF | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
</p>
|
||||
|
||||
[](https://pymupdf.readthedocs.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=docs)
|
||||
[](https://pypi.org/project/PyMuPDF/)
|
||||
[](https://pypi.org/project/pymupdf/)
|
||||
[](https://github.com/pymupdf/PyMuPDF/blob/master/COPYING)
|
||||
[](https://pepy.tech/projects/pymupdf)
|
||||
[](https://github.com/pymupdf/PyMuPDF/stargazers)
|
||||
[](https://artifex.com/discord/artifex?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=discord)
|
||||
[](https://forum.mupdf.com/c/general/4?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=forum)
|
||||
[](https://x.com/pymupdf4llm)
|
||||
[](https://huggingface.co/artifex-software)
|
||||
[](https://demo.pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=badges&utm_term=demo)
|
||||
|
||||
**The PDF engine behind over 50 million monthly downloads, powering AI pipelines worldwide.**
|
||||
|
||||
**PyMuPDF is a high-performance Python library for data extraction, analysis, conversion, rendering and manipulation of PDF (and other) documents.** Built on top of MuPDF — a lightweight, fast C engine — PyMuPDF gives you precise, low-level control over documents alongside high-level convenience APIs. No mandatory external dependencies.
|
||||
|
||||
[](https://github.com/pymupdf/PyMuPDF/)
|
||||
|
||||
---
|
||||
|
||||
## Why PyMuPDF?
|
||||
|
||||
- **Fast** — powered by [MuPDF](https://mupdf.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=mupdf), a best-in-class C rendering engine
|
||||
- **Accurate** — pixel-perfect text extraction with font, color, and position metadata
|
||||
- **Versatile** — read, write, annotate, redact, merge, split, and convert documents
|
||||
- **LLM-ready** — native Markdown output via [PyMuPDF4LLM](https://pdf4llm.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=pymupdf4llm) for RAG and AI pipelines
|
||||
- **No mandatory dependencies** — `pip install pymupdf` and you're done
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install pymupdf
|
||||
```
|
||||
|
||||
Wheels are available for **Windows**, **macOS**, and **Linux** on Python 3.10–3.14. If no pre-built wheel exists for your platform, pip will compile from source (requires a C/C++ toolchain).
|
||||
|
||||
### Optional extras
|
||||
|
||||
| Package | Purpose |
|
||||
|---|---|
|
||||
| `pymupdf-fonts` | Extended font collection for text output |
|
||||
| `pymupdf4llm` | LLM/RAG-optimised Markdown and JSON extraction |
|
||||
| `pymupdfpro` | Adds Office document support |
|
||||
| `tesseract-ocr` | OCR for scanned pages and images (separate install) |
|
||||
|
||||
```bash
|
||||
# More fonts
|
||||
pip install pymupdf-fonts
|
||||
|
||||
# LLM-ready extraction
|
||||
pip install pymupdf4llm
|
||||
|
||||
# Office support
|
||||
pip install pymupdfpro
|
||||
|
||||
# OCR (Tesseract must be installed separately)
|
||||
# macOS
|
||||
brew install tesseract
|
||||
|
||||
# Ubuntu / Debian
|
||||
sudo apt install tesseract-ocr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Supported File Formats
|
||||
|
||||
### Input
|
||||
|
||||
| Category | Formats |
|
||||
|---|---|
|
||||
| PDF & derivatives | PDF, XPS, EPUB, CBZ, MOBI, FB2, SVG, TXT, MD |
|
||||
| Images | PNG, JPEG, BMP, TIFF, GIF, and more |
|
||||
| Microsoft Office *(Pro)* | DOC, DOCX, XLS, XLSX, PPT, PPTX |
|
||||
| Korean Office *(Pro)* | HWP, HWPX |
|
||||
|
||||
### Output
|
||||
|
||||
| Format | Notes |
|
||||
|---|---|
|
||||
| PDF | Full fidelity conversion from Office formats |
|
||||
| SVG | Vector page rendering |
|
||||
| Image (PNG, JPEG, …) | Page rasterisation at any DPI |
|
||||
| Markdown | Structure-aware, LLM-ready |
|
||||
| JSON | Bounding boxes, layout data, per-element detail |
|
||||
| Plain text | Fast, lightweight extraction |
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
### Extract text
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for page in doc:
|
||||
print(page.get_text())
|
||||
```
|
||||
|
||||
### Extract text with layout metadata
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
page = doc[0]
|
||||
|
||||
blocks = page.get_text("dict")["blocks"]
|
||||
for block in blocks:
|
||||
if block["type"] == 0: # text block
|
||||
for line in block["lines"]:
|
||||
for span in line["spans"]:
|
||||
print(f"{span['text']!r} font={span['font']} size={span['size']:.1f}")
|
||||
```
|
||||
|
||||
### Extract tables
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("spreadsheet.pdf")
|
||||
page = doc[0]
|
||||
|
||||
tables = page.find_tables()
|
||||
for table in tables:
|
||||
print(table.to_markdown())
|
||||
|
||||
# or get as Pandas DataFrame
|
||||
df = table.to_pandas()
|
||||
```
|
||||
|
||||
### Render a page to an image
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
page = doc[0]
|
||||
|
||||
pixmap = page.get_pixmap(dpi=150)
|
||||
pixmap.save("page_0.png")
|
||||
```
|
||||
|
||||
### OCR a scanned document
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("scanned.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Requires Tesseract installed and on PATH
|
||||
text = page.get_textpage_ocr(language="eng").extractText()
|
||||
print(text)
|
||||
```
|
||||
|
||||
### Convert Markdown to PDF
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
md_doc = pymupdf.open("example.md")
|
||||
md_doc.save("example.pdf")
|
||||
```
|
||||
|
||||
### Convert to Markdown for LLMs
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
|
||||
md = pymupdf4llm.to_markdown("report.pdf")
|
||||
# Pass directly to your LLM or vector store
|
||||
print(md)
|
||||
```
|
||||
|
||||
### Annotate and redact
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("contract.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Add a highlight annotation
|
||||
rect = pymupdf.Rect(72, 100, 400, 120)
|
||||
page.add_highlight_annot(rect)
|
||||
|
||||
# Add a redaction and apply it
|
||||
page.add_redact_annot(rect)
|
||||
page.apply_redactions()
|
||||
|
||||
doc.save("contract_redacted.pdf")
|
||||
```
|
||||
|
||||
### Merge PDFs
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
merger = pymupdf.open()
|
||||
for path in ["part1.pdf", "part2.pdf", "part3.pdf"]:
|
||||
merger.insert_pdf(pymupdf.open(path))
|
||||
|
||||
merger.save("merged.pdf")
|
||||
```
|
||||
|
||||
### Convert an Office document to PDF
|
||||
|
||||
```python
|
||||
import pymupdf.pro
|
||||
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
doc = pymupdf.open("presentation.pptx")
|
||||
pdf_bytes = doc.convert_to_pdf()
|
||||
|
||||
with open("output.pdf", "wb") as f:
|
||||
f.write(pdf_bytes)
|
||||
```
|
||||
|
||||
### Extract LLM-ready Markdown from a Word document
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
import pymupdf.pro
|
||||
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
md = pymupdf4llm.to_markdown("document.docx")
|
||||
print(md)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
### Core capabilities
|
||||
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| **Text extraction** | Plain text, rich dict (font, size, color, bbox), HTML, XML, raw blocks |
|
||||
| **Table detection** | `find_tables()` — locate, extract, and export tables as Markdown or structured data |
|
||||
| **Image extraction** | Extract embedded images and render any page to a high-resolution `Pixmap` |
|
||||
| **Rendering** | Render PDF pages to images or `Pixmap` data for use in UI or other workflows |
|
||||
| **OCR** | Tesseract integration — full-page or partial OCR, configurable language |
|
||||
| **Annotations** | Read and write highlights, underlines, squiggly lines, sticky notes, free text, ink, stamps |
|
||||
| **Redaction** | Add and permanently apply redaction annotations |
|
||||
| **Forms** | Read and fill PDF AcroForm fields |
|
||||
| **PDF creation** | Create PDFs directly with the API or quickly convert from Markdown files |
|
||||
| **PDF editing** | Insert, delete, and reorder pages; set metadata; merge and split documents |
|
||||
| **Drawing** | Draw lines, curves, rectangles, and circles; insert HTML boxes |
|
||||
| **Encryption** | Open password-protected PDFs; save with RC4 or AES encryption |
|
||||
| **Links** | Extract hyperlinks, internal cross-references, and URI targets |
|
||||
| **Bookmarks** | Read and write the outline / table of contents tree |
|
||||
| **Metadata** | Title, author, creation date, producer, subject, and custom entries |
|
||||
| **Color spaces** | RGB, CMYK, greyscale; color space conversion |
|
||||
|
||||
### LLM & AI output (via PyMuPDF4LLM)
|
||||
|
||||
| Output | API |
|
||||
|---|---|
|
||||
| Markdown | `pymupdf4llm.to_markdown(path)` |
|
||||
| JSON | `pymupdf4llm.to_json(path)` |
|
||||
| Plain text | `pymupdf4llm.to_text(path)` |
|
||||
|
||||
Supports multi-column layouts, natural reading order and page chunking.
|
||||
|
||||
|
||||
[](https://demo.pymupdf.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=demo)
|
||||
|
||||
---
|
||||
|
||||
## Supported Python versions
|
||||
|
||||
Python **3.10 – 3.14** (as of v1.27.x). Wheels ship for:
|
||||
|
||||
- `manylinux` x86\_64 and aarch64
|
||||
- `musllinux` x86\_64
|
||||
- macOS x86\_64 and arm64
|
||||
- Windows x86 and x86\_64
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
PyMuPDF is built on MuPDF — one of the fastest PDF rendering engines available. Typical benchmarks against pure-Python PDF libraries show **10–50× speed improvements** for text extraction and **100× or more** for page rendering, with a minimal memory footprint.
|
||||
|
||||
For AI workloads, PyMuPDF4LLM processes documents **without a GPU**, cutting infrastructure costs significantly compared to vision-based LLM approaches.
|
||||
|
||||
---
|
||||
|
||||
## Recipes
|
||||
|
||||
<details>
|
||||
<summary>Extract all images from a PDF</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
from pathlib import Path
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
out = Path("images")
|
||||
out.mkdir(exist_ok=True)
|
||||
|
||||
for page_index, page in enumerate(doc):
|
||||
for img_index, img in enumerate(page.get_images()):
|
||||
xref = img[0]
|
||||
pix = pymupdf.Pixmap(doc, xref)
|
||||
if pix.n > 4: # convert CMYK
|
||||
pix = pymupdf.Pixmap(pymupdf.csRGB, pix)
|
||||
pix.save(out / f"page{page_index}_img{img_index}.png")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Search for text across a document</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
needle = "confidential"
|
||||
|
||||
for page in doc:
|
||||
hits = page.search_for(needle)
|
||||
if hits:
|
||||
print(f"Page {page.number}: {len(hits)} occurrence(s)")
|
||||
for rect in hits:
|
||||
page.add_highlight_annot(rect)
|
||||
|
||||
doc.save("highlighted.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Split a PDF into individual pages</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for i, page in enumerate(doc):
|
||||
out = pymupdf.open()
|
||||
out.insert_pdf(doc, from_page=i, to_page=i)
|
||||
out.save(f"page_{i + 1}.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Insert a watermark on every page</summary>
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("document.pdf")
|
||||
for page in doc:
|
||||
page.insert_text(
|
||||
point=pymupdf.Point(72, page.rect.height / 2),
|
||||
text="DRAFT",
|
||||
fontsize=72,
|
||||
color=(0.8, 0.8, 0.8),
|
||||
rotate=45,
|
||||
)
|
||||
|
||||
doc.save("watermarked.pdf")
|
||||
```
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Office Document Processing
|
||||
|
||||
PyMuPDF can be extended with PyMuPDF Pro. This adds a conversion layer that handles Microsoft and Korean Office formats natively — no Office installation, no COM interop, no LibreOffice subprocess.
|
||||
|
||||
Once unlocked, `pymupdf.open()` accepts Office files exactly like PDFs:
|
||||
|
||||
```python
|
||||
import pymupdf.pro
|
||||
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
|
||||
|
||||
# Works identically regardless of format
|
||||
for fmt in ["contract.docx", "data.xlsx", "deck.pptx", "report.hwpx"]:
|
||||
doc = pymupdf.open(fmt)
|
||||
for page in doc:
|
||||
print(page.get_text())
|
||||
```
|
||||
|
||||
[Get a trial license key for PyMuPDF Pro](https://pymupdf.pro/try-pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=body&utm_term=pymupdf_pro)
|
||||
|
||||
**What you can do with Office documents:**
|
||||
|
||||
- Extract text and images page-by-page
|
||||
- Convert to PDF with `doc.convert_to_pdf()`
|
||||
- Rasterise pages to PNG/JPEG for visual inspection
|
||||
- Feed directly into PyMuPDF4LLM for AI-ready output
|
||||
|
||||
|
||||
|
||||
### Restrictions Without a License Key
|
||||
|
||||
When `pymupdf.pro.unlock()` is called **without** a key, the following restrictions apply:
|
||||
|
||||
| Restriction | Detail |
|
||||
|---|---|
|
||||
| Page limit | Only the **first 3 pages** of any document are accessible |
|
||||
| Time limit | Evaluation period — functionality expires after a set duration |
|
||||
|
||||
All other Pro features work normally within these constraints, making it straightforward to prototype before purchasing a license.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### Can I use PyMuPDF, PyMuPDF4LLM and PyMuPDF Pro without sending data to the cloud?
|
||||
|
||||
Yes, absolutely — and this is one of PyMuPDF's most significant advantages.
|
||||
|
||||
PyMuPDF runs entirely locally. It is a native Python library built on top of the MuPDF C engine. When you call `pymupdf.open()`, `page.get_text()`, `page.find_tables()`, or any other method, everything executes in-process on your own machine. No data is transmitted anywhere.
|
||||
|
||||
|
||||
There are no telemetry calls, no licence validation callbacks, no cloud dependencies of any kind in the open-source AGPL build or the commercial build. Once the package is installed, it works fully air-gapped.
|
||||
|
||||
This makes PyMuPDF well-suited for:
|
||||
|
||||
- Regulated industries — healthcare (HIPAA), finance, legal, government, where documents cannot leave a controlled environment
|
||||
- On-premise deployments — servers with no outbound internet access
|
||||
- Air-gapped systems — classified or sensitive environments
|
||||
- Self-hosted RAG pipelines — processing confidential documents locally before feeding an on-premise LLM
|
||||
- Saving on token costs for document pre-processing before sending data to your LLM
|
||||
|
||||
The only thing you need an internet connection for is the initial `pip install`. After that, the package and all its capabilities are entirely self-contained.
|
||||
|
||||
|
||||
### Should I `import pymupdf` or `import fitz`?
|
||||
|
||||
Use `import pymupdf`. The `fitz` name is a legacy alias that still works as of v1.24.0+, but `import pymupdf` is the recommended and future-proof approach. The two are interchangeable in existing code:
|
||||
|
||||
```python
|
||||
import pymupdf # recommended
|
||||
# import fitz # legacy alias — still works but avoid for new code
|
||||
```
|
||||
|
||||
### Does PyMuPDF work with Korean, Japanese, or Chinese documents?
|
||||
|
||||
Yes — PyMuPDF has solid CJK support
|
||||
|
||||
### How do I extract Markdown from PDF for LLM?
|
||||
|
||||
Let PyMuPDF4LLM do everything (recommended for RAG).
|
||||
|
||||
PyMuPDF4LLM is a high-level wrapper that outputs standard text and table content together in an integrated Markdown-formatted string across all document pages PyMuPDF — tables are detected, converted to GitHub-compatible Markdown, and interleaved with surrounding text in the correct reading order. This is the best starting point for feeding an LLM or building a RAG pipeline.
|
||||
|
||||
```python
|
||||
import pymupdf4llm
|
||||
|
||||
md = pymupdf4llm.to_markdown("report.pdf")
|
||||
print(md)
|
||||
# Tables appear as Markdown | col1 | col2 | ... inline with the text
|
||||
```
|
||||
|
||||
|
||||
### Text extraction returns garbled characters or empty output. Why?
|
||||
|
||||
This usually means the PDF uses custom font encodings without a proper character map (CMAP). The font's glyphs are present but cannot be mapped back to Unicode. In these cases:
|
||||
|
||||
- Use OCR as a fallback (`page.get_textpage_ocr()`)
|
||||
- Consider that scanned PDFs will always need OCR — text extraction on scans returns nothing
|
||||
|
||||
|
||||
|
||||
### How do I extract text from a specific area of a page?
|
||||
|
||||
Pass a `clip` rectangle to `get_text()`:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Define the area you want (x0, y0, x1, y1) in points
|
||||
clip = pymupdf.Rect(50, 100, 400, 300)
|
||||
text = page.get_text("text", clip=clip)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How do I search for text and find its location on the page?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Returns a list of Rect objects surrounding each match
|
||||
locations = page.search_for("invoice number")
|
||||
for rect in locations:
|
||||
print(rect) # e.g. Rect(72.0, 120.5, 210.0, 134.0)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### `get_images` shows no images but I can clearly see charts in the PDF. Why?
|
||||
|
||||
Charts and diagrams created by tools like matplotlib, Excel, or R are typically rendered as vector graphics (PDF drawing commands), not raster images. `get_images` only lists embedded raster image objects and will not detect vector graphics. To capture these, rasterise the entire page with `page.get_pixmap()`.
|
||||
|
||||
|
||||
|
||||
### How does OCR work in PyMuPDF? Does it require a separate Tesseract installation?
|
||||
|
||||
PyMuPDF uses MuPDF's built-in Tesseract-based OCR support, so there is no Python-level `pytesseract` dependency. However, PyMuPDF still needs access to the **Tesseract language data files** (`tessdata`), and automatic tessdata discovery may invoke the `tesseract` executable (for example, to list available languages) if you do not explicitly provide a tessdata path. In practice, the recommended setup is to either install Tesseract so discovery works automatically, or configure the tessdata location yourself via the `tessdata` parameter or the `TESSDATA_PREFIX` environment variable. Over 100 languages are supported.
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("scanned.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Get a text page using OCR
|
||||
tp = page.get_textpage_ocr(language="eng")
|
||||
text = page.get_text(textpage=tp)
|
||||
print(text)
|
||||
```
|
||||
|
||||
|
||||
### How do I run OCR on a standalone image file (not a PDF)?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
pix = pymupdf.Pixmap("image.png")
|
||||
if pix.alpha:
|
||||
pix = pymupdf.Pixmap(pix, 0) # remove alpha channel — required for OCR
|
||||
|
||||
# Wrap in a 1-page PDF and OCR it
|
||||
doc = pymupdf.open()
|
||||
page = doc.new_page(width=pix.width, height=pix.height)
|
||||
page.insert_image(page.rect, pixmap=pix)
|
||||
tp = page.get_textpage_ocr()
|
||||
text = page.get_text(textpage=tp)
|
||||
```
|
||||
|
||||
|
||||
### How do I highlight text in a PDF?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Use quads=True for accurate highlights on non-horizontal text
|
||||
quads = page.search_for("important term", quads=True)
|
||||
page.add_highlight_annot(quads)
|
||||
|
||||
doc.save("highlighted.pdf")
|
||||
```
|
||||
|
||||
PyMuPDF supports all standard PDF text markers: highlight, underline, strikeout, and squiggly.
|
||||
|
||||
|
||||
|
||||
### How do I permanently redact (remove) content from a PDF?
|
||||
|
||||
Redaction is a deliberate two-step process so you can review before committing:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
page = doc[0]
|
||||
|
||||
# Step 1: Mark the area(s) to redact
|
||||
rect = page.search_for("confidential")[0]
|
||||
page.add_redact_annot(rect, fill=(1, 1, 1)) # white fill
|
||||
|
||||
# Step 2: Apply — permanently removes the underlying content
|
||||
page.apply_redactions()
|
||||
|
||||
doc.save("redacted.pdf")
|
||||
```
|
||||
|
||||
After `apply_redactions()`, the original content is gone. It cannot be recovered from the saved file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### How do I read form field values from a PDF?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("form.pdf")
|
||||
page = doc[0]
|
||||
|
||||
for field in page.widgets():
|
||||
print(f"{field.field_name}: {field.field_value}")
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How do I fill in a PDF form programmatically?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("form.pdf")
|
||||
page = doc[0]
|
||||
|
||||
for field in page.widgets():
|
||||
if field.field_name == "First Name":
|
||||
field.field_value = "Ada"
|
||||
field.update()
|
||||
|
||||
doc.save("filled_form.pdf")
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Can I use multithreading with PyMuPDF?
|
||||
|
||||
No. PyMuPDF does not support multithreaded use, even with Python's newer free-threading mode. The underlying MuPDF library only provides partial thread safety, and a fully thread-safe PyMuPDF implementation would still impose a single-threaded overhead — negating the benefit.
|
||||
|
||||
**Use multiprocessing instead.** Each process opens the file independently and works on its own page range:
|
||||
|
||||
```python
|
||||
from multiprocessing import Pool
|
||||
import pymupdf
|
||||
|
||||
def process_pages(args):
|
||||
path, start, end = args
|
||||
doc = pymupdf.open(path) # each process opens its own handle
|
||||
results = []
|
||||
for i in range(start, end):
|
||||
results.append(doc[i].get_text())
|
||||
return results
|
||||
|
||||
with Pool(4) as pool:
|
||||
chunks = [("input.pdf", 0, 25), ("input.pdf", 25, 50), ...]
|
||||
all_results = pool.map(process_pages, chunks)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### How can I speed up repeated text extraction on the same page?
|
||||
|
||||
Reuse a `TextPage` object. Creating a `TextPage` is the expensive part — once created, switching between extraction formats is cheap:
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
page = doc[0]
|
||||
tp = page.get_textpage() # create once
|
||||
|
||||
text = page.get_text("text", textpage=tp)
|
||||
words = page.get_text("words", textpage=tp)
|
||||
data = page.get_text("dict", textpage=tp)
|
||||
```
|
||||
|
||||
This can reduce execution time by 50–95% for repeated extractions on the same page.
|
||||
|
||||
|
||||
|
||||
|
||||
### How do I read and write PDF metadata?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
|
||||
# Read
|
||||
print(doc.metadata)
|
||||
# {'title': '...', 'author': '...', 'subject': '...', 'keywords': '...', ...}
|
||||
|
||||
# Write
|
||||
doc.set_metadata({
|
||||
"title": "Annual Report 2025",
|
||||
"author": "Finance Team",
|
||||
"keywords": "annual, finance, 2025"
|
||||
})
|
||||
doc.save("output.pdf")
|
||||
```
|
||||
|
||||
|
||||
### How do I read or set the table of contents / bookmarks?
|
||||
|
||||
```python
|
||||
import pymupdf
|
||||
|
||||
doc = pymupdf.open("input.pdf")
|
||||
|
||||
# Read — returns a list of [level, title, page_number] entries
|
||||
toc = doc.get_toc()
|
||||
for level, title, page in toc:
|
||||
print(" " * level, title, "→ page", page)
|
||||
|
||||
# Write
|
||||
new_toc = [
|
||||
[1, "Introduction", 1],
|
||||
[1, "Methods", 5],
|
||||
[2, "Data sources", 6],
|
||||
]
|
||||
doc.set_toc(new_toc)
|
||||
doc.save("output.pdf")
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
Full installation guide, API reference, cookbook, and tutorial at **[pymupdf.readthedocs.io](https://pymupdf.readthedocs.io?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=docs)**.
|
||||
|
||||
- [Installation guide](https://pymupdf.readthedocs.io/en/latest/installation.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=installation)
|
||||
- [API reference](https://pymupdf.readthedocs.io/en/latest/classes.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=classes)
|
||||
- [Cookbook](https://pymupdf.readthedocs.io/en/latest/the-basics.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=the_basics)
|
||||
- [Tutorial](https://pymupdf.readthedocs.io/en/latest/tutorial.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=tutorial)
|
||||
- [Changelog](https://pymupdf.readthedocs.io/en/latest/changes.html?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=changelog)
|
||||
- [PyMuPDF4LLM docs](https://docs.pdf4llm.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=docs)
|
||||
- [PyMuPDF Pro docs](https://pymupdf.readthedocs.io/en/latest/pymupdf-pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=documentation_community&utm_term=pymupdf_pro)
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Related projects
|
||||
|
||||
| Project | Description |
|
||||
|---|---|
|
||||
| [PyMuPDF4LLM](https://github.com/pymupdf/pymupdf4llm) | LLM/RAG-optimised Markdown and JSON extraction |
|
||||
| [PyMuPDF Pro](https://pymupdf.io/pro?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=related_projects&utm_term=pymupdf_pro) | Adds Office and HWP document support |
|
||||
| [pymupdf-fonts](https://pypi.org/project/pymupdf-fonts/) | Extended font collection for PyMuPDF text output |
|
||||
|
||||
---
|
||||
|
||||
## Licensing
|
||||
|
||||
PyMuPDF and MuPDF are maintained by [Artifex Software, Inc.](https://artifex.com?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=website)
|
||||
|
||||
- **Open source** — [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.html). Free for open-source projects.
|
||||
- **Commercial** — separate commercial licences available from [Artifex](https://artifex.com/licensing?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=licensing) for proprietary applications.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. Please open an issue before submitting large pull requests.
|
||||
|
||||
- [Issue tracker](https://github.com/pymupdf/PyMuPDF/issues)
|
||||
- [Discord community](https://artifex.com/discord/artifex?utm_source=github&utm_medium=referral&utm_campaign=pymupdf_github&utm_content=footer&utm_term=discord)
|
||||
|
||||
## ⭐ Support this project
|
||||
|
||||
If you find this useful, please consider giving it a star — it helps others discover it!
|
||||
|
||||
[](https://github.com/pymupdf/PyMuPDF/)
|
||||
@@ -0,0 +1,131 @@
|
||||
../../../bin/pymupdf,sha256=Xm4VRrjt7zpBLI24XTk3ccz7medPFsZxzTkSltKGXhY,204
|
||||
fitz/__init__.py,sha256=I9rn6si73K5_wXXef6FouEnCW2_sGnGWp6np9hQaNy8,479
|
||||
fitz/__pycache__/__init__.cpython-311.pyc,,
|
||||
fitz/__pycache__/table.cpython-311.pyc,,
|
||||
fitz/__pycache__/utils.cpython-311.pyc,,
|
||||
fitz/table.py,sha256=irhKvEpZ_4PN--TJXM2vbrSsQ4QVve43R9Cy2KZeJxM,85
|
||||
fitz/utils.py,sha256=TnLKI9a60-JjET9Kj9p7Gl4MoAvpaEcDG9ZP7ywvoTA,85
|
||||
pymupdf-1.28.0.dist-info/COPYING,sha256=QOYGl2AFNeq_ta4F9ygp2Iz-jQLdR5L1p1T29R2r5Vs,64
|
||||
pymupdf-1.28.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
pymupdf-1.28.0.dist-info/METADATA,sha256=8OIDPTwe-41YxPRlARAxmmOqNtAHCpoiS5VuA2QNXQU,26482
|
||||
pymupdf-1.28.0.dist-info/README.md,sha256=0NF77YURM0MHRIZpQaFwdULRrrByu6toHe7B5JSYZjw,25223
|
||||
pymupdf-1.28.0.dist-info/RECORD,,
|
||||
pymupdf-1.28.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pymupdf-1.28.0.dist-info/WHEEL,sha256=iLe16dGmlGUohyBfqUyEIEl7DF5umjdZ4suqY8Fmd5w,97
|
||||
pymupdf-1.28.0.dist-info/entry_points.txt,sha256=9NcH_CVkHVuLNxE1TYbfwXwClVkMcM890TMTJ3C5fDA,51
|
||||
pymupdf/__init__.py,sha256=FpKdq4e05VwrLLGp6zq5R8YzXCA-3DFyOvSAz6IpA7U,919377
|
||||
pymupdf/__main__.py,sha256=djqXMFk30GZaQ9S2kgkk77Fdj4d5XsKSbAn52mm_0ss,41358
|
||||
pymupdf/__pycache__/__init__.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/__main__.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/_apply_pages.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/_build.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/_wxcolors.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/extra.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/mupdf.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/pymupdf.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/table.cpython-311.pyc,,
|
||||
pymupdf/__pycache__/utils.cpython-311.pyc,,
|
||||
pymupdf/_apply_pages.py,sha256=cgtSAV1wMguzYDwackwHQcm1PoeplD7JapEe84tb1Fc,7716
|
||||
pymupdf/_build.py,sha256=Ph9aSK3YPiA9kciFMAaGleXJD1J28kATsk7TEZI9Hvw,406
|
||||
pymupdf/_extra.so,sha256=IAlkcOKQPB7RmetfwJfNy6wZxd2X5ELXiPjtvsIn1MA,249408
|
||||
pymupdf/_mupdf.so,sha256=7zKl_aV-DJMNSnIeQFhxzbecqS-rF9KO9Z2K317qm1I,15489448
|
||||
pymupdf/_wxcolors.py,sha256=AjY_qridRoV-JefKiHB8opddNnVKT6n9HRUIH8UjrB0,20533
|
||||
pymupdf/extra.py,sha256=GT1lRpD4cBpYxexdbLantdbFnJtSnLTrPzKsTwlY5bI,6662
|
||||
pymupdf/libmupdf.so.29.0,sha256=OIfMB9wEOHg2JVEzkp34-VkuxIpBwusOORLLwDt4vUg,36168568
|
||||
pymupdf/libmupdfcpp.so.29.0,sha256=Ksvn-NPqtopzN1gZn5fZIvxSuhXg0SXJxwJJpUMaqFg,3070544
|
||||
pymupdf/mupdf-devel/include/mupdf/classes.h,sha256=RedWzFpxHZWLA6ScCB1GqPZCVqRXiJEniVFT4VetmQ4,745548
|
||||
pymupdf/mupdf-devel/include/mupdf/classes2.h,sha256=gD4cer5wC9D3l_J22h4gLxDtdLukCw8vK-j0rsDE6fQ,511827
|
||||
pymupdf/mupdf-devel/include/mupdf/exceptions.h,sha256=lZK8a8bVdJYtMSXuP7lFeewpQpG97eUpFdhv1QypiAw,2079
|
||||
pymupdf/mupdf-devel/include/mupdf/extra.h,sha256=zmdHVZuWMxtCrm7vQRwmvLWAl0yIrWJRfj39g-IVCpQ,8241
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz.h,sha256=PIUeNydxe9ZREoNx2o5eQnYzQVnPpZqk96YzRnvt63s,2877
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/archive.h,sha256=LrqCwgFVNfQd6Q6UrXOJ6LJS8m5zZOfhkLaxgic5UGE,12458
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/band-writer.h,sha256=RL5OypSBjWJHcr7C7qPZkSc0psYxofDs4K83mz1E36k,3759
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/barcode.h,sha256=dfDkzlQPVx2y9cni7ol_jXOkAC9Cpm99jDmXjW4fLME,4245
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/bidi.h,sha256=YnFGsH-vUDyUNM3Govo--nWgNvL7ltbSxOb9R6-hmzc,2530
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/bitmap.h,sha256=Go-tezmbgmMLg6RJUcUIAvVYHGm6DGKvYf3aOFf7pc0,5350
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/buffer.h,sha256=3RTBX4NoMf6DFOkI1Am_9s9lBq7PKCrSU1qSFwcHDVY,8089
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/color.h,sha256=lAgg0cZMLd1jdmsYj5uXmKeGXgv5UeE8Rjlr-if9aYg,13251
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/compress.h,sha256=qzNqNdrVxW4c-LYqcHJwhggc4R4AgsDCB9xSuAoqx_c,5188
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/compressed-buffer.h,sha256=TOxjRBCJ6siep3GXuCB3aCp0BiV4KlVfSJgMZT7z8ks,4643
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/config.h,sha256=E0GVpt7BOqjiF4gs14s2EMiWb0ZdOTvkvZo3PfrUKbQ,8245
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/context.h,sha256=1_vm2hT_arzwCtVvhiZkLOcIFm5kVAdPMJeGwP0CwF0,31974
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/crypt.h,sha256=tFDydnNpMamFlcILo5fwWnQiN1Y-aloUETpgudyqpUY,6750
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/deskew.h,sha256=U3NC83n3rJMN_JOhIf6fOYNHj4l0ianenreMlWJXWfU,1442
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/device.h,sha256=axL0iMm2nu4HLWSu2cX7lW_znlkkEXwHekI62k0_e64,25696
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/display-list.h,sha256=yYtX3oRHV8DFCjjBayEDV-cLmdtRFW2SGJH_-jxvLpo,4954
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/document.h,sha256=9Rq7HoAtsQvhe0ZAJzLw_7UK3uLyuAmUc5k4QmDqLQo,35716
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/export.h,sha256=-TWHp7YI7rg5bYOgYMNyGxOVGULJ3SRlxtRzFLARPSw,1689
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/filter.h,sha256=Fzsyt12sQcZmF4Lh_Cg-VWIdnmB1ce8rtxvYMLUpcx8,8104
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/font.h,sha256=1YGEnSpR3SGxKLLt837JaBitvmjcJfsUAGUeJ4x6YHs,25042
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/geometry.h,sha256=zvyHUieD3i3GW6DA5QxHGFF_R3wYFurYGNAdetNoDHU,24294
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/getopt.h,sha256=J-qJ3hHVvmR9n1mUv7xoutUHUvbGu85_NMLvE1hR4mE,4934
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/glyph-cache.h,sha256=5F7rSjej9vw-NBDLmSd0zdwpsU6okjuFDxHB2tp0xMM,3417
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/glyph.h,sha256=jSj-jspSOQNR0c_Vi9qtmHWNqkg6GxSJC_Fs4aE47LQ,2397
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/hash.h,sha256=2r0RT5R2tUp1xDaGJP2jZ-1SuL71EBQN7lXPHKdO9yw,4107
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/heap-imp.h,sha256=Kf0Xb6idULEXsrVvzVPTziBRT-s-wYX-aRbg5dYKNSM,4514
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/heap.h,sha256=NjkuUjuLUdYlnAAdyuen4ME0r0srX65FQRqQSuB8VJ8,5171
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/hyphen.h,sha256=jP37_J-hxAy_EPrti1I5lA0Bdwg0MaGo5YZ5PzcXhI8,2018
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/image.h,sha256=7E_H-5Tj7L1SNU_U46VYIZTNnbAHj7zEZxP4kcjEV04,15513
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/json.h,sha256=05m-JZ5cWJyL7sO5tBA4JR9IN8Kt0nhU_muoI4XfMiM,3263
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/link.h,sha256=zMEUOHWSRzk9nd2vkCaSDkANJONGzYkVzDWUam92bDU,4129
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/log.h,sha256=4xmhWdgwuBtFqbf12OUhfKgBT4HLEEOdWeZqHjI-CRc,1961
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/options.h,sha256=p8nqjDArVl5w4pYjCEpNgTlfNwaUoOGD0nQfFg5hYwc,6705
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/outline.h,sha256=6Fkz-Dyk0akWVxaQGRYBZdValB9NG0iWHOdORCvPrTQ,8148
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/output-svg.h,sha256=72BpfnSOPh_GzndQmfFaht42lGxWM1z1iy8HK771iRk,2947
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/output.h,sha256=JOe5oN1MvJkmTPGfOZ9tf28eig_YOkmRg5CsGm5BUyU,13780
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/path.h,sha256=FkS_p981Sc-AKLPrp_k9NHPxj6MRa9gZCFXFbGSmG8U,14146
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/pixmap.h,sha256=ps16r72LG_rgkeCAo7GEoWHq5EkoNUB1DBU3AyGUd8o,16252
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/pool.h,sha256=5pARCi3_A5N1H0ys2zq6yqJRJO232yycyLW6wZ_9PUc,3302
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/separation.h,sha256=2N9MuYDIa6jD5n4RpOjPqWJkn05vKklqGDm1ESQcq90,4603
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/shade.h,sha256=dPHkCrXxD6ra7A2SRBqxDS4aoJv09D6Q2dNVerPH-cs,6211
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/store.h,sha256=vzopA5kIdFExcUqE-GAvr48rdy3iO3UyxcxilrFUVYg,14139
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/story-writer.h,sha256=G3-ed4Znt8fjkPPhQvnM63iNEDhhOAV0qp6xX6xTDT4,6916
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/story.h,sha256=d00V0j3R77QoqKXmovFB1YTiTGtqPszRJWrEnhEA_b4,7681
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/stream.h,sha256=wcYOxFapZ0apWpZjJOdMu2dGuFo76A4iF-pXlCqPaN8,16683
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/string-util.h,sha256=YvX1Ld1iQvDze_MDwgiFq7-tss97GXxjoqy8CUK02OY,12673
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/structured-text.h,sha256=zhhPz08QwLXs_rZOwwix55f36JMGGJJY3jgYwTY6NQE,43372
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/system.h,sha256=Bz5GlUK6OoSz-tk71fqxRku3kqqC3qa5FVjl41VjC-U,15316
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/text.h,sha256=F0tWsh0T_hgkZCfdaNcSsKgcJU-8F81IFU0COkwRlck,6456
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/track-usage.h,sha256=oleSq1ZwWWqMsAykvFKqxcTGBHDQpWjmQ4RRFLsdByo,1707
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/transition.h,sha256=B5Ubf9bj_WWoqa05InIdk978-VRg6rR07Puxatfu56w,2188
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/tree.h,sha256=425CcmbbB0j9PFtq4S4TwLlEWvLTEMJ92mheXoEWWF8,1983
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/types.h,sha256=P0WLCXlGYNyVSrdvjlRgdLUoZHptE_WCk35YksWe2f0,1470
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/util.h,sha256=YCOiFIEK2F0lTkE2JQa1wPFOoe9vJIpQO_ASuLlcEEE,12276
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/version.h,sha256=sdT_thTsijUbMJoyOt8ULMZX7qHuUBDwozzE18mfmrU,1200
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/write-pixmap.h,sha256=giGP9tYZ-p0XRq76lS5mhFry2f3cmIyxTJiLkgUaqxw,16876
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/writer.h,sha256=2rlXcsbR470qSHtn-sNvFKWAvvdLcphkIj133nu32VM,10455
|
||||
pymupdf/mupdf-devel/include/mupdf/fitz/xml.h,sha256=2AxngUvxrf1PUsZYW_ah_28RElZNwOF3rfLdAWdXhDY,12937
|
||||
pymupdf/mupdf-devel/include/mupdf/functions.h,sha256=N8WRFu2bwuayaDQtc-hC2yM7mL2YsIQDMUh0AuD3QiY,562679
|
||||
pymupdf/mupdf-devel/include/mupdf/helpers/mu-office-lib.h,sha256=yxvJ5B90c1Tu5sqq8d6O4dIZJO48ZBvXWlu5E6bVSBE,22192
|
||||
pymupdf/mupdf-devel/include/mupdf/helpers/mu-threads.h,sha256=9ZRYn-Rg_02WjHTtpgL6A9gGuU8SIWm-GM1JQX4J8hA,5774
|
||||
pymupdf/mupdf-devel/include/mupdf/helpers/pkcs7-openssl.h,sha256=jQb1aMNEcgC8EaKhfX4mIzE7KcvAENlK_-jMiTpelh4,2427
|
||||
pymupdf/mupdf-devel/include/mupdf/html.h,sha256=RJcuoBaunOZcvuqMZHMGvCepY4rc_Lbenj_jOZf6UDs,2074
|
||||
pymupdf/mupdf-devel/include/mupdf/internal.h,sha256=zV-K1o3Cg0wrPlEbcaKMH4ZD9sU32H1fq5DRBBw_ObY,1344
|
||||
pymupdf/mupdf-devel/include/mupdf/memento.h,sha256=MSoxjQJw-2p9xPkvuPn5VgaYPC5kjbBzBinvStZOcXk,17041
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf.h,sha256=GzHpp-9SgHqM42HlKneOM2FkS2FuDrOe5E-fPBDmRsg,1692
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/annot.h,sha256=DAw9miLS02HywIEvNcp6y__9kjmk3GM27MO9n5qwu-0,35759
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/clean.h,sha256=yYlkLxNQkO5j_Ojo2wkVLn-i1vqlDHL6c-XQAy7ruhY,2872
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/cmap.h,sha256=uiW7WPOcI1tnElBTxAItOInNHIcn5t6Jo-bCiJIKt_4,3954
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/crypt.h,sha256=5UaYdwjoDg9lFj1Lp3PsM2j206hWak3Djxku5f6svqY,4548
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/document.h,sha256=Wkcb0sVA8zPhVfCNtrV-D5VqKbCnFleX-tAS_u23nqM,32885
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/event.h,sha256=J_wWweEHcvVTBzuxA7c_jOv1pf2cCElKwCskO691DqY,4777
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/font.h,sha256=rv_4Y01eA1qzvw8Uo6mJLDz3LS7tnch4d59rbQNi19c,5391
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/form.h,sha256=kZaWRqLZzq1T-b4dPozYEJAjcJVy6e9VVqosrFpXzbI,15059
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/image-rewriter.h,sha256=15mbZX9D7cum5LilJ_yTATCKbxW5UTuw8PNZCxJnNh4,3565
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/interpret.h,sha256=KvXrauVksJ-_TKgrr3r9vnDHhTi-XGlfJYdOqOTJLg0,20664
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/javascript.h,sha256=NCrd8NG_qiNJiicEVu8oT1IYnpvXJlcNjlJbOoQNwuA,1823
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/name-table.h,sha256=OiMgf7TLcjwR2cMk84jMW8bfTMDf9DVAIrcuNqmNf08,20990
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/object.h,sha256=zryPgdBzgKd2wGb6kdznYlLbur25En2FSN1zBSRj68g,20933
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/page.h,sha256=ff99EomX4nimFltvFm4Mt3XOwYe4Jf_bvkWbQpatGgw,12357
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/parse.h,sha256=nX2CoEpO7I7pi5x99cMLHhygLTZJSuaX4P4F930KZ1M,2596
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/recolor.h,sha256=KEr9F2SnW-S3p92unTKRtlJthKI3XlkY9xaOAUuHGTA,1563
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/resource.h,sha256=QnsilywDmNXQtteTU1EXnoBFBPCyHtXB9OavuZhe9F0,6902
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/xref.h,sha256=TVTtPwHKmJQmuyALeNTKjLVK6TDUxrhwq8AIcdjvBYU,12131
|
||||
pymupdf/mupdf-devel/include/mupdf/pdf/zugferd.h,sha256=ma314FDM37JFdtqyRYMLgBG8FxwzkIeRE0TpbNXUT88,1616
|
||||
pymupdf/mupdf-devel/include/mupdf/ucdn.h,sha256=hyRG_xZmQFBZS8HmwrSpWjX1wcmmVWVDDvqMKGI1ynU,14378
|
||||
pymupdf/mupdf-devel/lib/libmupdf-threads.a,sha256=RhDZzC_2dr2OWxZKTXrYYAXB8vvKdGrKs1pc83utV6g,7190
|
||||
pymupdf/mupdf.py,sha256=e-gyu5eVvvQoE0POjdnBG9VNG4nuR9UpGBBAl7WStbQ,2671193
|
||||
pymupdf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pymupdf/pymupdf.py,sha256=TmBAFot49935b2zksN21nmcCqXm1VwTmLDi5tDBZY1I,64
|
||||
pymupdf/table.py,sha256=_eJg18iF6uOcZXZhB8gAFpVsSpGpzRnrgrZKck2vkLY,95317
|
||||
pymupdf/utils.py,sha256=zBcgZ_4ncGijq9uciIbvv6yqvJsmH4Lstobs2F-3Yi0,39718
|
||||
@@ -0,0 +1,4 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: pipcl
|
||||
Root-Is-Purelib: false
|
||||
Tag: cp310-abi3-manylinux_2_28_x86_64
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
[console_scripts]
|
||||
pymupdf = pymupdf.__main__:main
|
||||
Reference in New Issue
Block a user