5
5
6
6
from core .permissions import AllPermissions
7
7
from core .redis import start_job_async_or_sync
8
+ from label_studio_sdk .label_interface import LabelInterface
8
9
from tasks .models import Annotation , Prediction , Task
9
10
10
11
logger = logging .getLogger (__name__ )
@@ -18,6 +19,8 @@ def cache_labels_job(project, queryset, **kwargs):
18
19
source_class = Annotation if source == 'annotations' else Prediction
19
20
control_tag = request_data .get ('custom_control_tag' ) or request_data .get ('control_tag' )
20
21
with_counters = request_data .get ('with_counters' , 'Yes' ).lower () == 'yes'
22
+ label_interface = LabelInterface (project .label_config )
23
+ label_interface_tags = {tag .name : tag for tag in label_interface .find_tags ('control' )}
21
24
22
25
if source == 'annotations' :
23
26
column_name = 'cache'
@@ -38,7 +41,7 @@ def cache_labels_job(project, queryset, **kwargs):
38
41
task_labels = []
39
42
annotations = source_class .objects .filter (task = task ).only ('result' )
40
43
for annotation in annotations :
41
- labels = extract_labels (annotation , control_tag )
44
+ labels = extract_labels (annotation , control_tag , label_interface_tags )
42
45
task_labels .extend (labels )
43
46
44
47
# cache labels in separate data column
@@ -57,20 +60,36 @@ def cache_labels_job(project, queryset, **kwargs):
57
60
return {'response_code' : 200 , 'detail' : f'Updated { len (tasks )} tasks' }
58
61
59
62
60
- def extract_labels (annotation , control_tag ):
63
+ def extract_labels (annotation , control_tag , label_interface_tags = None ):
61
64
labels = []
62
65
for region in annotation .result :
63
66
# find regions with specific control tag name or just all regions if control tag is None
64
67
if (control_tag is None or region ['from_name' ] == control_tag ) and 'value' in region :
65
- # scan value for a field with list of strings,
66
- # as bonus it will work with textareas too
68
+ # scan value for a field with list of strings (eg choices, textareas)
69
+ # or taxonomy (list of string-lists)
67
70
for key in region ['value' ]:
68
- if (
69
- isinstance (region ['value' ][key ], list )
70
- and region ['value' ][key ]
71
- and isinstance (region ['value' ][key ][0 ], str )
72
- ):
73
- labels .extend (region ['value' ][key ])
71
+ if region ['value' ][key ] and isinstance (region ['value' ][key ], list ):
72
+
73
+ if key == 'taxonomy' :
74
+ showFullPath = 'true'
75
+ pathSeparator = '/'
76
+ if label_interface_tags is not None and region ['from_name' ] in label_interface_tags :
77
+ # if from_name is not a custom_control tag, then we can try to fetch taxonomy formatting params
78
+ label_interface_tag = label_interface_tags [region ['from_name' ]]
79
+ showFullPath = label_interface_tag .attr .get ('showFullPath' , 'false' )
80
+ pathSeparator = label_interface_tag .attr .get ('pathSeparator' , '/' )
81
+
82
+ if showFullPath == 'false' :
83
+ for elems in region ['value' ][key ]:
84
+ labels .append (elems [- 1 ]) # just the leaf node of a taxonomy selection
85
+ else :
86
+ for elems in region ['value' ][key ]:
87
+ labels .append (pathSeparator .join (elems )) # the full delimited taxonomy path
88
+
89
+ # other control tag types like Choices & TextAreas
90
+ elif isinstance (region ['value' ][key ][0 ], str ):
91
+ labels .extend (region ['value' ][key ])
92
+
74
93
break
75
94
return labels
76
95
0 commit comments