Adopt deepcell-auth for model/data downloads - #47
Merged
xuefei-wang merged 4 commits intoJul 30, 2026
Conversation
This was referenced Jul 30, 2026
The shared client's bundled ``asset_manifest.yaml`` becomes the single source of truth for deepcell-types asset keys and integrity hashes, the way vanvalenlab/torch-mesmer already consumes it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sy8eiMVmmQHXRAccKwzAyz
The next commit deletes this repo's download transport in favour of deepcell-auth, but ``extract_archive`` stays: deepcell-auth's extractor calls ``extractall`` without vetting members, so delegating it would drop the zip-slip / tar-traversal / symlink rejection and the member-count and size bounds. Move it (and the archive limits it reads) out of ``_auth`` ahead of that deletion, and split its tests out of ``tests/test_auth.py``. Pure move: no behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sy8eiMVmmQHXRAccKwzAyz
deepcell-auth's bundled asset_manifest.yaml is now the single source of truth for deepcell-types asset keys and integrity hashes, so this repo drops its duplicate registry and its auth transport (`utils/_auth.py`). The public API is unchanged: `download_model`, `download_baseline_checkpoint`, `download_training_data`, `list_model_versions` and `list_baseline_names` keep their signatures, `Path`/`list[Path]` return types, the `ValueError` on an unknown identifier, and the pointer to Nimbus' upstream weights. `predict.py` is untouched. Two details worth flagging: * The SSL checkpoint's manifest key is `2026-06-23-ptft`, not `2026-06-23` (vanvalenlab/deepcell-auth#8 renamed it); the mirrored list follows. * The 2025 CLIP checkpoints are in the manifest for reproducibility but cannot be loaded by this code, so `download_model` rejects them instead of handing back a checkpoint that fails at `load_state_dict`. `tests/test_download_delegation.py` reads the packaged manifest offline and fails if the mirrored versions/baselines drift from it, which is what would otherwise surface as a `KeyError` from inside `deepcell_auth` at download time. The `_auth.py` unit tests go with the module they covered. Note: deepcell-auth's `fetch_data` is simpler than the transport removed here -- it hashes only for cache lookup (no post-download integrity check), writes straight to the final path rather than temp-then-replace, hashes whole-file rather than chunked, and sets no request timeouts. Adopting it is the deliberate consolidation trade-off; the safe `extract_archive` was kept locally rather than delegated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sy8eiMVmmQHXRAccKwzAyz
xuefei-wang
force-pushed
the
refactor/adopt-deepcell-auth
branch
from
July 30, 2026 15:58
d05a07f to
4fc03aa
Compare
xuefei-wang
marked this pull request as ready for review
July 30, 2026 15:59
This was referenced Jul 30, 2026
Merged
vanvalenlab/deepcell-auth#12 ships all three baselines in a single `.tar.gz` with a subdirectory per baseline, under one version-scoped top-level directory (the cellsam layout). The motivation is atomicity -- `maps` and `xgboost` each ship a companion file required at inference (`_stats.npz`, `.remap.json`), and as separate assets those could be fetched into inconsistent states -- plus one asset to upload, version and hash instead of five. Bundling also compresses the xgboost booster (1.1 GB of JSON) by ~2.9x, so the baselines go from 1.5 GB to 646 MB. `download_baseline_checkpoint` now unpacks the bundle with this package's path-traversal-safe `extract_archive` -- deliberately not deepcell-auth's, which calls `extractall` unvetted -- and returns only the requested baseline's subdirectory, sorted. The public contract is unchanged: still `list[Path]`, and sorting reproduces the order the loose assets were declared in (weights before companion). The cost of one shared archive is that requesting any single baseline downloads all three. `fetch_data` caches by filename, so the first request pays the transfer and the other two are then served from cache; verified end-to-end against the real bundle (three baselines, one transfer). Extraction is skipped when the bundle directory already exists, matching cellsam. `fetch_data` still re-checks the archive's pinned hash on every call, so a corrupt download is caught; a hand-edited extraction directory is not. A bundle missing the requested baseline's subdirectory, or holding a plain file in its place, raises a readable error instead of NotADirectoryError. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sy8eiMVmmQHXRAccKwzAyz
xuefei-wang
force-pushed
the
refactor/adopt-deepcell-auth
branch
from
July 30, 2026 17:44
d072beb to
5e0981b
Compare
xuefei-wang
added a commit
that referenced
this pull request
Aug 11, 2026
Rebuilt from master @ 59d74a9 (docs(tutorial): run the whole pipeline at build, fail loudly on an empty mask, #55). The previous build predated both #47 (deepcell-auth migration) and #55. The tutorial was re-executed end to end -- remote zarr read, cellSAM segmentation, deepcell-types predict, and both napari screenshots -- so the published page reflects a real run rather than cached output. The /superpowers/ pages and their _sources counterparts are carried over unchanged; they are not Sphinx output of this build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BHtuHjUExCH8bvCowX7GJ3
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.
Replaces this repo's inlined asset-download layer with the shared
deepcell-authclient, asvanvalenlab/torch-mesmeralready does.deepcell-auth's bundled manifest becomes the single source of truth for asset keys and hashes, so this repo drops its duplicate registry and auth transport.All the upstream pieces have landed: vanvalenlab/deepcell-auth#8 (the deepcell-types + baseline manifest entries), #10 (the download helpers now return the downloaded path), and #12 (all three baselines served in a single
.tar.gz). The dependency is pinned tovanvalenlab/deepcell-auth@main.Changes
deepcell_authgit dependency; deleteutils/_auth.pyand the local model/baseline registries. Downloads delegate todeepcell_auth.download_deepcell_types_{model,baseline,data}.download_model,download_baseline_checkpoint,download_training_data,list_model_versions,list_baseline_names) is unchanged — thin adapters preserve the signatures, thePath/list[Path]return types, theValueErroron an unknown identifier, and the Nimbus upstream pointer.predict.pyis untouched.extract_archivelocal, moved toutils/_archive.py, sincedeepcell-auth's extractor callsextractallwithout vetting members. This is the current hardened version (zip-slip / tar-traversal / symlink rejection plus the member-count and per-member/total size bounds), moved verbatim..tar.gzwith a subdirectory per baseline (cellsam's layout: a single version-scoped top-level directory), sodownload_baseline_checkpointnow extracts and returns just the requested baseline's subdirectory. The public contract is unchanged — stilllist[Path], and sorting reproduces the order the loose assets were declared in (weights before companion).Two behavioral details
2026-06-23-ptft, not2026-06-23— deepcell-auth#8 renamed it. The old key would have raisedKeyErrorfrom insidedeepcell_authat download time.download_modelrejects them rather than handing back a checkpoint that fails atload_state_dict.Trade-off worth recording
deepcell_auth.fetch_datais simpler than the transport this PR deletes. Relative toutils/_auth.pyon master it: hashes only for cache lookup (no post-download integrity check), writes straight to the final path instead of temp-then-os.replace, hashes whole-file instead of chunked, sets no request timeouts, and has noContent-Lengthcap. Consolidating on the shared client was chosen deliberately over keeping a second transport in this repo; porting the hardening upstream intodeepcell-authwould restore it fortorch-mesmerandcellsamtoo, and is the natural follow-up.Verification
uv run pytest— 470 passed, 1 skipped (with the[train]extra, matching CI).ruff checkclean.Drove the real 646 MB bundle through
download_baseline_checkpointwith only the network hop stubbed: every extracted file md5-matches the original loose checkpoint, each request returns only its own baseline's files, and all three baselines cost one transfer.Offline wiring check with
fetch_datastubbed: every asset key and hash the adapters request matches the staged upload set byte-for-byte —download_model()models/deepcell-types_2026-06-15_resmlp.ptb819a7e0…download_model("2026-06-23-ptft")models/deepcell-types_2026-06-23_resmlp_ptft.pt402e94c1…download_baseline_checkpoint("cellsighter" | "maps" | "xgboost")models/deepcell-types_baselines_2026-06-30.tar.gz910840c7…download_training_data()data/deepcell-types/public_data_v1.1.zipWhy the baselines are bundled and the models are not
mapsandxgboosteach ship a companion file required at inference (_stats.npz,.remap.json); as separate assets those can be fetched into inconsistent states. One archive also means a single asset to upload, version and hash instead of five, and it cuts the baselines from 1.5 GB to 646 MB — almost all of that the xgboost booster, 1.1 GB of JSON that gzips 2.94×.The cost is that requesting any single baseline downloads all three.
fetch_datacaches by filename, so the first request pays the transfer and the other two are then free; a user who only ever wantsmaps(7 MB of checkpoint) still pulls 646 MB once.The model checkpoints stay bare
.ptfiles: one file per version, and already-compressed tensor data (measured 1.08×), so a tarball would buy nothing. That is also the shapetorch-mesmeruses.Note on the diff
The branch was rebuilt directly on
master(c677b28). Its previous head was based on the fork's lineage, whose merge-base with this repo's squash-mergedv0.1.0history is the pre-release616d4b5— so GitHub was showing the whole monorepo merge as the diff and reported 171 conflicts. The rebuilt branch is the same change reapplied on the correct base: 8 files, +341/−799.🤖 Generated with Claude Code
https://claude.ai/code/session_01Sy8eiMVmmQHXRAccKwzAyz