diff --git a/dandiapi/api/tests/test_asset.py b/dandiapi/api/tests/test_asset.py index 061e81178..60f35c1bc 100644 --- a/dandiapi/api/tests/test_asset.py +++ b/dandiapi/api/tests/test_asset.py @@ -318,6 +318,35 @@ def test_asset_rest_list_include_metadata(api_client, version, asset, asset_fact assert r.json()['results'][0]['metadata'] == asset.full_metadata +@pytest.mark.django_db +def test_asset_rest_list_zarr_only( + api_client, draft_version, draft_asset_factory, zarr_archive_factory +): + # Create two blob assets and one zarr asset + zarr_asset = draft_asset_factory( + blob=None, zarr=zarr_archive_factory(dandiset=draft_version.dandiset) + ) + draft_version.assets.add(zarr_asset) + draft_version.assets.add(draft_asset_factory()) + draft_version.assets.add(draft_asset_factory()) + + # Assert missing and false both return all assets + ident = draft_version.dandiset.identifier + ver = draft_version.version + assert api_client.get(f'/api/dandisets/{ident}/versions/{ver}/assets/').json()['count'] == 3 + assert ( + api_client.get(f'/api/dandisets/{ident}/versions/{ver}/assets/', {'zarr': False}).json()[ + 'count' + ] + == 3 + ) + + # Test positive case + r = api_client.get(f'/api/dandisets/{ident}/versions/{ver}/assets/', {'zarr': True}).json() + assert r['count'] == 1 + assert r['results'][0]['asset_id'] == str(zarr_asset.asset_id) + + @pytest.mark.parametrize( ('path', 'result_indices'), [ diff --git a/dandiapi/api/views/asset.py b/dandiapi/api/views/asset.py index fbd94a842..7c02de5c0 100644 --- a/dandiapi/api/views/asset.py +++ b/dandiapi/api/views/asset.py @@ -431,6 +431,11 @@ def list(self, request, *args, **kwargs): # Apply filtering from included filter class first asset_queryset = self.filter_queryset(version.assets.all()) + # Filter query to only zarr assets, if requested + zarr_only = serializer.validated_data['zarr'] + if zarr_only: + asset_queryset = asset_queryset.filter(zarr__isnull=False) + # Must do glob pattern matching before pagination glob_pattern: str | None = serializer.validated_data.get('glob') if glob_pattern is not None: diff --git a/dandiapi/api/views/serializers.py b/dandiapi/api/views/serializers.py index e6c31be1a..9725aedcd 100644 --- a/dandiapi/api/views/serializers.py +++ b/dandiapi/api/views/serializers.py @@ -373,6 +373,7 @@ class Meta(AssetSerializer.Meta): class AssetListSerializer(serializers.Serializer): glob = serializers.CharField(required=False) metadata = serializers.BooleanField(required=False, default=False) + zarr = serializers.BooleanField(required=False, default=False) class AssetPathsQueryParameterSerializer(serializers.Serializer): diff --git a/web/src/views/DandisetLandingView/DandisetPublish.vue b/web/src/views/DandisetLandingView/DandisetPublish.vue index 5a1572af4..ffdb17b3c 100644 --- a/web/src/views/DandisetLandingView/DandisetPublish.vue +++ b/web/src/views/DandisetLandingView/DandisetPublish.vue @@ -305,11 +305,15 @@ const alreadyBeingPublishedError = ref(false); const containsZarr = ref(false); watchEffect(async () => { if (currentDandiset.value) { - const zarr = await dandiRest.zarr({ - dandiset: currentDandiset.value.dandiset.identifier, - }); - - containsZarr.value = zarr.count > 0; + const { identifier } = currentDandiset.value.dandiset; + const { version } = currentDandiset.value; + const res = await dandiRest.assets( + identifier, + version, + { params: { zarr: true, page_size: 1 } }, + ); + + containsZarr.value = res !== null && res.count > 0; } });