Skip to content

feat(py): PyO3 bindings (fleischwolf-py) — docling-shaped drop-in, local-only - #30

Merged
artiz merged 1 commit into
masterfrom
claude/docling-rust-review-profile-d26fdq
Jul 6, 2026
Merged

feat(py): PyO3 bindings (fleischwolf-py) — docling-shaped drop-in, local-only#30
artiz merged 1 commit into
masterfrom
claude/docling-rust-review-profile-d26fdq

Conversation

@artiz

@artiz artiz commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

The strangler-fig PyO3 bindings from the roadmap — experimental, not published anywhere (the PyPI name is tentative), built locally with maturin:

# was:  from docling.document_converter import DocumentConverter
from fleischwolf import DocumentConverter

result = DocumentConverter().convert("document.pdf")
print(result.document.export_to_markdown())
data = result.document.export_to_dict()          # docling JSON wire format, schema 1.10.0
  • API surface mirrors docling: DocumentConverter(strict, fetch_images, artifacts_path), .convert(path) (str/os.PathLike, GIL released for the conversion), .convert_bytes(name, data) (the DocumentStream counterpart), ConversionResult.status/.document, DoclingDocument.export_to_markdown/export_to_dict/export_to_json/save_as_*.
  • Models download in pure Python, docling-style: fleischwolf.download_models() fetches the pipeline assets (incl. pdfium and the INT8 variants) from the models-v1 GitHub release into ~/.cache/fleischwolf ($FLEISCHWOLF_CACHE_DIR overrides) with stdlib urllib; ensure_env() — called by the constructor — points the native pipeline at the cache via the standard DOCLING_*/PDFIUM_* env vars, preferring INT8 like the Rust default and never overriding explicitly-set variables. Declarative formats need no models at all.
  • Deliberately isolated: standalone crate (own empty [workspace], publish = false) — outside the repo workspace, untouched by CI's cargo test/clippy and by ci_publish.sh. Renaming the distribution later costs nothing.
  • Crate README documents the full local try-it flow (venv → maturin develop --releasedownload_models() → convert); MIGRATION §6 moves PyO3 from "planned" to "experimental in-repo".

Testing (all in-container, per the README steps)

  • maturin develop --release builds and installs into a fresh venv.
  • download_models() pulled 623 MB from the release (required + optional INT8/.data assets, 404-tolerant optional path exercised earlier against a tag without int8).
  • Declarative Markdown conversion, export_to_dict() (schema 1.10.0), bytes API and pathlib.Path inputs pass without any models configured.
  • A PDF converted through the full ML pipeline from a foreign CWD with a clean environment is byte-identical to the CLI's output on the same file (INT8 stack auto-selected from the cache).

🤖 Generated with Claude Code

https://claude.ai/code/session_017fKFbatf55BK5j8vr3dZjj


Generated by Claude Code

crates/fleischwolf-py: a strangler-fig replacement for Python docling's
common path — DocumentConverter(strict, fetch_images, artifacts_path)
.convert(path) / .convert_bytes(name, data) returning a ConversionResult
with .status and .document (export_to_markdown / export_to_dict /
export_to_json / save_as_*). Conversion releases the GIL; paths accept
str/os.PathLike; bytes input detects the format from the name.

Models are handled on the Python side the way docling handles its
artifacts: fleischwolf.download_models() fetches the pipeline assets
(incl. pdfium and the INT8 variants) from the models-v1 GitHub release
into ~/.cache/fleischwolf ( overrides) with pure
urllib, and ensure_env() — called by the converter constructor — points
the native pipeline at them via the standard DOCLING_*/PDFIUM_* env
vars, preferring INT8 like the Rust default (FLEISCHWOLF_FP32 opts
out) and never overriding explicitly-set variables.

Deliberately unpublished and outside the Cargo workspace/crates.io
publish flow (empty [workspace], publish = false; the PyPI name is
tentative). Built locally with maturin — see the crate README for the
try-it steps.

Verified in-container: maturin develop --release; download_models()
pulled 623 MB from the release; Markdown/dict/bytes/pathlib round-trips
pass; a PDF converted through the full ML pipeline from a foreign CWD
with a clean environment is byte-identical to the CLI's output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fKFbatf55BK5j8vr3dZjj
@artiz
artiz merged commit 0522628 into master Jul 6, 2026
3 checks passed
@artiz
artiz deleted the claude/docling-rust-review-profile-d26fdq branch July 6, 2026 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants