Repository navigation
Add a registry of dandi-archive features used only where supported - #1970
Open
yarikoptic-gitmate wants to merge 4 commits into
Open
yarikoptic-gitmate wants to merge 4 commits into
yarikoptic-gitmate wants to merge 4 commits into
Conversation
dandi-cli talks to several independently deployed dandi-archive instances, which gain new features at different times. Register such features in dandi/server_features.py as ServerFeature entries (CODENAME, description, refs, base_version, released_version, and a side-effect free sense function), and ask DandiAPIClient.server_features whether the server supports one. Support is decided once per client: - not, if the CODENAME is listed in DANDI_DEVEL_DISABLE_SERVER_FEATURES; - by the server version, if it is a dandi-archive release (development versions and versions of forks cannot be compared with releases); - otherwise by sensing; code which finds out by using a feature can record() it. routes_endpoint() probes for an API endpoint by comparing OPTIONS responses for it and for a path no server routes. Register ALLOWED_SCHEMA_VERSIONS, now used by check_schema_version(), and BULK_DELETE (dandi-archive#2920) for dandi-cli#1960 to use. A weekly "Survey server features" workflow runs test_survey (marked server_features_survey, skipped without --server-features-survey), which fails once all known instances support a registered feature, i.e., once its fallback can be removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
…dandiapi dandi.dandiapi imports dandi.server_features, so the latter importing DandiAPIClient back (even only under TYPE_CHECKING) made CodeQL report a module-level cyclic import. Declare instead, as the APIClient Protocol, the few attributes of a DandiAPIClient which the module needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
…her than '...' CodeQL reports a bare '...' body as a statement which has no effect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1970 +/- ##
==========================================
+ Coverage 90.82% 90.94% +0.11%
==========================================
Files 92 94 +2
Lines 14190 14484 +294
==========================================
+ Hits 12888 13172 +284
- Misses 1302 1312 +10
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:
|
The survey test runs only with --server-features-survey (weekly), so its logic, now in _survey(), is otherwise never run. Test it with mocked servers: support everywhere, an unreachable instance, a failing sense function, and missing support. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU
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.
This is the follow-up planned in #1963. It adds a registry of the dandi-archive features which dandi-cli uses only where the server supports them, and adds the weekly survey and the disabling env var that it described.
What it adds
dandi/server_features.pyServerFeaturerecords, for each feature:base_version: the dandi-archive release the feature was developed on top of;released_version: the release that added it, once known;sense(client): a function that checks for the feature without changing anything on the server.SERVER_FEATURES.APIClientProtocol(api_url,session,server_info,get_url()) rather than importingdandi.dandiapi, which imports it; CodeQL flags the cycle even underTYPE_CHECKING.DandiAPIClient.server_featuresdecides, once per client:.supports("CODENAME") -> bool..resolve()also says how the answer was reached:disabled,version,sensedorrecorded..record("CODENAME", supported)lets code that found out by using the feature update the answer.How support is decided
Disabled, if the CODENAME is listed in
DANDI_DEVEL_DISABLE_SERVER_FEATURES, e.g.BULK_DELETE,ALLOWED_SCHEMA_VERSIONS. Unknown names are warned about and ignored.By version, only if
/api/info/'sversionis a clean dandi-archive release:version >= released_version: supported;version < released_version: not supported;version <= base_version: not supported.Development versions (sandbox instances) and versions with a post or local part (forks) do not count as releases, because they can't be compared with dandi-archive's. LINC today reports
0.0.post6586+g39387b8.Otherwise by
sense().routes_endpoint(client, path)is a probe that does not modify anything. It sendsOPTIONStopathand to a sibling path that no server has, then compares status and content type.Registered features
ALLOWED_SCHEMA_VERSIONS(released in 0.19.0; expose "allowed_schema_versions" to /info (/server-info) dandi-archive#2624, Expose allowed schema versions at/info/endpoint dandi-archive#2625, Allow for client to provide records with newer COMPATIBLE or older (upgradable) version of schema to the server #1732).check_schema_version()now uses the server'sallowed_schema_versionsthrough the registry, and falls back to dandischema'sALLOWED_INPUT_SCHEMASas before./info/endpoint dandi-archive#2625 settled the name.BULK_DELETE(Add bulk asset deletion endpoint dandi-archive#2920, which is unmerged and based on 1.0.19).routes_endpoint()on/dandisets/000000/versions/draft/assets/bulk-delete/.Survey of known instances.
test_survey[CODENAME]checks every instance inknown_instancesexcept the local Docker one.server_features_surveyand skipped unless--server-features-surveyis given..github/workflows/server-features.yml: weekly (Mondays 05:23 UTC), on demand, and on PRs that touch the registry. Its run on this PR gave the table below.Docs
dandi.server_featuresis added.Checked against live servers
The survey job on this PR produced:
From the environment this was prepared in, only
lincbrain.orgwas reachable; DANDI and EMBER hosts were blocked by its network policy.no (sensed). LINC lacksallowed_schema_versionsand the bulk-delete route.routes_endpoint()returnsTruefor routes LINC has (…/assets/paths/,/zarr/);Falsefor…/assets/bulk-delete/and for a made-up path.test_local_archivechecks the probe against the Docker archive (dandiarchive/dandiarchive-api) in CI'sdandi-apijobs. Docker Hub rate-limited the image pull here.Notes
client.server_features.supports("BULK_DELETE")instead of inferring support from a 404. That 404 can't tell an old server from a missing version.DandiAPIClient, likeserver_info. The DEVELOPMENT.md: require backward compatible support of new dandi-archive features #1963 plan suggested keying them by API URL across clients. Per client is simpler to reason about and to test, and the CLI uses one client per command; I can switch if preferred.schema_version0.6.9. That is older than the 0.8.0 of the current dandischema (0.14.0) and is not in itsALLOWED_TARGET_SCHEMAS(0.6.10, 0.7.0, 0.8.0), socheck_schema_version()'s "server is older" branch raisesSchemaVersionError. That branch does not involveALLOWED_SCHEMA_VERSIONS, and this PR does not change it. It may deserve its own issue.x-amz-tagginghandling in Zarr upload, which senses from each presigned URL rather than once per server;_get_instance()'s/server-info→/api/info/fallback, which happens before a client has any server info.Testing
test_server_features.py(new,ai_generated):record(), unknown CODENAMEs, the probe's responses,check_schema_version()with and without the feature, registry hygiene, and the survey's report;test_local_archive, against the Docker archive;test_surveycases.--server-features-survey(LINC rowsno (sensed), others unreachable);-W;-m "not obolibrary"): 916 passed, 26 failed. All 26 failures are tests that needdandiarchive.org, which that environment's network policy blocks (proxy errors and timeouts); CI runs them with network access.🤖 Generated with Claude Code
https://claude.ai/code/session_014sJtxzEPbSxycxetp4DquU