Repository navigation
DEVELOPMENT.md: require backward compatible support of new dandi-archive features - #1963
yarikoptic-gitmate wants to merge 2 commits into
Conversation
…ive features dandi-cli works with several independently deployed dandi-archive instances (DANDI and EMBER production and sandbox, LINC, ...), which get new features at different times. Document that support for a new dandi-archive feature must keep working against prior dandi-archive versions, in particular those deployed by the DANDI and EMBER instances, so that dandi-cli can be released before dandi-archive and tested against sandbox instances, without synchronized releases and deployments. Describe how to decide whether a server supports a feature (server version, one-time sensing, or a future "features" list in /api/info/), and ask to give each feature a CODENAME (e.g. BULK_DELETE), test both code paths, and remove the fallback once all known instances support the feature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1963 +/- ##
==========================================
+ Coverage 90.76% 90.82% +0.06%
==========================================
Files 92 92
Lines 14159 14159
==========================================
+ Hits 12851 12860 +9
+ Misses 1308 1299 -9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
yarikoptic
left a comment
There was a problem hiding this comment.
keep it more factual to the moment and with better refs to the code for humans
….0 code Per review: drop the not yet existing "features" list in /api/info/ and the CODENAME convention, describing instead how such conditionals are annotated now (a comment referring to the dandi-archive issue/PR and saying when the fallback can be removed). List the examples one per line, each linked to its code in the 0.81.0 release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
| fail the first time. Simply re-run `git commit` — the second attempt should | ||
| succeed. Investigate further only if it still fails. | ||
|
|
||
| ## Compatibility with dandi-archive instances |
There was a problem hiding this comment.
@waxlamp @jjnesbitt @naglepuff and @dandi/dandi-archive at large: I am initiating these guidelines so far within dandi-cli but hope we could distill a solution which we would implement between both dandi-archive and dandi-cli in a more robust fashion. See this PR description (alert: claude-composed but quite informative! yet to be fully curated but looked sensible, might be worth migrating parts into doc for the next stage if we decide to proceed on "centralized" solution) for more history/pointers etc than this brief addition to DEVELOPMENT.md provides. Also please review this text snippet on either anything to change to reflect our agreement from the recent Zoom session on Tue.
Summary
This adds a "Compatibility with dandi-archive instances" section to
DEVELOPMENT.md, plus a one-line pointer inCLAUDE.md. The section says:server_info["version"]if the releasing dandi-archive version is known (forks may report versions that cannot be compared);This first step is documentation only, describing how this is done today. A follow-up PR will propose a registry of such conditionals (see "Next steps").
Ongoing:
BULK_DELETE(WiP)Use the bulk asset deletion endpoint for all asset deletion #1960 (draft) sends all asset deletion through
POST /dandisets/{id}/versions/{version}/assets/bulk-delete/. That endpoint comes from Add bulk asset deletion endpoint dandi-archive#2920, which is open and not in any release (dandi-archive is at 1.0.19). On a 404 that does not list missing assets, Use the bulk asset deletion endpoint for all asset deletion #1960 falls back to per-assetDELETEand remembers that on theDandiAPIClient.It shows the limits of sensing:
A
featuresentry in/api/info/, or a structured 404 body (missing_asset_ids, which Use the bulk asset deletion endpoint for all asset deletion #1960 already accepts), would remove the ambiguity.Only support bulk asset deletion dandi-archive#2930 proposes removing the single-asset
DELETE. Per this guideline the client keeps its fallback until all instances have bulk delete. The safer order is expand/contract: the server keeps the old endpoint while clients migrate.Historical precedents
Lockstep (2021–2023, before LINC and EMBER). Server changes were followed right away by a client release, and older clients broke:
/info/endpointdandisetin/uploads/initialize/service-scripts#1202 and Update for fix to Zarr upload procedure #1215: new Zarr upload. 0.49.0 broke once themd5encoding changed on the server.get_assets_by_glob()#981 (get_assets_by_glob) was held about 2.5 months until the server shipped its endpoint.Server-driven gates in
/api/info/:cli-minimal-version/cli-bad-versionswere introduced in Add a get_instance() function #186 (redirector, 2020) and moved into/api/info/with Add netlify plugin and redirection dandi-archive#1018.dandi-clidandi-archive#1878, Display the correct CLI and required python version in the GUI dandi-archive#2714).allowed_schema_versions(Allow for client to provide records with newer COMPATIBLE or older (upgradable) version of schema to the server #1732; field added in expose "allowed_schema_versions" to /info (/server-info) dandi-archive#2624 / Expose allowed schema versions at/info/endpoint dandi-archive#2625);migrateand make dandi-cli usemigrate! dandi-schema#343).< 0.10.2#1458 / Revert "Temporarily restrict dandischema requirement to< 0.10.2" #1459, New release to unwind schema pin? #1635 / Unrestrictdandischemaversion #1637. Support multiple versions of target dandischema #1571 (support multiple target schemas) is still open.Sensing and fallbacks in the client:
_get_instance()tries/server-infoand falls back to/api/info/on 404 (Accept URLs as Dandi instance specifiers #1298).x-amz-taggingonly if the presigned URL signs it (Add tagging to zarr upload if embargoed #1685).versionas0.0.post6586+g39387b8./uploads/zarr/initialize/once per server for Use multi-part upload on zarr chunks larger than 5GB #1839.cli-minimal-versionon production and list the new client incli-bad-versionson downstream instances. It was not adopted, because it makes other instances react to every client change. This guideline takes that position.upload_typefrom the server's response, so an older server simply does not return the field.nextfollowing (dandi/dandiapi.py, Fetch paginated results concurrently #1021).DANDI_PAGINATION_DISABLE_FALLBACKis an existing env var precedent for controlling a fallback.Coordinated deployment instead of a fallback:
x-amz-aclheader in zarr upload #1710 (stop sendingx-amz-acl): the merge was held about 3 weeks until EMBER confirmed its forks were synced.staging=>sandbox#1668, Bring back dandi-staging to provide more graceful transition for 3rd party libraries #1694, Add support for all known instances in short URL format, removed dandi-staging and renamed EMBER* ones into EMBER-DANDI* #1750).CI gap:
dandiarchive/dandiarchive-apiimage. A client PR that depends on an unmerged server PR therefore stays red (Use multi-part upload on zarr chunks larger than 5GB #1839, Use the bulk asset deletion endpoint for all asset deletion #1960), and older-server code paths are covered only by mocks.Existing conditionals: removable now?
Links are to the 0.81.0 release. The verdicts are based on the source of the branches the instances deploy: upstream master,
aplbrain/dandi-archiveprodfor EMBER, andlincbrain/linc-archivereleasefor LINC. I could not query/api/info/on the live servers from the environment where this was prepared, so please check before acting on it._get_instance(),/server-info→/api/info/(dandi/utils.py)allowed_schema_versionsfallback incheck_schema_version()(dandi/dandiapi.py)x-amz-taggingcheck, commented out (dandi/files/zarr.py)mkzarr(dandi/files/zarr.py)dandi-stagingcheck inget_instance()(dandi/utils.py)known_instances[dandi_id]raisesKeyErrorfirstdandi/download.py)To verify: if LINC still serves schema
0.6.9,check_schema_version()raises ondandi uploadto LINC for every dandischema that dandi-cli allows.0.6.9is not inALLOWED_TARGET_SCHEMAS, and it is in a different MAJOR.MINOR band than client schemas0.7.0and0.8.0.How other projects handle this
AnnexRepo._check_version_kludges()computes named, version-dependent flags once and caches them. It has a "maybe" state for development snapshots. Flags are removed in batches when the minimum version is raised (fa58b48). A cron-only CI job tests the minimum git-annex version./versionsreturns specversionsplusunstable_featuresflags. Flags are dropped once a feature is in the spec, and an absent flag means unsupported. matrix-js-sdk'sfeatureSupportResolveris a registry mapping each feature to its unstable flag(s) and the stable spec version, which is close to the registry proposed under "Next steps".bulkUpload()readsdav.bulkuploadand can be forced on or off withNEXTCLOUD_BULK_UPLOAD=0/1. This is the closest analogue toBULK_DELETEplus a kill switch.DOCKER_API_VERSIONpins it and is meant only for when you must, or for debugging.protocol.versionknob mattered in practice: v2 was made the default in 2.26, demoted in 2.27 for rough edges, and restored in 2.29.fieldValidation. Both feature gates and the skew policy define when old paths can go./api/versionand runs a weekly CI matrix over about 10 Galaxy releases.featureslist should be curated and pruned.deprecated(gone_in=...)turns into an error once pip reaches that version;deprecationpackage hasfail_if_not_removed;RemovedInDjangoXXWarningcomments;Next steps (follow-up PRs, not here)
base_version(the version the feature is developed on, so older servers need no sensing), optionalreleased_version, and a sensing function. Results are resolved once per server, keyed by API URL rather than perDandiAPIClient.DANDI_DEVEL_DISABLE_SERVER_FEATURES=BULK_DELETE,...to force the fallback when a feature turns out to be buggy.known_instancesthat reports which features each instance supports. It fails when a fallback is supported everywhere and can be removed. Keep in mind that scheduled workflows are disabled after 60 days of repository inactivity.featuresentry in/api/info/generated from code. Keep old endpoints while clients migrate (Only support bulk asset deletion dandi-archive#2930).🤖 Generated with Claude Code
https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU