Skip to content

Commit c61e60f

Browse files
author
Ubuntu
committed
Tests passing
1 parent 6ac90ac commit c61e60f

File tree

4 files changed

+60
-18
lines changed

4 files changed

+60
-18
lines changed

nucleus/annotation.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,25 @@ def to_payload(self) -> dict:
582582

583583
return payload
584584

585-
def has_files(self) -> bool:
585+
def has_local_files(self) -> bool:
586586
if is_local_path(self.mask_url):
587587
if not os.path.isfile(self.mask_url):
588588
raise Exception(f"Mask file {self.mask_url} does not exist.")
589589
return True
590590
return False
591591

592+
def __eq__(self, other):
593+
if not isinstance(other, SegmentationAnnotation):
594+
return False
595+
self.annotations = sorted(self.annotations, key=lambda x: x.index)
596+
other.annotations = sorted(other.annotations, key=lambda x: x.index)
597+
return (
598+
(self.annotation_id == other.annotation_id)
599+
and (self.annotations == other.annotations)
600+
and (self.mask_url == other.mask_url)
601+
and (self.reference_id == other.reference_id)
602+
)
603+
592604

593605
class AnnotationTypes(Enum):
594606
BOX = BOX_TYPE

nucleus/annotation_uploader.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
FormDataContextHandler,
88
make_many_form_data_requests_concurrently,
99
)
10-
from nucleus.constants import ITEMS_KEY, SEGMENTATIONS_KEY
10+
from nucleus.constants import MASK_TYPE, SERIALIZED_REQUEST_KEY
1111
from nucleus.payload_constructor import (
1212
construct_annotation_payload,
1313
construct_segmentation_payload,
@@ -143,7 +143,7 @@ def make_batched_file_form_data_requests(
143143
return make_many_form_data_requests_concurrently(
144144
client=self._client,
145145
requests=requests,
146-
route=f"dataset/{self.dataset_id}/annotate_segmentation_files",
146+
route=f"dataset/{self.dataset_id}/annotate",
147147
progressbar=progressbar,
148148
concurrency=local_file_upload_concurrency,
149149
)
@@ -166,7 +166,7 @@ def fn():
166166
)
167167
form_data = [
168168
FileFormField(
169-
name=ITEMS_KEY,
169+
name=SERIALIZED_REQUEST_KEY,
170170
filename=None,
171171
value=json.dumps(request_json),
172172
content_type="application/json",
@@ -186,7 +186,7 @@ def fn():
186186
)
187187
form_data.append(
188188
FileFormField(
189-
name=SEGMENTATIONS_KEY,
189+
name=MASK_TYPE,
190190
filename=segmentation.mask_url,
191191
value=mask_fp,
192192
content_type="image/png",

nucleus/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
REFERENCE_ID_KEY = "reference_id"
100100
REQUEST_ID_KEY = "requestId"
101101
SCENES_KEY = "scenes"
102+
SERIALIZED_REQUEST_KEY = "serialized_request"
102103
SEGMENTATIONS_KEY = "segmentations"
103104
SLICE_ID_KEY = "slice_id"
104105
STATUS_CODE_KEY = "status_code"

tests/test_segmentation.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,57 @@
11
from nucleus.annotation import SegmentationAnnotation
2+
from nucleus.dataset import Dataset
23
from tests.helpers import (
34
TEST_LOCAL_MASK_URL,
45
TEST_SEGMENTATION_ANNOTATIONS,
56
assert_segmentation_annotation_matches_dict,
67
)
78

89

9-
def test_single_local_semseg_gt_upload(dataset):
10-
annotation = SegmentationAnnotation.from_json(
10+
def test_single_local_semseg_gt_upload(dataset: Dataset):
11+
request_annotation = SegmentationAnnotation.from_json(
1112
TEST_SEGMENTATION_ANNOTATIONS[0]
1213
)
13-
annotation.mask_url = TEST_LOCAL_MASK_URL
14-
response = dataset.annotate(annotations=[annotation])
14+
request_annotation.mask_url = TEST_LOCAL_MASK_URL
15+
response = dataset.annotate(annotations=[request_annotation])
1516

1617
assert response["dataset_id"] == dataset.id
1718
assert response["annotations_processed"] == 1
1819
assert response["annotations_ignored"] == 0
1920

20-
response_annotation = dataset.refloc(annotation.reference_id)[
21+
response_annotation = dataset.refloc(request_annotation.reference_id)[
2122
"annotations"
2223
]["segmentation"][0]
23-
assert_segmentation_annotation_matches_dict(
24-
response_annotation, TEST_SEGMENTATION_ANNOTATIONS[0]
25-
)
24+
25+
assert response_annotation == request_annotation
26+
27+
28+
def test_batch_local_semseg_gt_upload(dataset: Dataset):
29+
30+
# This reference id is not in the dataset.
31+
bad_reference_id = TEST_SEGMENTATION_ANNOTATIONS[-1]["reference_id"]
32+
33+
request_annotations = [
34+
SegmentationAnnotation.from_json(json_data)
35+
for json_data in TEST_SEGMENTATION_ANNOTATIONS
36+
]
37+
for request_annotation in request_annotations:
38+
request_annotation.mask_url = TEST_LOCAL_MASK_URL
39+
response = dataset.annotate(annotations=request_annotations)
40+
41+
print(request_annotations)
42+
print(response)
43+
44+
assert response["dataset_id"] == dataset.id
45+
assert response["annotations_processed"] == 4
46+
assert response["annotations_ignored"] == 0
47+
assert bad_reference_id in response["errors"][0]
48+
49+
for request_annotation in request_annotations[:4]:
50+
response_annotation = dataset.refloc(request_annotation.reference_id)[
51+
"annotations"
52+
]["segmentation"][0]
53+
54+
assert response_annotation == request_annotation
2655

2756

2857
def test_single_semseg_gt_upload(dataset):
@@ -49,7 +78,7 @@ def test_batch_semseg_gt_upload(dataset):
4978
]
5079
response = dataset.annotate(annotations=annotations)
5180
assert response["dataset_id"] == dataset.id
52-
assert response["annotations_processed"] == 5
81+
assert response["annotations_processed"] == 4
5382
assert response["annotations_ignored"] == 0
5483

5584

@@ -61,14 +90,14 @@ def test_batch_semseg_gt_upload_ignore(dataset):
6190
]
6291
response = dataset.annotate(annotations=annotations)
6392
assert response["dataset_id"] == dataset.id
64-
assert response["annotations_processed"] == 5
93+
assert response["annotations_processed"] == 4
6594
assert response["annotations_ignored"] == 0
6695

6796
# When we re-upload, expect them to be ignored
6897
response = dataset.annotate(annotations=annotations)
6998
assert response["dataset_id"] == dataset.id
7099
assert response["annotations_processed"] == 0
71-
assert response["annotations_ignored"] == 5
100+
assert response["annotations_ignored"] == 4
72101

73102

74103
def test_batch_semseg_gt_upload_update(dataset):
@@ -79,11 +108,11 @@ def test_batch_semseg_gt_upload_update(dataset):
79108
]
80109
response = dataset.annotate(annotations=annotations)
81110
assert response["dataset_id"] == dataset.id
82-
assert response["annotations_processed"] == 5
111+
assert response["annotations_processed"] == 4
83112
assert response["annotations_ignored"] == 0
84113

85114
# When we re-upload, expect uploads to be processed
86115
response = dataset.annotate(annotations=annotations, update=True)
87116
assert response["dataset_id"] == dataset.id
88-
assert response["annotations_processed"] == 5
117+
assert response["annotations_processed"] == 4
89118
assert response["annotations_ignored"] == 0

0 commit comments

Comments
 (0)