pylopdf
Japanese README / Documentation: https://yhay81.github.io/pylopdf/ (with a pymupdf migration guide and API stability policy)
PDF editing, rendering, extraction, and generation for Python, powered by Rust — lopdf for editing, hayro (the pure-Rust PDF renderer adopted by Typst) for rendering and extraction, and krilla with HarfRust for generated text and form appearances.
MIT licensed, no mandatory Python dependencies, lightweight wheels. Covers the common pymupdf use cases without the AGPL.
Why pylopdf?
| pylopdf | pymupdf | pypdf | pypdfium2 | pdf_oxide | pikepdf | |
|---|---|---|---|---|---|---|
| License | MIT | AGPL / commercial | BSD | Apache/BSD | MIT/Apache-2.0 | MPL-2.0 |
| Wheel size (MiB) | ~5.0–5.8 | ~17.5–24.7 | small (pure Python) | ~2.7–5.0 | ~9.7–10.9 | ~1.9–4.6 |
| Editing (merge / split / rotate / outlines) | ✅ | ✅ | ✅ | limited | ✅ | ✅ (structure-focused) |
| Rendering (PNG / SVG) | ✅ | ✅ | ❌ | ✅ (PNG) | ❌ | ❌ (docs point to other tools) |
| Text extraction | ✅ (positioned text, tables, Markdown) | ✅ (advanced) | ✅ | ✅ | ✅ (advanced, table detection / Markdown) | ❌ (docs point to other tools) |
| Encryption (AES-256) | ✅ read & write | ✅ | ✅ | read only | undocumented | ✅ (via qpdf) |
| Japanese font fallback / generation | ✅ ([cjk] extra) | ✅ | — | manual | — | — |
| Implementation | pure Rust | C/C++ | Python | C++ (PDFium) | Rust | C++ (qpdf) |
Wheel sizes are the ranges of published files for pylopdf 0.10.0, pymupdf 1.28.0, pypdfium2 5.12.1, pdf-oxide 0.3.75, and pikepdf 10.10.0 on 2026-07-25; the exact artifact depends on platform and Python ABI.
- Fits size-constrained environments such as AWS Lambda
- Safe for commercial projects that need to avoid the AGPL
- abi3: one wheel covers Python 3.10–3.14
- v0.10 includes native
cp314twheels for free-threaded Python 3.14 - API modeled after pymupdf
Limitations: multicolumn text follows deterministic whitespace gutters, and
find_tables() reconstructs bordered grids from strokes or thin filled rules,
including rectangular merged cells. It conservatively separates repeated text
records when a generator omits internal rules inside an otherwise connected
grid. The opt-in
find_tables(strategy="text") handles high-confidence borderless layouts, but
can interpret aligned multicolumn prose as a table. Document.to_markdown()
inserts complete bordered tables by default; pass table_strategy="text" to
opt into borderless candidates or None to preserve plain layout text.
Vertical CJK columns are
reconstructed conservatively and ordered right-to-left; ruby, warichu, and
mixed-orientation Japanese typography are not interpreted semantically. There
is no general-purpose regeneration of arbitrary existing annotation
appearances. AcroForm filling generates appearances for text, choice, checkbox,
radio, and comb text fields, but rich text, pushbuttons, and signature fields
remain out of scope. Typesetting, PDF/A output, and digital signatures are
covered by the ecosystem recipes below. Native OCR returns axis-aligned word
boxes; automatic page orientation, arbitrary deskew, ruby, warichu, and
mixed-orientation typography remain explicit limits.
Install
pip install pylopdf
To render Japanese PDFs without embedded fonts, or auto-subset a JP font for
Japanese/Han insert_text and insert_textbox, install the optional font
package (Noto Sans/Serif JP):
pip install pylopdf[cjk]
For local PP-OCRv6 recognition without system executables, shared libraries, network requests, or an ONNX parser at runtime, install the optional model wheel:
pip install "pylopdf[ocr]"
See the offline OCR guide for memory controls, searchable-layer behavior, and current layout boundaries.
WebAssembly and Cloudflare Workers
pylopdf 0.11 adds a static PyEmscripten wheel for the pinned Python 3.13 /
Pyodide 0.28.3 ABI. Cloudflare Python Workers are the supported public
installation path: every release resolves the wheel from PyPI, bundles the
repository's
bounded PDF extraction Worker, starts
local workerd, and verifies that a module-scope import pylopdf can serve
/health.
Pyodide 0.28.3 itself is runtime-tested, but its older micropip cannot install
PyPI's PEP 783 wheel tag directly. Native OCR inference is intentionally absent
from Wasm; external OCR results can still be inserted with
Page.insert_ocr_text_layer(). See the
WebAssembly guide for the exact
version matrix, local Pyodide workflow, resource policy, and release gates.
Building from source (requires a Rust toolchain):
uv sync
Concurrency and free-threaded Python
Starting with v0.10, pylopdf supports concurrent work on distinct Document
objects. Heavy native operations release the GIL, and the cp314-cp314t wheel
keeps the GIL disabled on free-threaded Python 3.14. Calls or edits on the same
Document must be serialized; use Document.render_pages(workers=...) for
supported parallel rendering within one document.
Pixmap is immutable. The cp314t wheel supports read-only, zero-copy
memoryview(pixmap); the Python 3.10-compatible abi3 wheel uses the one-copy
pixmap.samples fallback. See the
full concurrency contract.
Usage
import pylopdf
# Open from a path or bytes
doc = pylopdf.open("input.pdf")
doc = pylopdf.open(stream=pdf_bytes)
# Page count
print(doc.page_count) # same as len(doc)
# Metadata
print(doc.metadata["title"])
doc.set_metadata({"title": "Monthly Report", "author": "Alice"})
# Text extraction (0-based page numbers)
text = doc.get_page_text(0)
# Positioned text and search (pymupdf-style, top-left origin)
words = doc[0].get_text("words") # (x0, y0, x1, y1, word, block, line, word_no)
layout = doc[0].get_text("dict") # blocks -> lines -> spans with bboxes
rects = doc[0].search_for("tax") # case-insensitive, list[Rect]
tables = doc[0].find_tables(clip=(30, 30, 500, 700)) # complete bordered grids in a region
text_tables = doc[0].find_tables(strategy="text") # opt-in borderless tables
confidence = text_tables[0].confidence if text_tables else None # ranking heuristic, not probability
images = doc[0].get_images() # [{"width", "height", "bbox", "ext", "image"}]
pix = doc[0].get_pixmap(dpi=144, clip=(0, 0, 300, 200)) # cropped RGBA8 pixels for NumPy / PIL
# Rendering
png: bytes = doc.render_page(0) # 72 dpi; 64 MiB encoded-output cap
png2x: bytes = doc.render_page(0, scale=2) # 144 dpi
png300 = doc.render_page(0, dpi=300) # by resolution
png_bg = doc.render_page(0, background=(255, 255, 255)) # white background (default: transparent)
batch = doc.render_pages([0, 1, 2], scale=2, workers=4) # ordered parallel PNGs
svg: str = doc.render_page_svg(0)
# Delete pages (split)
doc.delete_page(0)
doc.delete_pages([1, 2])
# Keep/reorder pages (repeating a page duplicates it)
doc.select([2, 0])
# Page objects (0-based; negative counts from the end)
page = doc[0]
for page in doc:
print(page.number, page.rect)
page.set_rotation(90) # display rotation (multiples of 90)
page.set_mediabox((0, 0, 300, 400)) # page boxes
# Insert / copy pages
doc.new_page() # blank A4 appended
doc.copy_page(0, to=1) # duplicate page 0 in front of page 1
# Drawing (coordinates are the same top-left display space as search_for / get_text)
page.insert_image((72, 72, 200, 200), filename="logo.png") # JPEG passthrough, PNG with alpha
page.insert_image(page.search_for("Approved")[0], stream=stamp_png) # stamp at a search hit
page.insert_image((300, 72, 500, 200), pixmap=thumbnail, rotate=90) # direct RGBA, clockwise rotation
page.show_pdf_page(page.rect, letterhead) # vector overlay; same-document sources also work
page.replace_text("DRAFT", "FINAL") # bounded, atomic simple-font replacement
# Headers / footers / page numbers (standard-14 fonts, WinAnsi range)
for i, p in enumerate(doc):
p.insert_text((p.rect.width - 90, p.rect.height - 30), f"Page {i + 1}", fontsize=9)
# Japanese/Han text auto-subsets the JP font with pip install "pylopdf[cjk]"
page.insert_text((40, 80), "社外秘", fontsize=20, color=(0.8, 0, 0))
# Wrap a paragraph into a rectangle; negative means nothing was drawn
spare = page.insert_textbox(
(40, 100, 300, 220),
"日本語も空白なしで自然に折り返します。",
fontsize=12,
align=pylopdf.TEXT_ALIGN_JUSTIFY,
)
# Annotations: search & highlight / link
page.add_highlight_annot(page.search_for("important")) # appearance stream included (visible everywhere)
page.add_link_annot(page.search_for("Example")[0], "https://example.com/")
print(page.annots()) # [{"type", "rect", "contents", "uri"}]
# Native offline OCR: model inputs share a 64 MiB cap; add a searchable layer
engine = pylopdf.OcrEngine(threads=4, max_concurrent=1) # pip install "pylopdf[ocr]"
words = page.get_text_ocr(engine=engine)
page.apply_ocr(engine=engine) # skips existing searchable text by default
# Correct a sideways scan clockwise for OCR without changing page rotation
page.apply_ocr(engine=engine, rotation=270)
# Or write external OCR results as an invisible text layer
page.insert_ocr_text_layer(ocr_words) # (x0, y0, x1, y1, text, ...); max 4,096 words / 1 MiB UTF-8 text
# Markdown conversion (RAG / LLM preprocessing; bordered tables are automatic)
md = doc.to_markdown()
md_with_borderless_tables = doc.to_markdown(table_strategy="text")
md_p1 = doc[0].to_markdown()
# Read the PDF/A self-declaration (1 MiB XMP cap; validation belongs to veraPDF)
print(doc.get_pdfa_claim()) # e.g. (2, "B") for PDF/A-2b; None if absent
# Forms (AcroForm): read and fill
print(doc.get_form_fields()) # [{"name", "type", "value"}]
doc.set_form_field("customer", "Taro Yamada")
doc.set_form_field("customer_ja", "山田 太郎") # auto-subset with pylopdf[cjk]
doc.set_form_field("agree", True) # checkboxes take bool or a state name
# Page labels (display numbers: roman front matter + decimal body, etc.)
doc.set_page_labels([{"startpage": 0, "style": "r"}, {"startpage": 3, "style": "D"}])
print(doc[4].get_label()) # "2"
# File attachments (e.g. attach the XML data to an invoice PDF)
doc.embfile_add("invoice.xml", xml_bytes, filename="invoice-data.xml")
print(doc.embfile_names()) # ["invoice.xml"]
xml = doc.embfile_get("invoice.xml") # decoded output is capped at 64 MiB by default
# known_large = doc.embfile_get("archive.bin", max_size=256 * 1024 * 1024)
# Table of contents (page numbers are 1-based here, pymupdf-compatible)
doc.set_toc([[1, "Chapter 1", 1], [2, "Section 1.1", 2]])
print(doc.get_toc())
# Merge (with ranges, reversed order, and an insertion position)
merged = pylopdf.Document()
merged.insert_pdf(pylopdf.open("a.pdf"))
merged.insert_pdf(pylopdf.open("b.pdf"), from_page=0, to_page=2, start_at=0)
# Save
merged.save("merged.pdf")
data: bytes = merged.tobytes() # 512 MiB output cap; max_size=None opts out
# Optimized save (prune unreferenced objects + compress + object streams)
merged.save("small.pdf", garbage=True, deflate=True, object_streams=True)
# Encrypted save (AES-256; owner_pw alone = open freely, restricted permissions)
merged.save("locked.pdf", user_pw="secret", permissions=pylopdf.Permissions.PRINT)
# Fast metadata probe without parsing the whole file
info = pylopdf.peek_metadata("input.pdf")
print(info["title"], info["page_count"], info["encrypted"], info["repaired"])
# Context manager
with pylopdf.open("input.pdf") as doc:
print(doc.metadata)
# Encrypted PDFs (RC4-40/128, AES-128, AES-256; empty user passwords open transparently)
doc = pylopdf.open("locked.pdf", password="secret")
doc = pylopdf.open("locked.pdf")
if doc.needs_pass:
doc.authenticate("secret") # 0=failed, 2=user, 4=owner, 6=both
# A bounded repair of an incorrect final classic startxref is always visible.
if doc.is_repaired:
doc.save("normalized.pdf")
# CJK fallback font for PDFs without embedded fonts
# (automatic with pylopdf[cjk]; or bring your own font)
doc.set_fallback_font("NotoSansJP-Regular.otf")
doc.set_fallback_font(font_bytes, kind="serif")
Embedded-font insert_text shapes each line with HarfRust and asks krilla to
subset and embed the resulting glyphs. With pylopdf[cjk], Japanese and Han
text automatically selects its JP-subset sans font; a Times fontname selects
serif. This is one whole-run font selection, not per-glyph fallback. Pass
fontfile= / fontbuffer= for Hangul, locale-specific Chinese glyph forms,
other scripts, or another typeface. RTL glyph shaping works, but extraction
currently follows visual rather than logical order. Use typst below when full
typesetting is required.
Ecosystem recipes (typesetting, PDF/A, signatures)
pylopdf stays a lightweight core for editing, extraction, rendering, and bounded text/form generation; adjacent concerns are solved by pairing it with established libraries. The recipes below are covered by integration tests (tests/test_interop.py).
Typesetting / creating new documents = typst (via typst-py). Typeset reports with typst and feed the bytes straight into pylopdf:
import typst
import pylopdf
pdf_bytes = typst.compile("report.typ") # typesetting: typst
doc = pylopdf.open(stream=pdf_bytes) # editing / extraction / merging: pylopdf
PDF/A for new documents is also typst's job (validated export via krilla; PDF/A-1b through 4 and PDF/UA-1):
pdf_a: bytes = typst.compile("report.typ", pdf_standards="a-2b")
Richly typeset CJK watermarks / headers / footers can combine typst with
pylopdf. For simple text, use insert_text(fontfile=...) directly; for a
full-page composition, typeset one stamp page with typst (fonts get
subset-embedded), then burn it onto every page as vectors with show_pdf_page:
from pylopdf_fonts_cjk import sans_path # pip install pylopdf[cjk] (reuses the Noto fonts)
stamp_typ = """
#set page(width: 595pt, height: 842pt, fill: none)
#set text(font: "Noto Sans JP", size: 48pt, fill: rgb(255, 0, 0, 40%))
#align(center + horizon)[社外秘]
"""
stamp = pylopdf.open(stream=typst.compile(stamp_typ.encode(), font_paths=[str(sans_path().parent)]))
for page in doc:
page.show_pdf_page((0, 0, page.rect.width, page.rect.height), stamp)
Converting or validating existing PDFs against PDF/A is a different problem; veraPDF (Java) is the de-facto validator.
Digital signatures (PAdES) = pyHanko (MIT). pyHanko signs with an incremental update, so the bytes produced by pylopdf remain untouched as a prefix of the signed file:
import io
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers
signer = signers.SimpleSigner.load("key.pem", "cert.pem")
out = signers.sign_pdf(
IncrementalPdfFileWriter(io.BytesIO(doc.tobytes())),
signers.PdfSignatureMetadata(field_name="Signature1"),
signer=signer,
)
signed_pdf: bytes = out.getvalue()
API
pylopdf.Document (pylopdf.open() is an alias constructor):
| Method / property | Description |
|---|---|
Document(filename=None, stream=None, password=None, max_decompressed_size=None, *, limits=None) |
Open from a path or bytes; empty document if both are None. Use limits=DocumentLimits.web() for a complete untrusted-upload policy; max_decompressed_size remains the compatible per-stream shorthand |
doc[i] / load_page(pno) / for page in doc |
Get a Page view (negative indices count from the end; re-fetch after structural changes) |
needs_pass / is_encrypted |
Encryption status (pymupdf-compatible semantics) |
is_repaired |
Whether opening repaired an incorrect final classic startxref; a PylopdfWarning is also emitted and saving normalizes the xref data |
authenticate(password) |
Decrypt with a password (returns 0/1/2/4/6, pymupdf-compatible) |
page_count / len(doc) |
Number of pages |
limits / complexity |
Immutable open-time resource policy / cheap page, object, stream, encoded-byte, and direct-depth facts without decoding |
metadata |
Bounded standard metadata dict (title, author, subject, keywords, creator, producer, creationDate, modDate, format); 1 MiB aggregate Info text |
set_metadata(dict) |
Atomically set standard metadata under the 1 MiB input/encoded boundary (empty string deletes the entry) |
get_page_text(pno, option="text") |
Extract text (or positioned layout: "words" / "blocks" / "dict") |
render_page(pno, scale=1.0, dpi=None, background=None, max_size=64 MiB) |
Render bounded PNG bytes; dpi replaces scale, background is an RGB(A) fill (max 65,535 px per side / 64 MP total); None opts out |
render_pages(pages=None, scale=1.0, workers=None, max_size=512 MiB, ...) |
Render up to 4,096 ordered PNGs from one immutable snapshot; up to 4 workers by default, ~512 MB estimated live-work concurrency, and a cumulative encoded-output cap (None opts out) |
render_page_svg(pno, max_size=64 MiB) |
Render bounded UTF-8 SVG; over-limit output is rejected before Python string conversion, None opts out |
compress_images(dpi=150, quality=75) |
Lossily downsample and JPEG-recompress safe unmasked DeviceGray/DeviceRGB DCT or Flate XObjects; preserves the largest reuse, skips non-smaller output, and returns typed byte/count statistics |
set_fallback_font(font, kind="sans", index=0, max_font_size=64 MiB) |
Set a bounded fallback font (path/bytes) for non-embedded CJK fonts; font=None disables auto-detection and max_font_size=None opts trusted font input out |
select(page_numbers) |
Keep up to 4,096 page entries in the given order (repeats duplicate the page) |
delete_page(pno) / delete_pages(iterable) |
Delete up to 4,096 page entries per call; an empty iterable is a true no-op |
insert_pdf(other, from_page=0, to_page=-1, start_at=-1) |
Merge up to 4,096 pages per call (negative / reversed ranges; start_at sets the insertion position) |
new_page(pno=-1, width=595, height=842) / copy_page(pno, to=-1) |
Insert a blank page / duplicate a page |
get_toc() / set_toc(toc) |
Read/write cycle-aware bounded outlines as [[level, title, page], ...] (page numbers are 1-based here; caps: 4,096 entries/nodes, 8,192 edges, 64 levels, 1 MiB text) |
to_markdown(pages=None, table_strategy="lines", max_size=64 MiB) |
Page-at-a-time two-pass Markdown conversion with a bounded linear entry builder, capped at 4,096 pages and cumulative UTF-8 output (None opts out); headings, emphasis, CJK joining, lists, columns, vertical order, and bordered/opt-in borderless tables |
get_form_fields() / set_form_field(name, value, fontfile=, fontbuffer=, fontindex=, max_font_size=64 MiB) |
List and fill AcroForm fields with native text/choice/button appearances; bounded field-tree/name/value/button-state/font interpretation; checkboxes take bool |
get_pdfa_claim(max_size=1 MiB) |
Bounded-decode the XMP PDF/A declaration (part, conformance) (a self-claim read, not validation); max_size=None explicitly opts out |
embfile_add(name, data, filename=, desc=) / embfile_names() / embfile_get(name, max_size=64 MiB) / embfile_del(name) |
Add / list / bounded-decode / delete attachments; max_size=None explicitly opts out, name trees are capped at 4,096 entries/nodes, and add metadata plus inline FileSpec clone shapes are bounded |
get_page_labels() / set_page_labels(labels) |
Read/write page label ranges ({"startpage", "style", "prefix", "firstpagenum"}); fixed caps: 4,096 entries/nodes, 32 levels, 1 MiB label text |
save(filename, garbage=, deflate=, object_streams=, user_pw=, owner_pw=, permissions=) / tobytes(same, max_size=512 MiB) |
Atomically replace a file after a complete same-directory streamed write, or return bounded PDF bytes; prune / compress / object streams, or AES-256 encryption via user_pw / owner_pw; max_size=None opts out of the byte-return limit |
close() |
Close (supports with) |
pylopdf.Page (obtained via doc[i]):
| Method / property | Description |
|---|---|
number / parent |
0-based page number and owning Document |
get_label() |
Display label of the page ("iv", "A-2", …; empty string if undefined) |
get_text(option="text") |
Text extraction; "words" / "blocks" / "dict" return positioned layout |
get_text_ocr(dpi=300, engine=None, tile_size=1408, overlap=192, min_confidence=0.5, rotation=0, clip=None) |
Recognize positioned words locally through pylopdf[ocr] without modifying the page; rotation corrects rendered input clockwise and clip uses display coordinates |
apply_ocr(..., rotation=0, clip=None, skip_existing=True) |
Recognize and insert an orientation-aware invisible searchable layer; existing searchable text in the selected region is skipped by default |
to_markdown(table_strategy="lines", max_size=64 MiB) |
Single-page Markdown with the same table and UTF-8 output controls as the document method |
search_for(needle) |
Case-insensitive text search returning list[Rect] |
find_tables(strategy="lines", clip=None) |
Detect complete or conservatively refined bordered grids and rectangular merged cells; use strategy="text" for opt-in borderless detection; clip filters in display coordinates and results expose confidence diagnostics |
get_images() |
Extract page images (original JPEG bytes passed through; others as PNG); rejects partial output above 4,096 placements, 64,000,000 cumulative pixels, or 64 MiB of payloads per page |
get_drawings() |
Extract interpreted vector fill/stroke paths as typed pymupdf-style dictionaries with display-space line/cubic geometry, RGB/opacity, fill rule, width, cap, join, and dashes |
get_pixmap(scale, dpi=, background=, clip=None) |
Render to an immutable Pixmap; clip is a display-coordinate rectangle (straight RGBA8: samples / width / height / stride / tobytes(max_size=64 MiB) / streaming, failure-atomic PNG-only save(path); cp314t also supports read-only zero-copy memoryview()) |
insert_image(rect, filename=/stream=/pixmap=, rotate=0, keep_proportion=True, overlay=True, max_size=64 MiB, max_pixels=64,000,000) |
Draw JPEG without recompression, bounded PNG with alpha, or a rendered RGBA Pixmap without a PNG round trip; None opts trusted encoded input or PNG pixels out of its boundary; optional clockwise right-angle rotation and rect use display coordinates |
show_pdf_page(rect, src, pno=0, keep_proportion=True, overlay=True) |
Overlay a page as vectors from another or the same document; same-document placement uses a stable pre-edit snapshot |
insert_text(point, text, fontsize=11, fontname="helv", fontfile=, fontbuffer=, fontindex=, color=, overlay=True, max_font_size=64 MiB) |
Print multiline text with a standard-14 or bounded shaped subset font; pylopdf[cjk] auto-selects its JP font for Japanese/Han; None opts trusted font input out; upright on rotated pages |
insert_textbox(rect, text, fontsize=11, fontname="helv", fontfile=, fontbuffer=, fontindex=, color=, align=0, lineheight=None, expandtabs=8, overlay=True, max_font_size=64 MiB) |
Wrap with UAX #14 and Core 14, bounded explicit OpenType, or auto-selected JP font metrics; returns spare height and draws nothing on overflow |
insert_ocr_text_layer(words, rotation=0) |
Write up to 4,096 words / 1 MiB UTF-8 text as an orientation-aware invisible OCR layer (searchable PDFs; no font embedding) |
annots() / get_links() |
Bounded annotation/link reads, including one cycle-aware named-destination index per call (4,096 annotations and 1 MiB aggregate metadata text; display coordinates) |
add_highlight_annot(rects, color=(1,1,0), opacity=0.4, content=None) |
Highlight annotation; feed up to 4,096 search_for results directly; appearance stream included; 1 MiB subtype/content budget |
add_link_annot(rect, uri) |
URI link annotation (no border; 1 MiB subtype/URI budget) |
replace_text(search, replacement, default_char=None, max_size=64 MiB) |
Atomic copy-on-write text replacement (simple-encoded fonts only; bounded input/output; returns the count; no CJK) |
render(scale, dpi=, background=) / render_svg(max_size=64 MiB) |
PNG / bounded UTF-8 SVG rendering |
rotation / set_rotation(deg) |
Display rotation (multiples of 90, inheritance-resolved) |
mediabox / cropbox / rect |
Page boxes (Rect); rect is the rotation-aware visible rectangle |
set_mediabox(rect) / set_cropbox(rect) |
Set page boxes |
Drawing insertions preflight page /Contents before decoding inputs or creating
dependent objects. The resulting array is capped at 4,096 stream references;
the one-time q/Q isolation pair is included in that total, and failures do
not mutate the document.
Module level:
| Name | Description |
|---|---|
peek_metadata(filename/stream, password=None) |
Fast metadata / page-count / encryption probe; repaired reports bounded classic-startxref recovery |
Permissions |
Encryption permission flags (IntFlag) |
Rect |
Rectangle NamedTuple with width / height |
ImageCompressionResult |
Typed counts and rewritten source/result byte totals from compress_images() |
DrawingInfo / DrawingItem |
Typed vector-path dictionary and its line/cubic command union |
TEXT_ALIGN_LEFT / CENTER / RIGHT / JUSTIFY |
insert_textbox alignment constants (0–3, pymupdf-compatible) |
OcrEngine / OcrWord / OcrRotation |
Reusable pure-Rust PP-OCR engine, its typed positioned-word result, and the 0 / 90 / 180 / 270 clockwise-correction contract |
TableFinder / Table / TableDiagnostics |
Owned table geometry, cell text, strategy, and confidence evidence; Table.to_markdown(max_size=64 MiB) preflights escaped UTF-8 output |
PylopdfWarning |
Recoverable interpretation warning, including bounded xref repair, font resolution, and image decoding |
| Exceptions | PdfError (ValueError-compatible base), PasswordError, OcrError, DocumentClosedError, EncryptedDocumentError, StalePageError |
For low-level access, use pylopdf.pylopdf_core._Document (a thin lopdf wrapper) directly.
Architecture
Follows the division of labor in the 2026 Rust PDF ecosystem:
pylopdf.Document (Python, pymupdf-style API)
└─ _Document (PyO3)
├─ lopdf 0.44 … editing: open → modify → save
├─ hayro 0.7 … rendering and positioned extraction
└─ krilla 0.8 + HarfRust 0.12
… shaped, subset-embedded text and form appearances
rust/ # PyO3 bindings
src/pylopdf/ # Python high-level API
tests/ # pytest (Rust behavior is verified through Python tests)
uv sync # build + install dependencies
uv run pytest # tests
uv run ruff check . # lint
uv run mypy src tests # type check
uv build --wheel # build a wheel
uv sync detects Rust source changes and rebuilds automatically (via tool.uv.cache-keys).
Contributing
Bug reports and focused contributions are welcome. See CONTRIBUTING.md for development commands, test expectations, and the rules for sharing PDF regression files. Report security vulnerabilities privately through GitHub Security Advisories.
Benchmarks
A reproducible benchmark ships with the repo (same corpus, same tasks, medians — wins and losses are published as-is). See bench/results/latest.md for the latest numbers with environment details:
uv sync --all-extras --group bench && uv run python bench/run.py
The separate native OCR report publishes strict and NFKC-normalized CER plus elapsed time on two licensed Japanese fixtures, including an image-only archival scan. It also records a bounded shared-engine concurrency check:
uv sync --all-extras && uv run python bench/ocr.py
License
MIT (lopdf and HarfRust are MIT; hayro and krilla are MIT/Apache-2.0)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pylopdf-0.11.1.tar.gz.
File metadata
- Download URL: pylopdf-0.11.1.tar.gz
- Upload date:
- Size: 218.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f66a52df438aa3a054df9b845c0f664012a8f40146d76f51e274fd12a2779d13
|
|
| MD5 |
e6230bc90d79e67de3077dd44a4aed05
|
|
| BLAKE2b-256 |
af38c0131b0e3d1bd38c1fbd5e20333d02fd51786eb3a9792a821658dd798dfa
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1.tar.gz:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1.tar.gz -
Subject digest:
f66a52df438aa3a054df9b845c0f664012a8f40146d76f51e274fd12a2779d13 - Sigstore transparency entry: 2255886037
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp314-cp314t-win_amd64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp314-cp314t-win_amd64.whl
- Upload date:
- Size: 7.3 MB
- Tags: CPython 3.14t, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
049e002edc52dfb14323bdbad166625ba77e5985da47cbcf25610fc17a4bc1c5
|
|
| MD5 |
c66975554cad24a3d9d8772ee1dfc9eb
|
|
| BLAKE2b-256 |
a1556a19aa20c77233ee08ef03100d9696d06305e7b7f56280803a3186c87715
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp314-cp314t-win_amd64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp314-cp314t-win_amd64.whl -
Subject digest:
049e002edc52dfb14323bdbad166625ba77e5985da47cbcf25610fc17a4bc1c5 - Sigstore transparency entry: 2255886120
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 8.1 MB
- Tags: CPython 3.14t, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3aee08ebbb89b387f808d2a3c7728eff997e87742730203f51f479a8cfe1293e
|
|
| MD5 |
daedb382472805628d1a6e7aea1fe2ff
|
|
| BLAKE2b-256 |
07b7cf1cfc68a04fa5f7630cfb514bf3e90d5ebf1ba9465d1c2fdda91a25b008
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
3aee08ebbb89b387f808d2a3c7728eff997e87742730203f51f479a8cfe1293e - Sigstore transparency entry: 2255886052
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 8.0 MB
- Tags: CPython 3.14t, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f02a39d2b90624db034183e6971d5170277c5ddfa3298fc1b4cf0e656b87e37c
|
|
| MD5 |
03ab48fa6a9f6b77b6ed23b0bc8415c8
|
|
| BLAKE2b-256 |
e1032253d285178afbfe080457f0bad276d9b03f62a87ddcd64bb89aa7bc9593
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
f02a39d2b90624db034183e6971d5170277c5ddfa3298fc1b4cf0e656b87e37c - Sigstore transparency entry: 2255886213
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp314-cp314t-macosx_11_0_arm64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp314-cp314t-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.0 MB
- Tags: CPython 3.14t, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8712fa01e34e319788c43ba14b659965bc28a1620ac85b76d53b6141ff80133
|
|
| MD5 |
182d7bb1bf05abaf8b87938e84fac4ba
|
|
| BLAKE2b-256 |
3b9f67e6c462e57483610c8a959e623811008f9c9622ae3a2e691c05a885661a
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp314-cp314t-macosx_11_0_arm64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp314-cp314t-macosx_11_0_arm64.whl -
Subject digest:
b8712fa01e34e319788c43ba14b659965bc28a1620ac85b76d53b6141ff80133 - Sigstore transparency entry: 2255886180
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp314-cp314t-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp314-cp314t-macosx_10_12_x86_64.whl
- Upload date:
- Size: 7.6 MB
- Tags: CPython 3.14t, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f897bca907b5630615253cb19753e20fa5206e2b710081d7aa60e28cdb70df2
|
|
| MD5 |
8b5164c3ef74e99dea61b7cdf552237c
|
|
| BLAKE2b-256 |
119a04c6c48a35239bb320b765c527d4c0fa921d5811df83b4929afd97da93fd
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp314-cp314t-macosx_10_12_x86_64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp314-cp314t-macosx_10_12_x86_64.whl -
Subject digest:
6f897bca907b5630615253cb19753e20fa5206e2b710081d7aa60e28cdb70df2 - Sigstore transparency entry: 2255886239
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 7.3 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a05db005f387c11bf82218153a7553860fa6d9c534e0daa2ca72108388e18d8d
|
|
| MD5 |
94de9221a319870ffed0c992fd502821
|
|
| BLAKE2b-256 |
576bcfa3e60f9894aaec2a0cd5deb1ea67cee91726a2f7a7f06b2664756ddab4
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-win_amd64.whl -
Subject digest:
a05db005f387c11bf82218153a7553860fa6d9c534e0daa2ca72108388e18d8d - Sigstore transparency entry: 2255886195
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-pyemscripten_2025_0_wasm32.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-pyemscripten_2025_0_wasm32.whl
- Upload date:
- Size: 4.1 MB
- Tags: CPython 3.10+, PyEmscripten 2025.0 wasm32
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
288d9feaea45fc8cecc5012eee8e574cf772ca0d27d19c7109c81617f9eba15d
|
|
| MD5 |
82e835eae8b9067c00dd3b719e633578
|
|
| BLAKE2b-256 |
500ce3c34b3fde233a9a6a6ca0b8345153db63c4c1816d51f8cfdc2ec293860d
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-pyemscripten_2025_0_wasm32.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-pyemscripten_2025_0_wasm32.whl -
Subject digest:
288d9feaea45fc8cecc5012eee8e574cf772ca0d27d19c7109c81617f9eba15d - Sigstore transparency entry: 2255886161
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 8.2 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61c2d020e25fdc5c5a156dc9bf87e803bccf045779835ba574445e68908b8d68
|
|
| MD5 |
fb16d11e922796b31a6e7867a5eebabb
|
|
| BLAKE2b-256 |
8410bdd027018086061a5c2a075fde0d992f42613260f1272867efa8f506b027
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
61c2d020e25fdc5c5a156dc9bf87e803bccf045779835ba574445e68908b8d68 - Sigstore transparency entry: 2255886267
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 8.0 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f642bd288b529ade373a0ce172ff5d99905850de5deacf2559ce5cb8e79b5728
|
|
| MD5 |
771315245d0908f7c77a8484fc272a8e
|
|
| BLAKE2b-256 |
320a8e5a72157e245c57b7ad1973eb31e3abd82fa4c23ebdeb0edcb05c07eb4c
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
f642bd288b529ade373a0ce172ff5d99905850de5deacf2559ce5cb8e79b5728 - Sigstore transparency entry: 2255886136
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.0 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c673fd9fdc55251b71f641fb715c64f69ef21ac1bac5d1de9e2f49d1445d9b8
|
|
| MD5 |
1684eeed0362724cc207dca6de62acfc
|
|
| BLAKE2b-256 |
902549c1ef8820ccc698aadff6cb768b316e45f0c723392d44f8009cf6f13d05
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
4c673fd9fdc55251b71f641fb715c64f69ef21ac1bac5d1de9e2f49d1445d9b8 - Sigstore transparency entry: 2255886066
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pylopdf-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pylopdf-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 7.6 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b90c42c6e9d13bbeb0e8fe272528eb709146e82fb089e24aa1e079204def9be
|
|
| MD5 |
349b829fc207f8f673e947c6d07ac013
|
|
| BLAKE2b-256 |
3a80dc27270e5d4c778e3b9e55e0ef3e9a0d3f73ee86ecf3c44c45bdf3f0fc63
|
Provenance
The following attestation bundles were made for pylopdf-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on yhay81/pylopdf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pylopdf-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
8b90c42c6e9d13bbeb0e8fe272528eb709146e82fb089e24aa1e079204def9be - Sigstore transparency entry: 2255886097
- Sigstore integration time:
-
Permalink:
yhay81/pylopdf@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Branch / Tag:
refs/tags/v0.11.1 - Owner: https://github.com/yhay81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b91ec71e37d85a8b23a4c089f18ed44f7b3506d -
Trigger Event:
push
-
Statement type: