Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • arkindex/backend
1 result
Show changes
Commits on Source (2)
1.6.0-beta2
1.6.0-beta3
......@@ -108,6 +108,8 @@ from arkindex.training.api import (
DatasetClone,
DatasetElementDestroy,
DatasetElements,
DatasetSetCreate,
DatasetSets,
DatasetUpdate,
ElementDatasetSets,
MetricValueBulkCreate,
......@@ -189,6 +191,8 @@ api = [
path("datasets/<uuid:pk>/clone/", DatasetClone.as_view(), name="dataset-clone"),
path("datasets/<uuid:pk>/elements/", DatasetElements.as_view(), name="dataset-elements"),
path("datasets/<uuid:dataset>/elements/<uuid:element>/", DatasetElementDestroy.as_view(), name="dataset-element"),
path("datasets/<uuid:pk>/sets/", DatasetSetCreate.as_view(), name="dataset-sets"),
path("datasets/<uuid:dataset>/sets/<uuid:set>/", DatasetSets.as_view(), name="dataset-set"),
# Moderation
path("classifications/", ClassificationCreate.as_view(), name="classification-create"),
......
......@@ -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(
......
......@@ -482,9 +482,20 @@ class MetricValueBulkSerializer(serializers.Serializer):
class DatasetSetSerializer(serializers.ModelSerializer):
dataset = serializers.HiddenField(
default=_dataset_from_context,
write_only=True,
)
class Meta:
model = DatasetSet
fields = ("id", "name",)
fields = ("id", "name", "dataset", )
read_only_fields = ("id", )
def validate_name(self, name):
if any(ds.name == name for ds in self.context["dataset"].sets.all()):
raise ValidationError("A set with this name already exists in this dataset.")
return name
class DatasetSerializer(serializers.ModelSerializer):
......
This diff is collapsed.