Skip to content
Snippets Groups Projects

Dataset sets management API endpoints

Merged ml bonhomme requested to merge sets-mgmt-api into master
All threads resolved!
1 file
+ 8
0
Compare changes
  • Side-by-side
  • Inline
+ 107
10
@@ -42,6 +42,7 @@ from arkindex.training.serializers import (
DatasetElementInfoSerializer,
DatasetElementSerializer,
DatasetSerializer,
DatasetSetSerializer,
ElementDatasetSetSerializer,
MetricValueBulkSerializer,
MetricValueCreateSerializer,
@@ -656,11 +657,6 @@ class CorpusDataset(CorpusACLMixin, ListCreateAPIView):
"""
Update a dataset. The dataset must not be in `complete` state.
The sets array can only be updated following those cases:
* Adding or removing sets, nothing specific is done.
* Updating a single set within the array,
all elements linked to the previous set will be moved to the new one.
Requires a **contributor** access to the dataset's corpus.
"""
),
@@ -670,11 +666,6 @@ class CorpusDataset(CorpusACLMixin, ListCreateAPIView):
"""
Partially update a dataset. The dataset must not be in `complete` state.
The sets array can only be updated following those cases:
* Adding or removing sets, nothing specific is done.
* Updating a single set within the array,
all elements linked to the previous set will be moved to the new one.
Requires a **contributor** access to the dataset's corpus.
"""
)
@@ -747,6 +738,112 @@ class DatasetElementCursorPagination(CountCursorPagination):
ordering = ("element_id", "id")
class DatasetSetBase():
permission_classes = (IsVerified, )
serializer_class = DatasetSetSerializer
@cached_property
def dataset(self):
dataset_id = self.kwargs["pk"] if self.request.method == "POST" else self.kwargs["dataset"]
dataset = get_object_or_404(
Dataset.objects.filter(corpus__in=Corpus.objects.readable(self.request.user))
.prefetch_related("sets")
.select_related("corpus"),
pk=dataset_id
)
if self.request.method == "DELETE" and not Corpus.objects.admin(self.request.user).filter(pk=dataset.corpus_id).exists():
raise PermissionDenied(detail="You do not have admin access to this dataset.")
elif self.request.method != "DELETE" and not Corpus.objects.writable(self.request.user).filter(pk=dataset.corpus_id).exists():
raise PermissionDenied(detail="You do not have contributor access to this dataset.")
if dataset.state != DatasetState.Open:
raise ValidationError(detail="You can only add or update sets from a dataset in an open state.")
return dataset
def get_serializer_context(self):
context = super().get_serializer_context()
# Ignore this step when generating the schema with OpenAPI
if not self.kwargs:
return context
context["dataset"] = self.dataset
return context
@extend_schema(tags=["datasets"])
@extend_schema_view(
post=extend_schema(
operation_id="CreateDatasetSet",
description=dedent(
"""
Sets can only be created in **open** datasets.
Requires **contributor** access to the dataset's corpus.
"""
)
),
)
class DatasetSetCreate(DatasetSetBase, CreateAPIView):
permission_classes = (IsVerified, )
@extend_schema(tags=["datasets"])
@extend_schema_view(
delete=extend_schema(
operation_id="DestroyDatasetSet",
description=dedent(
"""
Delete a set from a dataset. Sets can only be deleted from **open** datasets.
Requires **admin** access to the dataset's corpus.
It is not possible to delete a dataset set if that set is selected in a process, or
if it is the only set in the dataset.
"""
)
),
put=extend_schema(
operation_id="UpdateDatasetSet",
description=dedent(
"""
Sets can only be updated if the dataset is in the **open** state.
Requires **contributor** access to the dataset's corpus.
"""
)
),
patch=extend_schema(
operation_id="PartialUpdateDatasetSet",
description=dedent(
"""
Sets can only be updated if the dataset is in the **open** state.
Requires **contributor** access to the dataset's corpus.
"""
)
)
)
class DatasetSets(DatasetSetBase, RetrieveUpdateDestroyAPIView):
lookup_url_kwarg = "set"
queryset = DatasetSet.objects.none()
def get_queryset(self):
return self.dataset.sets.all()
def check_object_permissions(self, request, obj):
super().check_object_permissions(request, obj)
if request.method == "DELETE":
if ProcessDatasetSet.objects.filter(set_id=obj.id).exists():
raise ValidationError("This dataset set is selected in a process and cannot be deleted.")
if self.dataset.sets.count() == 1:
raise ValidationError("This dataset set is the only one in its dataset and cannot be deleted.")
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
# Delete the dataset set's DatasetElement objects
DatasetElement.objects.filter(set_id=instance.id).delete()
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@extend_schema(tags=["datasets"])
@extend_schema_view(
get=extend_schema(
Loading