Skip to content

Commit

Permalink
Merge pull request #1216 from dandi/397-asset-list
Browse files Browse the repository at this point in the history
  • Loading branch information
jjnesbitt committed Jul 27, 2022
2 parents 739aa6b + ac03c6a commit 4ab30ec
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
22 changes: 22 additions & 0 deletions dandiapi/api/tests/test_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,28 @@ def test_asset_rest_list(api_client, version, asset, asset_factory):
}


@pytest.mark.django_db
def test_asset_rest_list_include_metadata(api_client, version, asset, asset_factory):
version.assets.add(asset)

# Create an extra asset so that there are multiple assets to filter down
asset_factory()

# Assert false has no effect
r = api_client.get(
f'/api/dandisets/{version.dandiset.identifier}/versions/{version.version}/assets/',
{'metadata': False},
)
assert 'metadata' not in r.json()['results'][0]

# Test positive case
r = api_client.get(
f'/api/dandisets/{version.dandiset.identifier}/versions/{version.version}/assets/',
{'metadata': True},
)
assert r.json()['results'][0]['metadata'] == asset.metadata


@pytest.mark.parametrize(
'path,result_indices',
[
Expand Down
19 changes: 14 additions & 5 deletions dandiapi/api/views/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,14 +533,22 @@ def destroy(self, request, versions__dandiset__pk, versions__version, **kwargs):

return Response(None, status=status.HTTP_204_NO_CONTENT)

@swagger_auto_schema(query_serializer=AssetListSerializer)
@swagger_auto_schema(query_serializer=AssetListSerializer, responses={200: AssetSerializer()})
def list(self, request, *args, **kwargs):
serializer = AssetListSerializer(data=request.query_params)
serializer.is_valid(raise_exception=True)

queryset = self.filter_queryset(self.get_queryset())
glob_pattern: str | None = serializer.validated_data.get('glob')
# Fetch initial queryset
queryset: QuerySet[Asset] = self.filter_queryset(
self.get_queryset().select_related('blob', 'embargoed_blob', 'zarr')
)

# Don't include metadata field if not asked for
include_metadata = serializer.validated_data['metadata']
if not include_metadata:
queryset = queryset.defer('metadata')

glob_pattern: str | None = serializer.validated_data.get('glob')
if glob_pattern is not None:
# Escape special characters in the glob pattern. This is a security precaution taken
# since we are using postgres' regex search. A malicious user who knows this could
Expand All @@ -549,12 +557,13 @@ def list(self, request, *args, **kwargs):
glob_pattern = re.escape(glob_pattern)
queryset = queryset.filter(path__iregex=glob_pattern.replace('\\*', '.*'))

# Paginate and return
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
serializer = self.get_serializer(page, many=True, metadata=include_metadata)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
serializer = self.get_serializer(queryset, many=True, metadata=include_metadata)
return Response(serializer.data)

@swagger_auto_schema(
Expand Down
10 changes: 10 additions & 0 deletions dandiapi/api/views/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,21 @@ class Meta:
'size',
'created',
'modified',
'metadata',
]
read_only_fields = ['created']

blob = EmbargoedSlugRelatedField(slug_field='blob_id', read_only=True)
zarr = serializers.SlugRelatedField(slug_field='zarr_id', read_only=True)

def __init__(self, *args, metadata=True, **kwargs):
# Instantiate the superclass normally
super().__init__(*args, **kwargs)

# Don't include metadata unless specified
if not metadata:
self.fields.pop('metadata')


class AssetDetailSerializer(AssetSerializer):
class Meta(AssetSerializer.Meta):
Expand All @@ -258,3 +267,4 @@ class AssetPathsQueryParameterSerializer(serializers.Serializer):

class AssetListSerializer(serializers.Serializer):
glob = serializers.CharField(required=False)
metadata = serializers.BooleanField(required=False, default=False)

0 comments on commit 4ab30ec

Please sign in to comment.