Skip to content

Commit 766dbb1

Browse files
author
Matt Sokoloff
committed
Merge branch 'ms/bulk-export-status' of https://github.com/Labelbox/labelbox-python into examples
2 parents 8c1ca40 + 01239f6 commit 766dbb1

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

labelbox/schema/bulk_import_request.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import ndjson
1111
import requests
1212
from pydantic import BaseModel, validator
13+
from requests.api import request
1314
from typing_extensions import Literal
1415
from typing import (Any, List, Optional, BinaryIO, Dict, Iterable, Tuple, Union,
1516
Type, Set)
@@ -115,58 +116,77 @@ class BulkImportRequest(DbObject):
115116
created_by = Relationship.ToOne("User", False, "created_by")
116117

117118
@property
118-
def inputs(self) -> Optional[List[Dict[str, str]]]:
119+
def inputs(self) -> List[Dict[str, Any]]:
119120
"""
120121
Inputs for each individual annotation uploaded.
121122
This should match the ndjson annotations that you have uploaded.
122123
123124
Returns:
124-
Uploaded ndjsons.
125+
Uploaded ndjson.
125126
126127
* This information will expire after 24 hours.
127128
"""
128129
return self._fetch_remote_ndjson(self.input_file_url)
129130

130131
@property
131-
def errors(self) -> Optional[List[Dict[str, str]]]:
132+
def errors(self) -> List[Dict[str, Any]]:
132133
"""
133-
Errors for each individual annotation uploaded.
134+
Errors for each individual annotation uploaded. This is a subset of statuses
134135
135136
Returns:
136-
Empty list if there are no errors and None if the update is still running.
137-
If there are errors, and the job has completed then a list of dicts containing the error messages will be returned.
137+
List of dicts containing error messages. Empty list means there were no errors
138+
See `BulkImportRequest.statuses` for more details.
138139
139140
* This information will expire after 24 hours.
140141
"""
142+
self.wait_until_done()
141143
return self._fetch_remote_ndjson(self.error_file_url)
142144

143145
@property
144-
def statuses(self) -> Optional[List[Dict[str, str]]]:
146+
def statuses(self) -> List[Dict[str, Any]]:
145147
"""
146148
Status for each individual annotation uploaded.
147149
148150
Returns:
149-
A status for each annotation if the upload is done running and was successful. Otherwise it returns None.
151+
A status for each annotation if the upload is done running.
152+
See below table for more details
153+
154+
.. list-table::
155+
:widths: 15 150
156+
:header-rows: 1
157+
158+
* - Field
159+
- Description
160+
* - uuid
161+
- Specifies the annotation for the status row.
162+
* - dataRow
163+
- JSON object containing the Labelbox data row ID for the annotation.
164+
* - status
165+
- Indicates SUCCESS or FAILURE.
166+
* - errors
167+
- An array of error messages included when status is FAILURE. Each error has a name, message and optional (key might not exist) additional_info.
150168
151169
* This information will expire after 24 hours.
152170
"""
171+
self.wait_until_done()
153172
return self._fetch_remote_ndjson(self.status_file_url)
154173

155174
@functools.lru_cache()
156-
def _fetch_remote_ndjson(
157-
self, url: Optional[str]) -> Optional[List[Dict[str, str]]]:
175+
def _fetch_remote_ndjson(self, url: str) -> List[Dict[str, Any]]:
158176
"""
159177
Fetches the remote ndjson file and caches the results.
160178
161179
Args:
162-
url (str): either the input_file_url, error_file_url, status_file_url, or None
163-
urls are None when the file is unavailable.
180+
url (str): Can be any url pointing to an ndjson file.
164181
Returns:
165-
None if the url is None or the ndjson as a list of dicts.
182+
ndjson as a list of dicts.
166183
"""
167-
if url is not None:
168-
return ndjson.loads(requests.get(url).text)
169-
return None
184+
if url is None:
185+
raise ValueError("Must provide valid ndjson url. Found `None`")
186+
187+
response = requests.get(url)
188+
response.raise_for_status()
189+
return ndjson.loads(response.text)
170190

171191
def refresh(self) -> None:
172192
"""Synchronizes values of all fields with the database.

tests/integration/bulk_import/test_bulk_import_request.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,11 @@ def test_wait_till_done(rectangle_inference, configured_project):
130130
annotations=url,
131131
validate=False)
132132

133-
assert bulk_import_request.errors is None
134-
assert bulk_import_request.statuses is None
135133
assert len(bulk_import_request.inputs) == 1
136-
137134
bulk_import_request.wait_until_done()
138135
assert bulk_import_request.state == BulkImportRequestState.FINISHED
139136

140-
#Check that the status files are being returned as expected
137+
# Check that the status files are being returned as expected
141138
assert len(bulk_import_request.errors) == 0
142139
assert len(bulk_import_request.inputs) == 1
143140
assert bulk_import_request.inputs[0]['uuid'] == rectangle_inference['uuid']

0 commit comments

Comments
 (0)