@@ -208,11 +208,11 @@ def annotations_by_data_type_v2(
208208
209209@pytest .fixture
210210def ontology ():
211- bbox_tool = {
211+ bbox_tool_with_nested_text = {
212212 'required' :
213213 False ,
214214 'name' :
215- 'bbox ' ,
215+ 'bbox_tool_with_nested_text ' ,
216216 'tool' :
217217 'rectangle' ,
218218 'color' :
@@ -259,6 +259,51 @@ def ontology():
259259 }]
260260 }
261261
262+ bbox_tool = {
263+ 'required' :
264+ False ,
265+ 'name' :
266+ 'bbox' ,
267+ 'tool' :
268+ 'rectangle' ,
269+ 'color' :
270+ '#a23030' ,
271+ 'classifications' : [{
272+ 'required' :
273+ False ,
274+ 'instructions' :
275+ 'nested' ,
276+ 'name' :
277+ 'nested' ,
278+ 'type' :
279+ 'radio' ,
280+ 'options' : [{
281+ 'label' :
282+ 'radio_option_1' ,
283+ 'value' :
284+ 'radio_value_1' ,
285+ 'options' : [{
286+ 'required' :
287+ False ,
288+ 'instructions' :
289+ 'nested_checkbox' ,
290+ 'name' :
291+ 'nested_checkbox' ,
292+ 'type' :
293+ 'checklist' ,
294+ 'options' : [{
295+ 'label' : 'nested_checkbox_option_1' ,
296+ 'value' : 'nested_checkbox_value_1' ,
297+ 'options' : []
298+ }, {
299+ 'label' : 'nested_checkbox_option_2' ,
300+ 'value' : 'nested_checkbox_value_2'
301+ }]
302+ }]
303+ },]
304+ }]
305+ }
306+
262307 polygon_tool = {
263308 'required' : False ,
264309 'name' : 'polygon' ,
@@ -387,6 +432,7 @@ def ontology():
387432
388433 tools = [
389434 bbox_tool ,
435+ bbox_tool_with_nested_text ,
390436 polygon_tool ,
391437 polyline_tool ,
392438 point_tool ,
@@ -500,6 +546,10 @@ def configured_project_without_data_rows(client, ontology, rand_gen):
500546 project .delete ()
501547
502548
549+ # This function allows to convert an ontology feature to actual annotation
550+ # At the moment it expects only one feature per tool type and this creates unnecessary coupling between differet tests
551+ # In an example of a 'rectangle' we have extended to support multiple instances of the same tool type
552+ # TODO: we will support this approach in the future for all tools
503553@pytest .fixture
504554def prediction_id_mapping (configured_project ):
505555 # Maps tool types to feature schema ids
@@ -512,15 +562,31 @@ def prediction_id_mapping(configured_project):
512562 else :
513563 tool_type = tool [
514564 'type' ] if 'scope' not in tool else f"{ tool ['type' ]} _{ tool ['scope' ]} " # so 'checklist' of 'checklist_index'
515- result [tool_type ] = {
516- "uuid" : str (uuid .uuid4 ()),
517- "schemaId" : tool ['featureSchemaId' ],
518- "name" : tool ['name' ],
519- "dataRow" : {
520- "id" : configured_project .data_row_ids [idx ],
521- },
522- 'tool' : tool
523- }
565+
566+ # TODO: remove this once we have a better way to associate multiple tools instances with a single tool type
567+ if tool_type == 'rectangle' :
568+ value = {
569+ "uuid" : str (uuid .uuid4 ()),
570+ "schemaId" : tool ['featureSchemaId' ],
571+ "name" : tool ['name' ],
572+ "dataRow" : {
573+ "id" : configured_project .data_row_ids [idx ],
574+ },
575+ 'tool' : tool
576+ }
577+ if tool_type not in result :
578+ result [tool_type ] = []
579+ result [tool_type ].append (value )
580+ else :
581+ result [tool_type ] = {
582+ "uuid" : str (uuid .uuid4 ()),
583+ "schemaId" : tool ['featureSchemaId' ],
584+ "name" : tool ['name' ],
585+ "dataRow" : {
586+ "id" : configured_project .data_row_ids [idx ],
587+ },
588+ 'tool' : tool
589+ }
524590 return result
525591
526592
@@ -546,9 +612,49 @@ def polygon_inference(prediction_id_mapping):
546612 return polygon
547613
548614
615+ def find_tool_by_name (tool_instances , name ):
616+ for tool in tool_instances :
617+ if tool ['name' ] == name :
618+ return tool
619+ return None
620+
621+
549622@pytest .fixture
550623def rectangle_inference (prediction_id_mapping ):
551- rectangle = prediction_id_mapping ['rectangle' ].copy ()
624+ tool_instance = find_tool_by_name (prediction_id_mapping ['rectangle' ],
625+ 'bbox' )
626+ rectangle = tool_instance .copy ()
627+ rectangle .update ({
628+ "bbox" : {
629+ "top" : 48 ,
630+ "left" : 58 ,
631+ "height" : 65 ,
632+ "width" : 12
633+ },
634+ 'classifications' : [{
635+ "schemaId" :
636+ rectangle ['tool' ]['classifications' ][0 ]['featureSchemaId' ],
637+ "name" :
638+ rectangle ['tool' ]['classifications' ][0 ]['name' ],
639+ "answer" : {
640+ "schemaId" :
641+ rectangle ['tool' ]['classifications' ][0 ]['options' ][0 ]
642+ ['featureSchemaId' ],
643+ "name" :
644+ rectangle ['tool' ]['classifications' ][0 ]['options' ][0 ]
645+ ['value' ]
646+ }
647+ }]
648+ })
649+ del rectangle ['tool' ]
650+ return rectangle
651+
652+
653+ @pytest .fixture
654+ def rectangle_inference_with_confidence (prediction_id_mapping ):
655+ tool_instance = find_tool_by_name (prediction_id_mapping ['rectangle' ],
656+ 'bbox_tool_with_nested_text' )
657+ rectangle = tool_instance .copy ()
552658 rectangle .update ({
553659 "bbox" : {
554660 "top" : 48 ,
@@ -581,17 +687,13 @@ def rectangle_inference(prediction_id_mapping):
581687 }
582688 }]
583689 })
584- del rectangle ['tool' ]
585- return rectangle
586690
587-
588- @pytest .fixture
589- def rectangle_inference_with_confidence (rectangle_inference ):
590- rectangle = rectangle_inference .copy ()
591691 rectangle .update ({"confidence" : 0.9 })
592692 rectangle ["classifications" ][0 ]["answer" ]["confidence" ] = 0.8
593693 rectangle ["classifications" ][0 ]["answer" ]["classifications" ][0 ][
594694 "confidence" ] = 0.7
695+
696+ del rectangle ['tool' ]
595697 return rectangle
596698
597699
0 commit comments