1
+ import pytest
2
+
3
+ from helpers import (
4
+ TEST_DATASET_NAME ,
5
+ TEST_IMG_URLS ,
6
+ TEST_BOX_ANNOTATIONS ,
7
+ TEST_POLYGON_ANNOTATIONS ,
8
+ reference_id_from_url ,
9
+ )
10
+
11
+ from nucleus import BoxAnnotation , PolygonAnnotation , DatasetItem
12
+ from nucleus .constants import ERROR_PAYLOAD
13
+
14
+
15
+ # Asserts that a box annotation instance matches a dict representing its properties.
16
+ # Useful to check annotation uploads/updates match.
17
+ def assert_box_annotation_matches_dict (annotation_instance , annotation_dict ):
18
+ assert annotation_instance .label == annotation_dict ['label' ]
19
+ assert annotation_instance .x == annotation_dict ['x' ]
20
+ assert annotation_instance .y == annotation_dict ['y' ]
21
+ assert annotation_instance .height == annotation_dict ['height' ]
22
+ assert annotation_instance .width == annotation_dict ['width' ]
23
+ assert annotation_instance .annotation_id == annotation_dict ['annotation_id' ]
24
+
25
+ def assert_polygon_annotation_matches_dict (annotation_instance , annotation_dict ):
26
+ assert annotation_instance .label == annotation_dict ['label' ]
27
+ assert annotation_instance .annotation_id == annotation_dict ['annotation_id' ]
28
+ for instance_pt , dict_pt in zip (annotation_instance .vertices , annotation_dict ['vertices' ]):
29
+ assert instance_pt ['x' ] == dict_pt ['x' ]
30
+ assert instance_pt ['y' ] == dict_pt ['y' ]
31
+
32
+ @pytest .fixture ()
33
+ def dataset (CLIENT ):
34
+ ds = CLIENT .create_dataset (TEST_DATASET_NAME )
35
+ ds_items = []
36
+ for url in TEST_IMG_URLS :
37
+ ds_items .append (DatasetItem (
38
+ image_location = url ,
39
+ reference_id = reference_id_from_url (url ),
40
+ ))
41
+
42
+ response = ds .append (ds_items )
43
+ assert ERROR_PAYLOAD not in response .json ()
44
+ yield ds
45
+
46
+ response = CLIENT .delete_dataset (ds .id )
47
+ assert response == {}
48
+
49
+
50
+ def test_box_gt_upload (dataset ):
51
+ annotation = BoxAnnotation (** TEST_BOX_ANNOTATIONS [0 ])
52
+ response = dataset .annotate (annotations = [annotation ])
53
+
54
+ assert response ['dataset_id' ] == dataset .id
55
+ assert response ['annotations_processed' ] == 1
56
+
57
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
58
+ assert len (response ) == 1
59
+ response_annotation = response [0 ]
60
+ assert_box_annotation_matches_dict (response_annotation , TEST_BOX_ANNOTATIONS [0 ])
61
+
62
+
63
+ def test_polygon_gt_upload (dataset ):
64
+ annotation = PolygonAnnotation (** TEST_POLYGON_ANNOTATIONS [0 ])
65
+ response = dataset .annotate (annotations = [annotation ])
66
+
67
+ assert response ['dataset_id' ] == dataset .id
68
+ assert response ['annotations_processed' ] == 1
69
+
70
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
71
+ assert len (response ) == 1
72
+ response_annotation = response [0 ]
73
+ print (response_annotation )
74
+ assert_polygon_annotation_matches_dict (response_annotation , TEST_POLYGON_ANNOTATIONS [0 ])
75
+
76
+
77
+ def test_box_gt_upload_update (dataset ):
78
+ annotation = BoxAnnotation (** TEST_BOX_ANNOTATIONS [0 ])
79
+ response = dataset .annotate (annotations = [annotation ])
80
+
81
+ assert response ['annotations_processed' ] == 1
82
+
83
+ # Copy so we don't modify the original.
84
+ annotation_update_params = dict (TEST_BOX_ANNOTATIONS [1 ])
85
+ annotation_update_params ['annotation_id' ] = TEST_BOX_ANNOTATIONS [0 ]['annotation_id' ]
86
+ annotation_update_params ['reference_id' ] = TEST_BOX_ANNOTATIONS [0 ]['reference_id' ]
87
+
88
+ annotation_update = BoxAnnotation (** annotation_update_params )
89
+ response = dataset .annotate (annotations = [annotation_update ], update = True )
90
+
91
+ assert response ['annotations_processed' ] == 1
92
+
93
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
94
+ assert len (response ) == 1
95
+ response_annotation = response [0 ]
96
+ assert_box_annotation_matches_dict (response_annotation , annotation_update_params )
97
+
98
+
99
+ def test_box_gt_upload_ignore (dataset ):
100
+ annotation = BoxAnnotation (** TEST_BOX_ANNOTATIONS [0 ])
101
+ response = dataset .annotate (annotations = [annotation ])
102
+
103
+ assert response ['annotations_processed' ] == 1
104
+
105
+ # Copy so we don't modify the original.
106
+ annotation_update_params = dict (TEST_BOX_ANNOTATIONS [1 ])
107
+ annotation_update_params ['annotation_id' ] = TEST_BOX_ANNOTATIONS [0 ]['annotation_id' ]
108
+ annotation_update_params ['reference_id' ] = TEST_BOX_ANNOTATIONS [0 ]['reference_id' ]
109
+ annotation_update = BoxAnnotation (** annotation_update_params )
110
+ # Default behavior is ignore.
111
+ response = dataset .annotate (annotations = [annotation_update ])
112
+
113
+ assert response ['annotations_processed' ] == 1
114
+
115
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
116
+ assert len (response ) == 1
117
+ response_annotation = response [0 ]
118
+ assert_box_annotation_matches_dict (response_annotation , TEST_BOX_ANNOTATIONS [0 ])
119
+
120
+
121
+ def test_polygon_gt_upload_update (dataset ):
122
+ annotation = PolygonAnnotation (** TEST_POLYGON_ANNOTATIONS [0 ])
123
+ response = dataset .annotate (annotations = [annotation ])
124
+
125
+ assert response ['annotations_processed' ] == 1
126
+
127
+ # Copy so we don't modify the original.
128
+ annotation_update_params = dict (TEST_POLYGON_ANNOTATIONS [1 ])
129
+ annotation_update_params ['annotation_id' ] = TEST_POLYGON_ANNOTATIONS [0 ]['annotation_id' ]
130
+ annotation_update_params ['reference_id' ] = TEST_POLYGON_ANNOTATIONS [0 ]['reference_id' ]
131
+
132
+ annotation_update = PolygonAnnotation (** annotation_update_params )
133
+ response = dataset .annotate (annotations = [annotation_update ], update = True )
134
+
135
+ assert response ['annotations_processed' ] == 1
136
+
137
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
138
+ assert len (response ) == 1
139
+ response_annotation = response [0 ]
140
+ assert_polygon_annotation_matches_dict (response_annotation , annotation_update_params )
141
+
142
+
143
+ def test_polygon_gt_upload_ignore (dataset ):
144
+ annotation = PolygonAnnotation (** TEST_POLYGON_ANNOTATIONS [0 ])
145
+ response = dataset .annotate (annotations = [annotation ])
146
+
147
+ assert response ['annotations_processed' ] == 1
148
+
149
+ # Copy so we don't modify the original.
150
+ annotation_update_params = dict (TEST_POLYGON_ANNOTATIONS [1 ])
151
+ annotation_update_params ['annotation_id' ] = TEST_POLYGON_ANNOTATIONS [0 ]['annotation_id' ]
152
+ annotation_update_params ['reference_id' ] = TEST_POLYGON_ANNOTATIONS [0 ]['reference_id' ]
153
+
154
+ annotation_update = PolygonAnnotation (** annotation_update_params )
155
+ # Default behavior is ignore.
156
+ response = dataset .annotate (annotations = [annotation_update ])
157
+
158
+ assert response ['annotations_processed' ] == 1
159
+
160
+ response = dataset .refloc (annotation .reference_id )['annotations' ]
161
+ assert len (response ) == 1
162
+ response_annotation = response [0 ]
163
+ assert_polygon_annotation_matches_dict (response_annotation , TEST_POLYGON_ANNOTATIONS [0 ])
0 commit comments