Repository navigation
release: v0.9.0 — cellstream, and gpudge on PyPI - #12
Conversation
The streaming dependency became installable, and so did gpudge. `shardad` has been renamed **cellstream** and published to PyPI at 0.9.0, so the optional `de(archive=...)` path no longer needs access to a private repository: both streaming extras now resolve from PyPI like any other dependency. gpudge itself is published too, so `pip install gpudge` installs this library rather than the 0.0.1 reservation stub that had been holding the name. MINOR, not PATCH: the streaming extras name a different package. No gpudge API moved -- `de(archive=)`, `layout='shard'`/`'cell'`, `stream_n_workers` and `stream_prefetch` are named for archive layouts, not for the package. Two caveats retire with the old pin. cellstream's Rust extension is no longer optional, so a source build without a toolchain fails loudly instead of silently falling back to the slow pure-Python cell decoder. And the categorical ordering defect that scoped cross-layout byte-identity to default-ordered archives was fixed upstream below this floor. The extras pin `cellstream>=0.9.0`, deliberately NOT `cellstream[cell]`: that extra is `pyfastpfor`, which publishes an sdist only, and cellstream's Rust decoder never calls it -- requiring it would make every install compile C++ for nothing. Platform: cellstream ships Linux x86_64 wheels only (manylinux_2_28, cp311/cp312, with an SSE4.1 floor). There is no wheel for Windows, aarch64 or Python 3.13, so `de(archive=...)` is effectively Linux-x86_64-only. The other three input modes are unaffected. Also adds `.github/workflows/release.yml`, which publishes to PyPI via Trusted Publishing on a `v*` tag. It checks three things before uploading: the sdist's top level against an allow-list, that the wheel carries only the package, and that the built version matches the tag. Suite: 626 passed / 202 skipped without cellstream installed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR prepares the v0.9.0 release by migrating gpudge’s optional streaming dependency from the private shardad package to the publicly published cellstream package on PyPI, and by adding a GitHub Actions workflow to publish gpudge to PyPI via Trusted Publishing.
Changes:
- Replace
shardadwithcellstreamacross streaming backends, tests, and user-facing documentation, and update streaming extras tocellstream>=0.9.0/cellstream[gpu]>=0.9.0. - Bump project version to
0.9.0and update install guidance (PyPI-first, with optional git pin for unreleased commits). - Add a tag-gated PyPI release workflow with sdist/wheel content allow/deny checks and tag/version matching.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tests/test_shard_stream.py |
Updates shard-layout streaming tests to import-skip cellstream and use cellstream APIs. |
tests/test_inmem_external_ref_gpu.py |
Switches GPU external-reference test setup from shardad to cellstream. |
tests/test_cell_stream.py |
Switches cell-layout streaming tests from shardad to cellstream and updates related commentary. |
tests/test_api.py |
Updates docstrings/comments around streaming guards to reference cellstream. |
src/gpudge/_stream_backend.py |
Renames importer helper and dispatch path to load cellstream and its schema error type. |
src/gpudge/_shard_stream.py |
Switches x_cupy capability detection to cellstream.read.GroupShard and updates messages/comments. |
src/gpudge/_refpool.py |
Updates streaming-path commentary to reference cellstream x_cupy. |
src/gpudge/_csr_dense.py |
Updates commentary about dtype behavior to reference cellstream gather behavior. |
src/gpudge/_cell_stream.py |
Updates cell backend’s private API rationale/comments and error text for cellstream. |
src/gpudge/__init__.py |
Updates public API docs for de(archive=...) to reference cellstream and new extra floor. |
SECURITY.md |
Updates threat-model wording from shardad archives to cellstream archives. |
README.md |
Updates install/extras docs to reflect PyPI availability and cellstream streaming extras/platform constraints. |
pyproject.toml |
Bumps version to 0.9.0, updates streaming extras to cellstream, removes old private source pin commentary. |
environment.yml |
Updates conda env guidance to pin gpudge==0.9.0 from PyPI and references cellstream for streaming. |
docs/tutorial.md |
Updates tutorial mention of streaming archives to cellstream. |
docs/THIRD_PARTY_LICENSES.md |
Adds a note that the shardad row is stale post-rename and should be regenerated. |
CONTRIBUTING.md |
Updates uv install guidance now that the private git-SSH streaming dependency is gone. |
CITATION.cff |
Updates abstract to reference “streamed cellstream archive”. |
CHANGELOG.md |
Adds 0.9.0 release notes and updates compare links/tag notes. |
.github/workflows/release.yml |
Adds Trusted Publishing workflow with sdist/wheel content gates and tag/version enforcement. |
.github/workflows/ci.yml |
Updates CI commentary to reflect cellstream gating and rationale for not installing streaming in core CI job. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # --- tau_star over the streaming paths ----------------------------------- | ||
| # CI is CPU-only and does not even COLLECT this module (it needs shardad), so | ||
| # CI is CPU-only and does not even COLLECT this module (it needs cellstream), so | ||
| # these run only on a GPU host with shardad installed. That is precisely why they |
There was a problem hiding this comment.
Code Review
This pull request transitions the streaming dependency from the private shardad repository to the newly published cellstream package on PyPI, bumping the project version to 0.9.0 and updating all references, imports, and documentation. The review feedback recommends updating the ImportError message in _stream_backend.py to suggest the standard pip install "gpudge[streaming]" command, and migrating from the private CellStore._load_groups() call to the public CellStore.group_spans() and CellStore.reference_row_count() APIs in _cell_stream.py to enhance maintainability.
| raise ImportError( | ||
| "de(archive=...) requires the optional 'streaming' extra, which " | ||
| "installs shardad. shardad is hosted privately at " | ||
| "ArcInstitute/shardad and is not published on PyPI, so the extra " | ||
| "only resolves with access to that repository -- see the Install " | ||
| "section of the README for the exact pin." | ||
| "installs cellstream (>=0.9.0, the former shardad) from PyPI. " | ||
| "Reinstall gpudge with the extra -- e.g. `pip install '.[streaming]'` " | ||
| "from a checkout, or add `streaming` to the pin in the README's " | ||
| "Install section." | ||
| ) from e |
There was a problem hiding this comment.
Since gpudge is now published on PyPI (as of v0.9.0), the error message should recommend the standard PyPI installation command pip install "gpudge[streaming]" instead of referencing a local checkout or the old README pin instructions.
raise ImportError(
"de(archive=...) requires the optional 'streaming' extra, which "
"installs cellstream (>=0.9.0, the former shardad) from PyPI. "
"Reinstall gpudge with the extra -- e.g. pip install \"gpudge[streaming]\"."
) from e| Reads cellstream's **private** ``CellStore._load_groups()``. That upstream | ||
| ask has since been answered: cellstream 0.8.0 added public | ||
| ``CellStore.group_spans()`` (a list of ``GroupSpan(label, start, stop)``) and | ||
| ``CellStore.reference_row_count()``, which give exactly this table without | ||
| loading obs. Migrating to them is tracked separately and is a cleanup, not a | ||
| fix -- the private call still exists in the pinned 0.9.0 and the suites pass | ||
| against it. Until then the reasoning below is history, not a live claim: run-detection | ||
| over ``store.obs[group_by]`` would load the whole obs DataFrame -- | ||
| 36 columns x 1.27 M rows on a production archive -- to recover a table the | ||
| archive already stores, which is why the private reach-in was taken; ``test_cell_group_ranges_private_api_gone`` makes | ||
| its removal fail loudly rather than silently. |
There was a problem hiding this comment.
Since gpudge now pins cellstream>=0.9.0 (which guarantees the availability of the public CellStore.group_spans() and CellStore.reference_row_count() APIs introduced in cellstream 0.8.0), we should migrate away from the private CellStore._load_groups() call. Relying on private internals (prefixed with _) poses a significant maintainability risk as they can be changed or removed in patch releases of the dependency without semver guarantees.
Two things ship together, and they have to: the streaming dependency became
installable, and so did gpudge.
shardadis nowcellstream, on PyPIThe optional
de(archive=…)path no longer needs access to a privaterepository — both streaming extras resolve from PyPI like any other dependency.
MINOR, not PATCH: the extras name a different package. No gpudge API
moved —
de(archive=),layout='shard'/'cell',stream_n_workersandstream_prefetchare named for archive layouts, not for the package.Deliberately not
cellstream[cell]: that extra ispyfastpfor, whichpublishes an sdist only, and cellstream's Rust decoder never calls it. Requiring
it would make every install compile C++ for nothing.
Two caveats retire with the old pin — the Rust extension is no longer optional
(a toolchain-less source build now fails loudly instead of silently falling back
to the slow pure-Python decoder), and the categorical-ordering defect that scoped
cross-layout byte-identity to default-ordered archives was fixed upstream below
this floor.
pip install gpudgenow installs gpudgePreviously the name held only a 0.0.1 reservation stub. The README leads with
PyPI; the git pin survives as the way to install an unreleased commit.
Platform
cellstream ships Linux x86_64 wheels only (
manylinux_2_28, cp311/cp312,with an SSE4.1 floor — check
grep sse4_1 /proc/cpuinfo). No wheel forWindows, aarch64 or Python 3.13, so
de(archive=…)is effectivelyLinux-x86_64-only. The other three input modes are unaffected.
Publishing
Adds
.github/workflows/release.yml— publishes to PyPI via TrustedPublishing (OIDC) on a
v*tag, so no API token exists. Three things arechecked before the upload:
gpudge/and its dist-infoVerification
benchmarks/sha256 manifest unchanged across the sync (10 files)v0.9.0tag; every scrub rule fires as declared and the leaksweep reports no unexplained reference
🤖 Generated with Claude Code