Skip to content

release: v0.9.0 — cellstream, and gpudge on PyPI - #12

Merged
alexdobin merged 1 commit into
mainfrom
release/v0.9.0
Aug 19, 2026
Merged

alexdobin merged 1 commit into
mainfrom
release/v0.9.0

Conversation

@alexdobin

Copy link
Copy Markdown
Collaborator

Two things ship together, and they have to: the streaming dependency became
installable, and so did gpudge.

shardad is now cellstream, on PyPI

The optional de(archive=…) path no longer needs access to a private
repository — both streaming extras resolve from PyPI like any other dependency.

streaming     = ["cellstream>=0.9.0"]
streaming-gpu = ["cellstream[gpu]>=0.9.0"]

MINOR, not PATCH: the 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.

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.

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 gpudge now installs gpudge

Previously 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 for
Windows, aarch64 or Python 3.13, so de(archive=…) is effectively
Linux-x86_64-only. The other three input modes are unaffected.

Publishing

Adds .github/workflows/release.yml — publishes to PyPI via Trusted
Publishing
(OIDC) on a v* tag, so no API token exists. Three things are
checked before the upload:

  1. the sdist's top level matches an allow-list of published entries
  2. the wheel carries nothing outside gpudge/ and its dist-info
  3. the built version equals the tag, and publishing from a non-tag ref is refused

Verification

  • 626 passed / 202 skipped without cellstream installed; 612 / 209 with it
  • benchmarks/ sha256 manifest unchanged across the sync (10 files)
  • built from the v0.9.0 tag; every scrub rule fires as declared and the leak
    sweep reports no unexplained reference

🤖 Generated with Claude Code

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>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 shardad with cellstream across streaming backends, tests, and user-facing documentation, and update streaming extras to cellstream>=0.9.0 / cellstream[gpu]>=0.9.0.
  • Bump project version to 0.9.0 and 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

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines 118 to 124
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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

Comment on lines +70 to 80
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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

@alexdobin
alexdobin merged commit f0cc611 into main Aug 19, 2026
5 checks passed
@alexdobin
alexdobin deleted the release/v0.9.0 branch August 19, 2026 23:40
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