11from collections import namedtuple
22from datetime import datetime , timezone
33import json
4+ from labelbox .schema .data_row import DataRow
45import logging
56from pathlib import Path
67import time
@@ -88,6 +89,7 @@ def create_label(self, **kwargs):
8889 # deprecated and we don't want the Py client lib user to know
8990 # about them. At the same time they're connected to a Label at
9091 # label creation in a non-standard way (connect via name).
92+ logger .warning ("This function is deprecated and is not compatible with the new editor." )
9193
9294 Label = Entity .Label
9395
@@ -249,18 +251,56 @@ def setup(self, labeling_frontend, labeling_frontend_options):
249251 timestamp = datetime .now (timezone .utc ).strftime ("%Y-%m-%dT%H:%M:%SZ" )
250252 self .update (setup_complete = timestamp )
251253
254+ def validate_labeling_parameter_overrides (self , data ):
255+ for idx , row in enumerate (data ):
256+ if len (row ) != 3 :
257+ raise TypeError (f"Data must be a list of tuples containing a DataRow, priority (int), num_labels (int). Found { len (row )} items" )
258+ data_row , priority , num_labels = row
259+ if not isinstance (data_row , DataRow ):
260+ raise TypeError (f"Datarow should be be of type DataRow. Found { data_row } " )
261+
262+ for name , value in [["priority" , priority ], ["Number of labels" , num_labels ]]:
263+ if not isinstance (value , int ):
264+ raise TypeError (f"{ name } must be an int. Found { type (value )} for data_row { data_row } " )
265+ if value < 1 :
266+ raise ValueError (f"{ name } must be greater than 0 for data_row { data_row } " )
267+
252268 def set_labeling_parameter_overrides (self , data ):
253269 """ Adds labeling parameter overrides to this project.
254270
271+ Priority:
272+ * data will be labeled in priority order with the lower priority numbers being labeled first
273+ - Minimum priority is 1.
274+ * Priority is not the queue position. The position is determined by the relative priority.
275+ - Eg. [(data_row_1, 5,1), (data_row_2, 2,1), (data_row_3, 10,1)]
276+ will be assigned in the following order: [data_row_2, data_row_1, data_row_3]
277+ * datarows with parameter overrides will appear before datarows without overrides
278+ * The priority only effects items in the queue and assigning a priority will not automatically add the item back the queue
279+ - If a datarow has already been labeled this will not have an effect until it is added back into the queue
280+
281+ Number of labels:
282+ * The number times a data row should be labeled
283+ * This will create duplicates in a project
284+ * The queue will never assign the same datarow to a labeler more than once
285+ - if the number of labels is greater than the number of labelers working on a project then
286+ the extra items will get stuck in the queue (thsi can be fixed by removing the override at any time).
287+ * This can add items to the queue even if they have already been labeled but they will only be assigned to members who have not labeled that image before.
288+ * Set this to 1 if you only want to effect the priority.
289+
290+
291+ See information on priority here:
292+ https://docs.labelbox.com/en/configure-editor/queue-system#reservation-system
293+
255294 >>> project.set_labeling_parameter_overrides([
256295 >>> (data_row_1, 2, 3), (data_row_2, 1, 4)])
257296
258297 Args:
259298 data (iterable): An iterable of tuples. Each tuple must contain
260- (DataRow, priority, numberOfLabels) for the new override.
299+ (Union[ DataRow, datarow_id] , priority, numberOfLabels) for the new override.
261300 Returns:
262301 bool, indicates if the operation was a success.
263302 """
303+ self .validate_labeling_parameter_overrides (data )
264304 data_str = ",\n " .join (
265305 "{dataRow: {id: \" %s\" }, priority: %d, numLabels: %d }" %
266306 (data_row .uid , priority , num_labels )
@@ -275,6 +315,8 @@ def set_labeling_parameter_overrides(self, data):
275315 def unset_labeling_parameter_overrides (self , data_rows ):
276316 """ Removes labeling parameter overrides to this project.
277317
318+ * This will remove unlabeled duplicates in the queue.
319+
278320 Args:
279321 data_rows (iterable): An iterable of DataRows.
280322 Returns:
@@ -290,12 +332,19 @@ def unset_labeling_parameter_overrides(self, data_rows):
290332 return res ["project" ]["unsetLabelingParameterOverrides" ]["success" ]
291333
292334 def upsert_review_queue (self , quota_factor ):
293- """ Reinitiates the review queue for this project.
335+ """ Sets the the proportion of total assets in a project to review.
336+
337+ More information can be found here:
338+ https://docs.labelbox.com/en/quality-assurance/review-labels#configure-review-percentage
294339
295340 Args:
296341 quota_factor (float): Which part (percentage) of the queue
297342 to reinitiate. Between 0 and 1.
298343 """
344+
345+ if (quota_factor > 1. ) or (quota_factor < 0. ):
346+ raise ValueError ("Quota factor must be in the range of [0,1]" )
347+
299348 id_param = "projectId"
300349 quota_param = "quotaFactor"
301350 query_str = """mutation UpsertReviewQueuePyApi($%s: ID!, $%s: Float!){
@@ -307,25 +356,6 @@ def upsert_review_queue(self, quota_factor):
307356 quota_param : quota_factor
308357 })
309358
310- def extend_reservations (self , queue_type ):
311- """ Extends all the current reservations for the current user on the given
312- queue type.
313-
314- Args:
315- queue_type (str): Either "LabelingQueue" or "ReviewQueue"
316- Returns:
317- int, the number of reservations that were extended.
318- """
319- if queue_type not in ("LabelingQueue" , "ReviewQueue" ):
320- raise InvalidQueryError ("Unsupported queue type: %s" % queue_type )
321-
322- id_param = "projectId"
323- query_str = """mutation ExtendReservationsPyApi($%s: ID!){
324- extendReservations(projectId:$%s queueType:%s)}""" % (
325- id_param , id_param , queue_type )
326- res = self .client .execute (query_str , {id_param : self .uid })
327- return res ["extendReservations" ]
328-
329359 def create_prediction_model (self , name , version ):
330360 """ Creates a PredictionModel connected to a Legacy Editor Project.
331361
@@ -335,6 +365,9 @@ def create_prediction_model(self, name, version):
335365 Returns:
336366 A newly created PredictionModel.
337367 """
368+
369+ logger .warning ("This function is deprecated and is not compatible with the new editor." )
370+
338371 PM = Entity .PredictionModel
339372 model = self .client ._create (PM , {
340373 PM .name .name : name ,
@@ -360,6 +393,8 @@ def create_prediction(self, label, data_row, prediction_model=None):
360393 is None and this Project's active_prediction_model is also
361394 None.
362395 """
396+ logger .warning ("This function is deprecated and is not compatible with the new editor." )
397+
363398 if prediction_model is None :
364399 prediction_model = self .active_prediction_model ()
365400 if prediction_model is None :
@@ -433,6 +468,7 @@ def upload_annotations(
433468 Returns:
434469 BulkImportRequest
435470 """
471+
436472 if isinstance (annotations , str ) or isinstance (annotations , Path ):
437473
438474 def _is_url_valid (url : Union [str , Path ]) -> bool :
@@ -493,6 +529,8 @@ class LabelingParameterOverride(DbObject):
493529 number_of_labels = Field .Int ("number_of_labels" )
494530
495531
532+
533+
496534LabelerPerformance = namedtuple (
497535 "LabelerPerformance" , "user count seconds_per_label, total_time_labeling "
498536 "consensus average_benchmark_agreement last_activity_time" )
0 commit comments