1111from labelbox .schema .data_row import DataRow
1212from labelbox .orm import query
1313from labelbox .schema .bulk_import_request import BulkImportRequest
14- from labelbox .exceptions import InvalidQueryError
14+ from labelbox .exceptions import InvalidQueryError , LabelboxError
1515from labelbox .orm .db_object import DbObject , Updateable , Deletable
1616from labelbox .orm .model import Entity , Field , Relationship
1717from labelbox .pagination import PaginatedCollection
@@ -160,6 +160,39 @@ def labels(self, datasets=None, order_by=None):
160160 return PaginatedCollection (self .client , query_str , {id_param : self .uid },
161161 ["project" , "labels" ], Label )
162162
163+ def export_queued_data_rows (self , timeout_seconds = 120 ):
164+ """ Returns all data rows that are currently enqueued for this project.
165+
166+ Args:
167+ timeout_seconds (float): Max waiting time, in seconds.
168+ Returns:
169+ URL of the data file with this DataRow information. If the server didn't
170+ generate during the `timeout_seconds` period, None is returned.
171+ """
172+ id_param = "projectId"
173+ query_str = """mutation GetQueuedDataRowsExportUrlPyApi($%s: ID!)
174+ {exportQueuedDataRows(data:{projectId: $%s }) {downloadUrl createdAt status} }
175+ """ % (id_param , id_param )
176+ sleep_time = 2
177+ while True :
178+ res = self .client .execute (query_str , {id_param : self .uid })
179+ res = res ["exportQueuedDataRows" ]
180+ if res ["status" ] == "COMPLETE" :
181+ return res ["downloadUrl" ]
182+ elif res ["status" ] == "FAILED" :
183+ raise LabelboxError ("Data row export failed." )
184+
185+ timeout_seconds -= sleep_time
186+ if timeout_seconds <= 0 :
187+ raise LabelboxError (
188+ f"Unable to export data rows within { timeout_seconds } seconds."
189+ )
190+
191+ logger .debug (
192+ "Project '%s' queued data row export, waiting for server..." ,
193+ self .uid )
194+ time .sleep (sleep_time )
195+
163196 def export_labels (self , timeout_seconds = 60 ):
164197 """ Calls the server-side Label exporting that generates a JSON
165198 payload, and returns the URL to that payload.
@@ -193,13 +226,13 @@ def export_labels(self, timeout_seconds=60):
193226 time .sleep (sleep_time )
194227
195228 def export_issues (self , status = None ):
196- """ Calls the server-side Issues exporting that
229+ """ Calls the server-side Issues exporting that
197230 returns the URL to that payload.
198231
199232 Args:
200233 status (string): valid values: Open, Resolved
201234 Returns:
202- URL of the data file with this Project's issues.
235+ URL of the data file with this Project's issues.
203236 """
204237 id_param = "projectId"
205238 status_param = "status"
@@ -229,14 +262,14 @@ def export_issues(self, status=None):
229262 def upsert_instructions (self , instructions_file : str ):
230263 """
231264 * Uploads instructions to the UI. Running more than once will replace the instructions
232-
265+
233266 Args:
234267 instructions_file (str): Path to a local file.
235268 * Must be either a pdf, text, or html file.
236269
237270 Raises:
238271 ValueError:
239- * project must be setup
272+ * project must be setup
240273 * instructions file must end with one of ".text", ".txt", ".pdf", ".html"
241274 """
242275
@@ -267,18 +300,18 @@ def upsert_instructions(self, instructions_file: str):
267300
268301 self .client .execute (
269302 """mutation UpdateFrontendWithExistingOptionsPyApi (
270- $frontendId: ID!,
271- $optionsId: ID!,
272- $name: String!,
273- $description: String!,
303+ $frontendId: ID!,
304+ $optionsId: ID!,
305+ $name: String!,
306+ $description: String!,
274307 $customizationOptions: String!
275308 ) {
276309 updateLabelingFrontend(
277- where: {id: $frontendId},
310+ where: {id: $frontendId},
278311 data: {name: $name, description: $description}
279312 ) {id}
280313 updateLabelingFrontendOptions(
281- where: {id: $optionsId},
314+ where: {id: $optionsId},
282315 data: {customizationOptions: $customizationOptions}
283316 ) {id}
284317 }""" , {
@@ -390,10 +423,10 @@ def validate_labeling_parameter_overrides(self, data):
390423
391424 def set_labeling_parameter_overrides (self , data ):
392425 """ Adds labeling parameter overrides to this project.
393-
426+
394427 See information on priority here:
395428 https://docs.labelbox.com/en/configure-editor/queue-system#reservation-system
396-
429+
397430 >>> project.set_labeling_parameter_overrides([
398431 >>> (data_row_1, 2, 3), (data_row_2, 1, 4)])
399432
@@ -407,11 +440,11 @@ def set_labeling_parameter_overrides(self, data):
407440 - Minimum priority is 1.
408441 * Priority is not the queue position.
409442 - The position is determined by the relative priority.
410- - E.g. [(data_row_1, 5,1), (data_row_2, 2,1), (data_row_3, 10,1)]
443+ - E.g. [(data_row_1, 5,1), (data_row_2, 2,1), (data_row_3, 10,1)]
411444 will be assigned in the following order: [data_row_2, data_row_1, data_row_3]
412445 * Datarows with parameter overrides will appear before datarows without overrides.
413446 * The priority only effects items in the queue.
414- - Assigning a priority will not automatically add the item back into the queue.
447+ - Assigning a priority will not automatically add the item back into the queue.
415448 Number of labels:
416449 * The number of times a data row should be labeled.
417450 - Creates duplicate data rows in a project (one for each number of labels).
@@ -458,7 +491,7 @@ def unset_labeling_parameter_overrides(self, data_rows):
458491 def upsert_review_queue (self , quota_factor ):
459492 """ Sets the the proportion of total assets in a project to review.
460493
461- More information can be found here:
494+ More information can be found here:
462495 https://docs.labelbox.com/en/quality-assurance/review-labels#configure-review-percentage
463496
464497 Args:
0 commit comments