Skip to content

Commit 545c0c8

Browse files
tedhabeckaraujofterylt
authored
feat: Python bindings (PyO3) (#70)
* docs: add requirements document for python bindings Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com> * docs: minor update Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com> * docs: add issue 19 implementation plan Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com> * docs: add ce implementation plan for issue 19 Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com> * feat(bindings/python): add PyO3 native bindings for cpex-core PluginManager Introduces `bindings/python/` — a new maturin-built Rust crate (`cpex-python`) that wraps `cpex_core::PluginManager` via PyO3 0.29, exposing a native Python `cpex` package backed entirely by the Rust runtime. Key design points: - `PluginManager(config_path)` — sync constructor; registers APL factories then loads YAML config (order critical for APL Weak upgrade) - `initialize()`, `shutdown()`, `invoke_hook()` — async via pyo3-async-runtimes `future_into_py`; all guarded by a 60 s wall-clock timeout (PY_WALL_CLOCK_TIMEOUT) - CMF hooks route payloads through `MessagePayload`; all others use a local `GenericPayload<serde_json::Value>` - `PipelineResult` exposes 7 read-only Python getters; `__repr__` is pointer-free - `cpex-python` is in `[workspace] members` but not `default-members`, so all pure-Rust CI targets remain libpython-independent (`--exclude cpex-python`) - Makefile gains `bindings-python-{build,build-release,test}` targets - 22 unit/integration tests; all pass alongside 2058 legacy tests (AE3) Signed-off-by: habeck <habeck@us.ibm.com> * chore: Fixed the Python bindings build after the dev branch merge: updated Cargo.toml and builtins.rs to use the new cpex-builtins facade, then resolved two clippy lint failures. Signed-off-by: habeck <habeck@us.ibm.com> * chore: remove unused dependencies Signed-off-by: habeck <habeck@us.ibm.com> * enh: build and test bindings/python in ci Signed-off-by: habeck <habeck@us.ibm.com> * chore: Added panic isolation and timeout coverage to the Python bindings. Signed-off-by: habeck <habeck@us.ibm.com> * chore: run cargo update with env set: CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse Signed-off-by: habeck <habeck@us.ibm.com> * fix: drop swatinem/rust-cache. rust-cache restores a partial `~/.cargo/registry` index ("full match: false"); with the sparse protocol, , `cargo package --locked` consults that stale local index, finds it can't satisfy the committed lock, and aborts with "cannot update the lock file" (fails ~1.4s in — too fast for a real network fetch) even though Cargo.lock resolves cleanly against a fresh index. Fetching the index fresh each run keeps this dry-run deterministic. Signed-off-by: habeck <habeck@us.ibm.com> * fix: Removing the index forces a clean fetch, against which Cargo.lock resolves cleanly — keeping this dry-run deterministic. Signed-off-by: habeck <habeck@us.ibm.com> * chore: cargo lock update Signed-off-by: habeck <habeck@us.ibm.com> --------- Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com> Signed-off-by: habeck <habeck@us.ibm.com> Co-authored-by: Frederico Araujo <frederico.araujo@ibm.com> Co-authored-by: Teryl Taylor <terylt@ibm.com>
1 parent e21dc1b commit 545c0c8

28 files changed

Lines changed: 3328 additions & 318 deletions

.github/workflows/ci.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,28 @@ jobs:
109109
fetch-depth: 1
110110
- name: Install Rust 1.96.0
111111
uses: dtolnay/rust-toolchain@1.96.0
112-
- uses: Swatinem/rust-cache@v2
112+
# NOTE: intentionally NO Swatinem/rust-cache here, AND we wipe the registry
113+
# index before packaging. The committed Cargo.lock is byte-identical to a
114+
# fresh x86_64 resolution (verified in an amd64 container), so the lock is
115+
# not the problem. The failure comes from stale `~/.cargo/registry` state
116+
# the hosted runner carries: under the sparse protocol `cargo package
117+
# --locked` consults that partial local index, decides it can't satisfy the
118+
# committed lock, and aborts with "cannot update the lock file ... --locked"
119+
# ~1.4s in (too fast for a real network fetch). Removing the index forces a
120+
# clean fetch, against which Cargo.lock resolves cleanly — keeping this
121+
# dry-run deterministic.
113122
# Continuous dry-run of the crates.io release: build + verify a .crate for
114123
# every publishable member without uploading. Catches publishability
115124
# regressions (missing version reqs, packaging-excluded files, broken
116125
# inter-crate deps) on every push/PR, long before a release tag. Mirrors
117126
# `make publish-dry` and the release workflow's dry-run. The two
118127
# `publish = false` FFI crates are excluded (not part of the registry set).
119128
- name: cargo package (no upload)
120-
run: cargo package --workspace --locked --exclude cpex-ffi --exclude cpex-demo-ffi
129+
run: |
130+
# Drop any pre-seeded registry index/cache so cargo fetches fresh and
131+
# --locked resolves against a clean index (see note above).
132+
rm -rf ~/.cargo/registry/index ~/.cargo/registry/cache
133+
cargo package --workspace --locked --exclude cpex-ffi --exclude cpex-demo-ffi
121134
122135
docs:
123136
name: Docs Build

.github/workflows/release.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ jobs:
7070
- uses: actions/checkout@v7
7171
- name: Install Rust 1.96.0
7272
uses: dtolnay/rust-toolchain@1.96.0
73-
- uses: Swatinem/rust-cache@v2
73+
# NOTE: intentionally NO Swatinem/rust-cache here. A restored partial
74+
# `~/.cargo/registry` index makes `cargo package/publish --locked` abort
75+
# with "cannot update the lock file" against the sparse index even when
76+
# Cargo.lock is correct (see the CI `package` job for the full rationale).
77+
# A fresh index each run keeps publish resolution deterministic.
7478
- name: cargo publish (dependency order)
7579
env:
7680
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

0 commit comments

Comments
 (0)