Releases: Sevthered/pdf2wiki
Release list
pdf2wiki 0.2.6 — provenance & hardening
[0.2.6] - 2026-07-24
A hardening, quality, and provenance release — the first published via signed, attested Trusted
Publishing. No converter behavior change: conversion output is byte-for-byte identical to 0.2.5.
Added
- Typed public API — the package now ships
py.typed(PEP 561), so downstream projects' type
checkers see pdf2wiki's types. The core ismypy --strict-clean. - REUSE 3.3 licensing metadata — per-file SPDX headers plus a
REUSE.toml, so every file's copyright and license are machine-readable. - Project governance & security documentation —
GOVERNANCE.md,CODE_OF_CONDUCT.md
(Contributor Covenant 2.1),ROADMAP.md, and a security assurance case at
docs/security/assurance-case.md(threat model, trust boundaries, input-validation map). - OpenSSF tooling — OpenSSF Best Practices badge, an OpenSSF Scorecard workflow, and Codecov
coverage reporting, all surfaced in the README.
Security
- Signed releases. Distributions are published via PyPI Trusted Publishing (OIDC, no stored
token) with PEP 740 provenance attestations; release tags are cryptographically signed. Verify
a tag withgit tag -v vX.Y.Zand the PyPI attestations on each file's page. - Static analysis. CI now runs ruff's
flake8-bandit(S) security ruleset oversrc/. - DCO sign-off. Contributions are signed off under the Developer Certificate of Origin
(git commit -s); vulnerability reporters are credited in advisories unless they opt out.
Changed
- Internal typed-
Blockrefactor with amypy --strictCI gate and Hypothesis property tests
for thephase5transformers. Locked byte-identical by golden snapshots — no user-facing change.
pdf2wiki 0.2.5 — ssh keepalive for long remote converts
A remote-mode robustness fix found by the first full-book (354-page) remote conversion. No API
changes; +1 test (108 → 109).
pip install --upgrade pdf2wiki # 0.2.5
Fixed
- Long remote conversions no longer drop the SSH control channel. During a long MinerU pass all
converter output goes to a remote log file, so the SSH channel is silent for minutes; a NAT/idle
timeout (common with WSL2 mirrored networking) could drop it, andbatchwould then mislabel a
still-running convert asconvert_failedwhile the remote job kept going. Every remote ssh/scp
call now sends keepalives (ServerAliveInterval=30,ServerAliveCountMax=240— ~2 h of tolerated
silence, within the existingtimeout Nsremote reaper). If a drop still happens, a re-run resumes
from cached (.done) passes rather than restarting.
Docs: new troubleshooting entry
for this symptom.
Full changelog: CHANGELOG.md ·
PyPI: https://pypi.org/project/pdf2wiki/0.2.5/
pdf2wiki 0.2.4 — fix remote-convert output paths
A targeted fix found by the first real end-to-end remote conversion run. No API changes; +1 test
(107 → 108).
pip install --upgrade pdf2wiki # 0.2.4
Fixed
- Remote convert produced no output (
FAILED pass … no content_list.json).run_mineruhanded the
MinerU subprocess a relative-o/-p, but MinerU runs with a different working directory (the
stdlib-shadow-safeclean_cwd), so its output landed where pdf2wiki couldn't find it. This only bit
--remotemode, where--outis passed home-relative (_remote_pathstrips the leading~/). The
local path was unaffected (convert_bookalreadyexpanduser-esout_rootto an absolute path).
Now the paths handed to MinerU are absolutized withos.path.abspath(idempotent for the local case).
A regression test reproduces the cwd divergence and locks the fix.
Verified end-to-end on a real GPU box: a remote batch now writes both passes' content_list.json to the
correct tree, produces a clean merged Markdown, and leaves no orphaned GPU job.
Full changelog: CHANGELOG.md ·
PyPI: https://pypi.org/project/pdf2wiki/0.2.4/
pdf2wiki 0.2.3 — QA flags report + batch error_class rollup
QA + diagnostics from an external review of the repo. No breaking changes — every existing command
and flag behaves the same. Test suite 103 → 107 passing.
pip install --upgrade pdf2wiki # 0.2.3
Added
pdf2wiki qa flags PATHS...— a per-book report of the code blocks where the VLM diverged from the
byte-clean text layer (_code_flag), or where hybrid indentation failed a Python ast check
(_indent_flag), read straight fromblocks.json. Pass several books'blocks.jsonand it ranks them
by flagged count (which books to trust least); pass one and it lists each flagged block (page /
language / snippet). These are the highest-signal spots to spot-check a conversion.
Changed
- Batch summary rolls up
error_class— a partial batch now prints, e.g.
5 book(s) not done — by class: permanent×3, timeout×1, fetch×1(plus the slug list), so a cluster of
same-kind failures reads as one diagnosis instead of N separate slugs. Exit code unchanged.
Full changelog: CHANGELOG.md ·
PyPI: https://pypi.org/project/pdf2wiki/0.2.3/
pdf2wiki 0.2.2 — resilience & security hardening
Resilience + security hardening from a book-grounded review (Kubernetes / microservices / API-security
references). No API changes — every existing command and flag behaves the same. Test suite 93 → 103 passing.
pip install --upgrade pdf2wiki # 0.2.2
Security
- Zip-slip guard — the mineru.net result ZIP (fetched from a server-supplied URL) is now validated
member-by-member before extraction; a..//absolute member is rejected instead of overwriting
arbitrary files. - HTTPS enforced on the API base URL, the presigned upload URL, and the result-download URL before
the Bearer token or the PDF is sent — a config/response downgrade tohttp://is refused. - Untrusted-response handling — submit-response fields are validated (clear error instead of a raw
KeyError); upstream error bodies are truncated + single-lined; presigned URLs are redacted (query
stripped) in error messages. - Token hygiene —
pdf2wiki.tomlis now gitignored and the config documents preferring
MINERU_API_TOKEN/token_fileover an inline token.
Added
- Retry with backoff + jitter on the cloud HTTP calls (submit / upload / result download) and
bounded tolerance for transient errors mid-poll — a momentary network blip or HTTP 429/5xx no longer
fails an otherwise-healthy conversion. Transient (429/5xx/network) vs permanent (4xx/API-error) is
classified; permanent errors still fail fast. Tunable:[mineru_cloud].retries,retry_base_delay,
poll_max_transient. - Batch circuit breaker — after
[remote].max_consec_fail(default 3) consecutive book failures the
batch re-probes executor health and aborts if the dependency is dead, instead of fast-failing every
remaining book. A healthy probe continues (content failures don't trip it). - Per-pass cloud resume — each cloud pass writes a
.donesentinel; a re-run reuses a completed pass
instead of re-uploading and re-paying. - Manifest now records an
error_classper failed book (transient / permanent / timeout / fetch / phase5).
Changed
- Remote convert timeout now kills the remote job — the SSH convert wraps the converter in a
server-sidetimeout Nsreaper, so a client-side timeout no longer leaves a zombie MinerU/vllm job
pinning GPU VRAM. SSH/scp calls gainConnectTimeout+BatchMode=yes;fetch()scp transfers are
now timeout-bounded and remote paths are shlex-quoted. - Local MinerU timeout kills the whole process group (
start_new_session=True+killpg), so
orphaned vllm/torch workers no longer survive a timed-out pass.
Full changelog: CHANGELOG.md ·
PyPI: https://pypi.org/project/pdf2wiki/0.2.2/
pdf2wiki 0.2.1 — cloud support in core
[0.2.1] - 2026-07-23
Changed
requestsis now a core dependency; thecloudoptional extra introduced in 0.2.0 is removed.
pip install pdf2wikiincludes the--mineru-cloudconverter out of the box — installpdf2wiki,
notpdf2wiki[cloud].
Install: pip install pdf2wiki (the cloud converter is now included — no [cloud] extra).
Full changelog: CHANGELOG.md.
pdf2wiki 0.2.0 — cloud & GPU-less conversion
⚠ Superseded by v0.2.1. As of 0.2.1 the cloud converter ships in the base package — install
pdf2wiki(the[cloud]extra shown below was removed). The 0.2.0 notes are kept below for history.
[0.2.0] - 2026-07-23
Added
Three GPU-less / offload conversion paths, so a machine with no local GPU (or no MinerU at all) can still
convert:
convert --hybrid-server-url URL— offload only the hybrid VLM pass to a BYO OpenAI-compatible MinerU
server; the pipeline pass stays local (runs on CPU). Effort / image-analysis (Mermaid, chart
transcription) is preserved. Mutually exclusive with--remote; fails fast (never silently falls back).convert --mineru-cloud— fully-managed conversion via the mineru.net Precision API: no GPU, no MinerU
install, token only.--cloud-model pipeline(default, code-safe) |vlm|MinerU-HTML. Uploads the
PDF to a third-party cloud (loud data-egress warning), ≤200 pages/file, token never logged. Needs the
newcloudextra:pip install 'pdf2wiki[cloud]'.convert --mineru-cloud --cloud-model merge— runs BOTH cloud passes (pipeline + vlm) and splices them
with pdf2wiki's own base-driven merge locally: byte-clean code (pipeline tokens) AND correct
indentation / tables / Mermaid (vlm), fully GPU-less. Costs 2× the daily page quota and 2× egress.- New
[mineru_cloud]config section and[mineru].hybrid_server_urlsetting. - Docs: how-to guides for offloading the hybrid pass and converting in the cloud.
Fixed
- The code-diverge merge path now recovers Python indentation from the hybrid pass (fuzzy
difflib
re-indent) instead of emitting flat pipeline tokens — Python code with genuine token divergence keeps
its indentation.
Install: pip install 'pdf2wiki[cloud]==0.2.0' (the [cloud] extra enables --mineru-cloud).
Full changelog: CHANGELOG.md.
v0.1.2
fix: fold all 11 audit findings into a 0.1.2 release
Pre-publish deep scan of src/ surfaced correctness/robustness bugs also
present in 0.1.0/0.1.1. This lands all eleven (5 HIGH + 6 MED), each with a
regression test (58 -> 75 tests), and cuts a 0.1.2 (v0.1.1 was tagged on
GitHub but never published to PyPI; 0.1.2 avoids a public-tag rewrite).
HIGH:
- watermark detection: bucket by abs_page, not chunk-relative page_idx
- open() everywhere: encoding="utf-8" (UnicodeError under non-UTF-8 locale)
- qa sample: clamp n to the page window (crashed on books < ~23 pages)
- chapter-split frontmatter: JSON-quoted scalars -> always valid YAML
- batch: catch convert/fetch errors per-book instead of aborting the run
MED:
- indent_suspect: catch ValueError (NUL byte in code) alongside SyntaxError
- run_mineru: TimeoutExpired -> PassFailed (clean hard-stop, cache intact)
- scan_one: page reads inside try -> one bad page can't abort the dir scan
- batch CLI: exit non-zero when any book is not done
- ToC: drop destination-less level-1 bookmarks (page -1) -> no spurious H1
- render_block: coerce explicit JSON-null field values to "" (no crash)
pdf2wiki 0.1.1
Fixed
- The
phase5command summary now reports thecode_unescapestep.
Added
- PyPI page now links to the GitHub repo, docs, issues, and changelog.
- README badges (PyPI version, Python versions, license).
CHANGELOG.mdandCONTRIBUTING.md.
Install: pip install pdf2wiki
Full changelog: https://github.com/Sevthered/pdf2wiki/blob/main/CHANGELOG.md