Skip to content

Commit 3c0f9f8

Browse files
committed
Move reformat function and include validation on provided keys
1 parent f27a65b commit 3c0f9f8

2 files changed

Lines changed: 51 additions & 64 deletions

File tree

app/grandchallenge/algorithms/serializers.py

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@
2222
Job,
2323
annotate_input_output_counts,
2424
)
25-
from grandchallenge.cases.widgets import DICOMUploadWithName
2625
from grandchallenge.components.backends.exceptions import (
2726
CIVNotEditableException,
2827
)
29-
from grandchallenge.components.models import CIVData
3028
from grandchallenge.components.serializers import (
3129
ComponentInterfaceSerializer,
3230
ComponentInterfaceValuePostSerializer,
3331
ComponentInterfaceValueSerializer,
3432
HyperlinkedComponentInterfaceValueSerializer,
33+
reformat_serialized_civ_data,
3534
)
3635
from grandchallenge.core.guardian import filter_by_permission
3736
from grandchallenge.core.templatetags.remove_whitespace import oxford_comma
@@ -241,7 +240,7 @@ def validate(self, data):
241240
data["algorithm_interface"] = (
242241
self.validate_inputs_and_return_matching_interface(inputs=inputs)
243242
)
244-
self.inputs = self.reformat_inputs(serialized_civs=inputs)
243+
self.inputs = reformat_serialized_civ_data(serialized_civ_data=inputs)
245244

246245
if Job.objects.get_jobs_with_same_inputs(
247246
inputs=self.inputs,
@@ -307,39 +306,3 @@ def validate_inputs_and_return_matching_interface(self, *, inputs):
307306
f"following input combinations: "
308307
f"{oxford_comma([f'Interface {n}: {oxford_comma(interface.inputs.all())}' for n, interface in enumerate(self._algorithm.interfaces.all(), start=1)])}"
309308
)
310-
311-
@staticmethod
312-
def reformat_inputs(*, serialized_civs):
313-
"""Takes serialized CIV data and returns list of CIVData objects."""
314-
315-
data = []
316-
for civ in serialized_civs:
317-
interface = civ["interface"]
318-
upload_session = civ.get("upload_session")
319-
user_upload = civ.get("user_upload")
320-
image = civ.get("image")
321-
file = civ.get("file")
322-
value = civ.get("value")
323-
user_uploads = civ.get("user_uploads")
324-
image_name = civ.get("image_name")
325-
dicom_upload_with_name = (
326-
DICOMUploadWithName(name=image_name, user_uploads=user_uploads)
327-
if user_uploads and image_name
328-
else None
329-
)
330-
try:
331-
data.append(
332-
CIVData(
333-
interface_slug=interface.slug,
334-
value=upload_session
335-
or user_upload
336-
or image
337-
or file
338-
or dicom_upload_with_name
339-
or value,
340-
)
341-
)
342-
except ValidationError as e:
343-
raise serializers.ValidationError(e)
344-
345-
return data

app/grandchallenge/components/serializers.py

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22

3+
from django.core.exceptions import ValidationError
34
from rest_framework import serializers
45
from rest_framework.exceptions import ValidationError as DRFValidationError
56
from rest_framework.fields import CharField, SerializerMethodField
@@ -26,6 +27,50 @@
2627
logger = logging.getLogger(__name__)
2728

2829

30+
def reformat_serialized_civ_data(*, serialized_civ_data):
31+
"""Takes serialized CIV data and returns list of CIVData objects."""
32+
33+
possible_keys = [
34+
"image",
35+
"value",
36+
"file",
37+
"user_upload",
38+
"upload_session",
39+
("image_name", "user_uploads"),
40+
]
41+
42+
civ_data_objects = []
43+
for civ in serialized_civ_data:
44+
interface = civ["interface"]
45+
46+
keys = set(civ.keys()) - {"interface"}
47+
48+
if not keys:
49+
raise serializers.ValidationError(
50+
f"You must provide at least one of {possible_keys}"
51+
)
52+
elif keys == {"image_name", "user_uploads"}:
53+
value = DICOMUploadWithName(
54+
name=civ["image_name"],
55+
user_uploads=civ["user_uploads"],
56+
)
57+
elif len(keys) > 1:
58+
raise serializers.ValidationError(
59+
f"You can only provide one of {possible_keys} for each interface."
60+
)
61+
else:
62+
value = civ[list(keys)[0]]
63+
64+
try:
65+
civ_data_objects.append(
66+
CIVData(interface_slug=interface.slug, value=value)
67+
)
68+
except ValidationError as e:
69+
raise serializers.ValidationError(e)
70+
71+
return civ_data_objects
72+
73+
2974
class ComponentInterfaceSerializer(serializers.ModelSerializer):
3075
kind = serializers.CharField(source="get_kind_display", read_only=True)
3176
super_kind = SerializerMethodField()
@@ -276,31 +321,10 @@ def update(self, instance, validated_data):
276321

277322
request = self.context["request"]
278323

279-
civ_data_objects = []
280-
281-
for value in values:
282-
interface = value["interface"]
283-
upload_session = value.get("upload_session")
284-
user_upload = value.get("user_upload")
285-
image = value.get("image")
286-
user_uploads = value.get("user_uploads")
287-
image_name = value.get("image_name")
288-
value = value.get("value")
289-
dicom_upload_with_name = (
290-
DICOMUploadWithName(name=image_name, user_uploads=user_uploads)
291-
if user_uploads and image_name
292-
else None
293-
)
294-
civ_data_objects.append(
295-
CIVData(
296-
interface_slug=interface.slug,
297-
value=upload_session
298-
or user_upload
299-
or image
300-
or dicom_upload_with_name
301-
or value,
302-
)
303-
)
324+
civ_data_objects = reformat_serialized_civ_data(
325+
serialized_civ_data=values
326+
)
327+
304328
try:
305329
instance.validate_civ_data_objects_and_execute_linked_task(
306330
civ_data_objects=civ_data_objects, user=request.user

0 commit comments

Comments
 (0)