feat(python): integrate pyodr bindings from OpenDocument.py#616
Merged
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: badb623522
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
andiwand
force-pushed
the
python-bindings
branch
from
July 25, 2026 16:56
83e5547 to
5574e2e
Compare
Bring the Python bindings into the main repo as a new root `python/` folder, replacing the separate OpenDocument.py repository: - pybind11 bindings rewritten against the current public API: odr free functions, the DecodedFile family, Document + full typed element tree (with keep_alive chains and Python iteration), styles, the HtmlService/HtmlView pipeline (views returned by list_views pin their service so they cannot dangle), Filesystem/Archive, GlobalParams, typed exceptions, and the HTTP server (gated by ODR_WITH_HTTP_SERVER) - `pyodr` package with a CLI (`pyodr <file>`, `--serve` to host over HTTP) and automatic data-asset discovery - hermetic pytest suite (inline-generated txt/csv/json/minimal ODT), including a live HTTP server round-trip - CMake: new ODR_PYTHON option includes python/CMakeLists.txt; install of CLI targets now conditional on ODR_CLI - conan: new with_python option requires pybind11 and wires ODR_PYTHON - packaging: root pyproject.toml (scikit-build-core); wheels bundle the odr.js/css assets under pyodr/data - CI: python.yml with black check, conan build + pytest (ubuntu/macos), wheel + sdist builds; releases attach wheels and sdist as GitHub release assets (nothing goes to PyPI yet — pip cannot build the sdist in an isolated backend and Linux wheels are not manylinux-audited; cibuildwheel+conan wiring is a follow-up) - core fix: implement TextFile::text() (was a TODO stub) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gffw8AurchbpS1rL3kWwBd
Replace the ODR_WITH_HTTP_SERVER ifdef in bind_http_server.cpp with a stub source file chosen in CMake, matching how the CLI handles the option; the compile definition is no longer needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gffw8AurchbpS1rL3kWwBd
CI's conan install rejects the new pybind11/2.13.6 requirement because the lockfile was not regenerated when the dependency was added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gffw8AurchbpS1rL3kWwBd
Drop the hardcoded pyproject version: setuptools-scm derives it from git tags via scikit-build-core dynamic metadata, matching how the conan package version is stamped from the release tag. The wheels/sdist jobs fetch full history so the tags are available. Publish wheels and the sdist to PyPI via trusted publishing on release, like the original OpenDocument.py repo did. Linux wheels are grafted onto a manylinux tag with auditwheel first since PyPI rejects plain linux_* platform tags. Also install ccache in the wheels job: the conan profiles use it as compiler launcher, so conan source builds fail without it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gffw8AurchbpS1rL3kWwBd
andiwand
force-pushed
the
python-bindings
branch
from
July 25, 2026 21:04
e7e94b6 to
92f4d26
Compare
andiwand
enabled auto-merge (squash)
July 25, 2026 21:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 Generated with Claude Code
Integrates the Python bindings from OpenDocument.py into the main repo as a new root
python/folder, so the old repo can be archived.Bindings
The old bindings targeted odrcore 4.1.1, so they were rewritten from scratch against the current public API (public headers only, no internals):
odr.hppfree functions:open(all overloads),list_file_types,mimetype, type/category/engine mappings, version infoDecodedFilefamily incl.FontFile,DecoderEngine,DecodePreference, encryption/decryptDocument+ complete typed element tree with Python iteration; everything returning anElementcarriespy::keep_aliveso handles keep the originatingDocumentaliveMeasure/DynamicUnit,Color,PageLayoutHtmlService/HtmlView/bring_offlinepipeline incl.HtmlConfig(all fields,resource_locatorcallables work),HtmlResource. Views returned bylist_viewspin their service Python object, sotranslate(...).list_views()[0]cannot dangleFilesystem/FileWalker/Archive,GlobalParams, typed exceptions (FileNotFoundmaps to Python'sFileNotFoundError)HttpServer, gated by the centralODR_WITH_HTTP_SERVERoption;listen/stoprelease the GIL.pyodr.has_http_serverreports availabilityThe
pyodrpackage ships a CLI:pyodr <file>renders and opens a document,pyodr <file> --servehosts it over HTTP.Build integration
ODR_PYTHONoption (default OFF) includespython/CMakeLists.txt, which also configures standalone against an installedodrcore. Install of the CLI targets is now conditional onODR_CLI(was unconditional and brokeODR_CLI=OFFbuilds).with_pythonoption (default False) requirespybind11/2.13.6and wiresODR_PYTHONthrough the toolchain.pyproject.toml(scikit-build-core); wheels bundle the odr.js/css assets underpyodr/dataandpyodrauto-configuresGlobalParamson import (env varODR_CORE_DATA_PATHalso honored).Tests
Hermetic pytest suite (32 tests) — inputs generated inline (txt/csv/json, a zip-built minimal ODT): detection/open, text extraction, document element walk + navigation, HTML translation via
bring_offline, view lifetime, and a live HTTP server round-trip. Also registered as a CTest test (pyodr_pytest) whenODR_TESTis on.CI (migrated from OpenDocument.py's format/pip/wheels workflows)
.github/workflows/python.yml:black --check pythonwith_python=True+ pytest on ubuntu-24.04/macos-26, reusing the existing conan profiles and cachesconan-odr-indexrecipes, which the sdist excludes), and the Linux wheels are not manylinux-audited. PyPI publishing via cibuildwheel+conan is a follow-up.Core fix
TextFile::text()was an unimplemented stub (return ""; // TODO) — now reads the underlying stream.