11import json
22import logging
3+ from string import Template
34import time
45import warnings
56from collections import namedtuple
67from datetime import datetime , timezone
78from pathlib import Path
8- from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , TypeVar , Union , overload
9+ from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , Tuple , TypeVar , Union , overload
910from urllib .parse import urlparse
1011
1112import requests
2829from labelbox .schema .export_filters import ProjectExportFilters , validate_datetime , build_filters
2930from labelbox .schema .export_params import ProjectExportParams
3031from labelbox .schema .export_task import ExportTask
32+ from labelbox .schema .id_type import IdType
33+ from labelbox .schema .identifiable import DataRowIdentifier , UniqueId
3134from labelbox .schema .identifiables import DataRowIdentifiers , UniqueIds
3235from labelbox .schema .media_type import MediaType
3336from labelbox .schema .queue_mode import QueueMode
4346except ImportError :
4447 pass
4548
49+ DataRowPriority = int
50+ LabelingParameterOverrideInput = Tuple [Union [DataRow , DataRowIdentifier ],
51+ DataRowPriority ]
52+
4653logger = logging .getLogger (__name__ )
4754
4855
56+ def validate_labeling_parameter_overrides (
57+ data : List [LabelingParameterOverrideInput ]) -> None :
58+ for idx , row in enumerate (data ):
59+ if len (row ) < 2 :
60+ raise TypeError (
61+ f"Data must be a list of tuples each containing two elements: a DataRow or a DataRowIdentifier and priority (int). Found { len (row )} items. Index: { idx } "
62+ )
63+ data_row_identifier = row [0 ]
64+ priority = row [1 ]
65+ if not isinstance (data_row_identifier ,
66+ Entity .DataRow ) and not isinstance (
67+ data_row_identifier , DataRowIdentifier ):
68+ raise TypeError (
69+ f"Data row identifier should be be of type DataRow or Data Row Identifier. Found { type (data_row_identifier )} . Index: { idx } "
70+ )
71+
72+ if not isinstance (priority , int ):
73+ raise TypeError (
74+ f"Priority must be an int. Found { type (priority )} for data_row_identifier { data_row_identifier } . Index: { idx } "
75+ )
76+
77+
4978class Project (DbObject , Updateable , Deletable ):
5079 """ A Project is a container that includes a labeling frontend, an ontology,
5180 datasets and labels.
@@ -1129,36 +1158,25 @@ def get_queue_mode(self) -> "QueueMode":
11291158 else :
11301159 raise ValueError ("Status not known" )
11311160
1132- def validate_labeling_parameter_overrides (self , data ) -> None :
1133- for idx , row in enumerate (data ):
1134- if len (row ) < 2 :
1135- raise TypeError (
1136- f"Data must be a list of tuples containing a DataRow and priority (int). Found { len (row )} items. Index: { idx } "
1137- )
1138- data_row = row [0 ]
1139- priority = row [1 ]
1140- if not isinstance (data_row , Entity .DataRow ):
1141- raise TypeError (
1142- f"data_row should be be of type DataRow. Found { type (data_row )} . Index: { idx } "
1143- )
1144-
1145- if not isinstance (priority , int ):
1146- raise TypeError (
1147- f"Priority must be an int. Found { type (priority )} for data_row { data_row } . Index: { idx } "
1148- )
1149-
1150- def set_labeling_parameter_overrides (self , data ) -> bool :
1161+ def set_labeling_parameter_overrides (
1162+ self , data : List [LabelingParameterOverrideInput ]) -> bool :
11511163 """ Adds labeling parameter overrides to this project.
11521164
11531165 See information on priority here:
11541166 https://docs.labelbox.com/en/configure-editor/queue-system#reservation-system
11551167
11561168 >>> project.set_labeling_parameter_overrides([
1157- >>> (data_row_1, 2), (data_row_2, 1)])
1169+ >>> (data_row_id1, 2), (data_row_id2, 1)])
1170+ or
1171+ >>> project.set_labeling_parameter_overrides([
1172+ >>> (data_row_gk1, 2), (data_row_gk2, 1)])
11581173
11591174 Args:
11601175 data (iterable): An iterable of tuples. Each tuple must contain
1161- (DataRow, priority<int>) for the new override.
1176+ either (DataRow, DataRowPriority<int>)
1177+ or (DataRowIdentifier, priority<int>) for the new override.
1178+ DataRowIdentifier is an object representing a data row id or a global key. A DataIdentifier object can be a UniqueIds or GlobalKeys class.
1179+ NOTE - passing whole DatRow is deprecated. Please use a DataRowIdentifier instead.
11621180
11631181 Priority:
11641182 * Data will be labeled in priority order.
@@ -1174,15 +1192,30 @@ def set_labeling_parameter_overrides(self, data) -> bool:
11741192 bool, indicates if the operation was a success.
11751193 """
11761194 data = [t [:2 ] for t in data ]
1177- self .validate_labeling_parameter_overrides (data )
1178- data_str = ",\n " .join ("{dataRow: {id: \" %s\" }, priority: %d }" %
1179- (data_row .uid , priority )
1180- for data_row , priority in data )
1181- id_param = "projectId"
1182- query_str = """mutation SetLabelingParameterOverridesPyApi($%s: ID!){
1183- project(where: { id: $%s }) {setLabelingParameterOverrides
1184- (data: [%s]) {success}}} """ % (id_param , id_param , data_str )
1185- res = self .client .execute (query_str , {id_param : self .uid })
1195+ validate_labeling_parameter_overrides (data )
1196+
1197+ template = Template (
1198+ """mutation SetLabelingParameterOverridesPyApi($$projectId: ID!)
1199+ {project(where: { id: $$projectId })
1200+ {setLabelingParameterOverrides
1201+ (dataWithDataRowIdentifiers: [$dataWithDataRowIdentifiers])
1202+ {success}}}
1203+ """ )
1204+
1205+ data_rows_with_identifiers = ""
1206+ for data_row , priority in data :
1207+ if isinstance (data_row , DataRow ):
1208+ data_rows_with_identifiers += f"{{dataRowIdentifier: {{id: \" { data_row .uid } \" , idType: { IdType .DataRowId } }}, priority: { priority } }},"
1209+ elif isinstance (data_row , DataRowIdentifier ):
1210+ data_rows_with_identifiers += f"{{dataRowIdentifier: {{id: \" { data_row .key } \" , idType: { data_row .id_type } }}, priority: { priority } }},"
1211+ else :
1212+ raise TypeError (
1213+ f"Data row identifier should be be of type DataRow or Data Row Identifier. Found { type (data_row )} ."
1214+ )
1215+
1216+ query_str = template .substitute (
1217+ dataWithDataRowIdentifiers = data_rows_with_identifiers )
1218+ res = self .client .execute (query_str , {"projectId" : self .uid })
11861219 return res ["project" ]["setLabelingParameterOverrides" ]["success" ]
11871220
11881221 @overload
0 commit comments