Skip to content

Commit de9b3ad

Browse files
vbrodskyGabefiresfendell-labelbox
authored
Vb/merge 5.1.0 (#1850)
Co-authored-by: Gabe <33893811+Gabefire@users.noreply.github.com> Co-authored-by: sfendell-labelbox <150080555+sfendell-labelbox@users.noreply.github.com>
1 parent a81e3a6 commit de9b3ad

File tree

12 files changed

+151
-92
lines changed

12 files changed

+151
-92
lines changed

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
project = 'Python SDK reference'
1717
copyright = '2024, Labelbox'
1818
author = 'Labelbox'
19-
release = '5.0.0'
19+
release = '5.1.0'
2020

2121
# -- General configuration ---------------------------------------------------
2222

libs/labelbox/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Changelog
2+
# Version 5.1.0 (2024-09-27)
3+
## Fixed
4+
* Support self-signed SSL certs([#1811](https://github.com/Labelbox/labelbox-python/pull/1811))
5+
* Rectangle units now correctly support percent inputs([#1848](https://github.com/Labelbox/labelbox-python/pull/1848))
6+
27
# Version 5.0.0 (2024-09-16)
38
## Updated
49
* Set tasks_remaining_count to None LabelingServiceDashboard if labeling has not started ([#1817](https://github.com/Labelbox/labelbox-python/pull/1817))

libs/labelbox/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "labelbox"
3-
version = "5.0.0"
3+
version = "5.1.0"
44
description = "Labelbox Python API"
55
authors = [{ name = "Labelbox", email = "engineering@labelbox.com" }]
66
dependencies = [

libs/labelbox/src/labelbox/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "labelbox"
22

3-
__version__ = "5.0.0"
3+
__version__ = "5.1.0"
44

55
from labelbox.client import Client
66
from labelbox.schema.project import Project

libs/labelbox/src/labelbox/client.py

Lines changed: 47 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@
77
import time
88
import urllib.parse
99
from collections import defaultdict
10+
from datetime import datetime, timezone
1011
from types import MappingProxyType
1112
from typing import Any, Callable, Dict, List, Optional, Set, Union, overload
1213

13-
import lbox.exceptions
1414
import requests
1515
import requests.exceptions
1616
from google.api_core import retry
17+
from lbox.exceptions import (
18+
InternalServerError,
19+
LabelboxError,
20+
ResourceNotFoundError,
21+
TimeoutError,
22+
)
1723
from lbox.request_client import RequestClient
1824

1925
from labelbox import __version__ as SDK_VERSION
@@ -111,7 +117,7 @@ def __init__(
111117
enable_experimental (bool): Indicates whether or not to use experimental features
112118
app_url (str) : host url for all links to the web app
113119
Raises:
114-
lbox.exceptions.AuthenticationError: If no `api_key`
120+
AuthenticationError: If no `api_key`
115121
is provided as an argument or via the environment
116122
variable.
117123
"""
@@ -199,7 +205,7 @@ def upload_file(self, path: str) -> str:
199205
Returns:
200206
str, the URL of uploaded data.
201207
Raises:
202-
lbox.exceptions.LabelboxError: If upload failed.
208+
LabelboxError: If upload failed.
203209
"""
204210
content_type, _ = mimetypes.guess_type(path)
205211
filename = os.path.basename(path)
@@ -208,9 +214,7 @@ def upload_file(self, path: str) -> str:
208214
content=f.read(), filename=filename, content_type=content_type
209215
)
210216

211-
@retry.Retry(
212-
predicate=retry.if_exception_type(lbox.exceptions.InternalServerError)
213-
)
217+
@retry.Retry(predicate=retry.if_exception_type(InternalServerError))
214218
def upload_data(
215219
self,
216220
content: bytes,
@@ -230,7 +234,7 @@ def upload_data(
230234
str, the URL of uploaded data.
231235
232236
Raises:
233-
lbox.exceptions.LabelboxError: If upload failed.
237+
LabelboxError: If upload failed.
234238
"""
235239

236240
request_data = {
@@ -271,18 +275,16 @@ def upload_data(
271275

272276
if response.status_code == 502:
273277
error_502 = "502 Bad Gateway"
274-
raise lbox.exceptions.InternalServerError(error_502)
278+
raise InternalServerError(error_502)
275279
elif response.status_code == 503:
276-
raise lbox.exceptions.InternalServerError(response.text)
280+
raise InternalServerError(response.text)
277281
elif response.status_code == 520:
278-
raise lbox.exceptions.InternalServerError(response.text)
282+
raise InternalServerError(response.text)
279283

280284
try:
281285
file_data = response.json().get("data", None)
282286
except ValueError as e: # response is not valid JSON
283-
raise lbox.exceptions.LabelboxError(
284-
"Failed to upload, unknown cause", e
285-
)
287+
raise LabelboxError("Failed to upload, unknown cause", e)
286288

287289
if not file_data or not file_data.get("uploadFile", None):
288290
try:
@@ -292,9 +294,7 @@ def upload_data(
292294
)
293295
except Exception:
294296
error_msg = "Unknown error"
295-
raise lbox.exceptions.LabelboxError(
296-
"Failed to upload, message: %s" % error_msg
297-
)
297+
raise LabelboxError("Failed to upload, message: %s" % error_msg)
298298

299299
return file_data["uploadFile"]["url"]
300300

@@ -307,15 +307,15 @@ def _get_single(self, db_object_type, uid):
307307
Returns:
308308
Object of `db_object_type`.
309309
Raises:
310-
lbox.exceptions.ResourceNotFoundError: If there is no object
310+
ResourceNotFoundError: If there is no object
311311
of the given type for the given ID.
312312
"""
313313
query_str, params = query.get_single(db_object_type, uid)
314314

315315
res = self.execute(query_str, params)
316316
res = res and res.get(utils.camel_case(db_object_type.type_name()))
317317
if res is None:
318-
raise lbox.exceptions.ResourceNotFoundError(db_object_type, params)
318+
raise ResourceNotFoundError(db_object_type, params)
319319
else:
320320
return db_object_type(self, res)
321321

@@ -329,7 +329,7 @@ def get_project(self, project_id) -> Project:
329329
Returns:
330330
The sought Project.
331331
Raises:
332-
lbox.exceptions.ResourceNotFoundError: If there is no
332+
ResourceNotFoundError: If there is no
333333
Project with the given ID.
334334
"""
335335
return self._get_single(Entity.Project, project_id)
@@ -344,7 +344,7 @@ def get_dataset(self, dataset_id) -> Dataset:
344344
Returns:
345345
The sought Dataset.
346346
Raises:
347-
lbox.exceptions.ResourceNotFoundError: If there is no
347+
ResourceNotFoundError: If there is no
348348
Dataset with the given ID.
349349
"""
350350
return self._get_single(Entity.Dataset, dataset_id)
@@ -470,7 +470,7 @@ def _create(self, db_object_type, data, extra_params={}):
470470
)
471471

472472
if not res:
473-
raise lbox.exceptions.LabelboxError(
473+
raise LabelboxError(
474474
"Failed to create %s" % db_object_type.type_name()
475475
)
476476
res = res["create%s" % db_object_type.type_name()]
@@ -528,9 +528,7 @@ def delete_model_config(self, id: str) -> bool:
528528
params = {"id": id}
529529
result = self.execute(query, params)
530530
if not result:
531-
raise lbox.exceptions.ResourceNotFoundError(
532-
Entity.ModelConfig, params
533-
)
531+
raise ResourceNotFoundError(Entity.ModelConfig, params)
534532
return result["deleteModelConfig"]["success"]
535533

536534
def create_dataset(
@@ -589,7 +587,7 @@ def create_dataset(
589587
)
590588

591589
if not validation_result["validateDataset"]["valid"]:
592-
raise lbox.exceptions.LabelboxError(
590+
raise LabelboxError(
593591
"IAMIntegration was not successfully added to the dataset."
594592
)
595593
except Exception as e:
@@ -895,7 +893,7 @@ def get_data_row_by_global_key(self, global_key: str) -> DataRow:
895893
"""
896894
res = self.get_data_row_ids_for_global_keys([global_key])
897895
if res["status"] != "SUCCESS":
898-
raise lbox.exceptions.ResourceNotFoundError(
896+
raise ResourceNotFoundError(
899897
Entity.DataRow, {global_key: global_key}
900898
)
901899
data_row_id = res["results"][0]
@@ -923,7 +921,7 @@ def get_model(self, model_id) -> Model:
923921
Returns:
924922
The sought Model.
925923
Raises:
926-
lbox.exceptions.ResourceNotFoundError: If there is no
924+
ResourceNotFoundError: If there is no
927925
Model with the given ID.
928926
"""
929927
return self._get_single(Entity.Model, model_id)
@@ -1169,7 +1167,7 @@ def delete_unused_feature_schema(self, feature_schema_id: str) -> None:
11691167
response = self.connection.delete(endpoint)
11701168

11711169
if response.status_code != requests.codes.no_content:
1172-
raise lbox.exceptions.LabelboxError(
1170+
raise LabelboxError(
11731171
"Failed to delete the feature schema, message: "
11741172
+ str(response.json()["message"])
11751173
)
@@ -1190,7 +1188,7 @@ def delete_unused_ontology(self, ontology_id: str) -> None:
11901188
response = self.connection.delete(endpoint)
11911189

11921190
if response.status_code != requests.codes.no_content:
1193-
raise lbox.exceptions.LabelboxError(
1191+
raise LabelboxError(
11941192
"Failed to delete the ontology, message: "
11951193
+ str(response.json()["message"])
11961194
)
@@ -1220,7 +1218,7 @@ def update_feature_schema_title(
12201218
if response.status_code == requests.codes.ok:
12211219
return self.get_feature_schema(feature_schema_id)
12221220
else:
1223-
raise lbox.exceptions.LabelboxError(
1221+
raise LabelboxError(
12241222
"Failed to update the feature schema, message: "
12251223
+ str(response.json()["message"])
12261224
)
@@ -1256,7 +1254,7 @@ def upsert_feature_schema(self, feature_schema: Dict) -> FeatureSchema:
12561254
if response.status_code == requests.codes.ok:
12571255
return self.get_feature_schema(response.json()["schemaId"])
12581256
else:
1259-
raise lbox.exceptions.LabelboxError(
1257+
raise LabelboxError(
12601258
"Failed to upsert the feature schema, message: "
12611259
+ str(response.json()["message"])
12621260
)
@@ -1284,7 +1282,7 @@ def insert_feature_schema_into_ontology(
12841282
)
12851283
response = self.connection.post(endpoint, json={"position": position})
12861284
if response.status_code != requests.codes.created:
1287-
raise lbox.exceptions.LabelboxError(
1285+
raise LabelboxError(
12881286
"Failed to insert the feature schema into the ontology, message: "
12891287
+ str(response.json()["message"])
12901288
)
@@ -1309,7 +1307,7 @@ def get_unused_ontologies(self, after: str = None) -> List[str]:
13091307
if response.status_code == requests.codes.ok:
13101308
return response.json()
13111309
else:
1312-
raise lbox.exceptions.LabelboxError(
1310+
raise LabelboxError(
13131311
"Failed to get unused ontologies, message: "
13141312
+ str(response.json()["message"])
13151313
)
@@ -1334,7 +1332,7 @@ def get_unused_feature_schemas(self, after: str = None) -> List[str]:
13341332
if response.status_code == requests.codes.ok:
13351333
return response.json()
13361334
else:
1337-
raise lbox.exceptions.LabelboxError(
1335+
raise LabelboxError(
13381336
"Failed to get unused feature schemas, message: "
13391337
+ str(response.json()["message"])
13401338
)
@@ -1630,12 +1628,12 @@ def _format_failed_rows(
16301628
elif (
16311629
res["assignGlobalKeysToDataRowsResult"]["jobStatus"] == "FAILED"
16321630
):
1633-
raise lbox.exceptions.LabelboxError(
1631+
raise LabelboxError(
16341632
"Job assign_global_keys_to_data_rows failed."
16351633
)
16361634
current_time = time.time()
16371635
if current_time - start_time > timeout_seconds:
1638-
raise lbox.exceptions.TimeoutError(
1636+
raise TimeoutError(
16391637
"Timed out waiting for assign_global_keys_to_data_rows job to complete."
16401638
)
16411639
time.sleep(sleep_time)
@@ -1739,12 +1737,10 @@ def _format_failed_rows(
17391737

17401738
return {"status": status, "results": results, "errors": errors}
17411739
elif res["dataRowsForGlobalKeysResult"]["jobStatus"] == "FAILED":
1742-
raise lbox.exceptions.LabelboxError(
1743-
"Job dataRowsForGlobalKeys failed."
1744-
)
1740+
raise LabelboxError("Job dataRowsForGlobalKeys failed.")
17451741
current_time = time.time()
17461742
if current_time - start_time > timeout_seconds:
1747-
raise lbox.exceptions.TimeoutError(
1743+
raise TimeoutError(
17481744
"Timed out waiting for get_data_rows_for_global_keys job to complete."
17491745
)
17501746
time.sleep(sleep_time)
@@ -1843,12 +1839,10 @@ def _format_failed_rows(
18431839

18441840
return {"status": status, "results": results, "errors": errors}
18451841
elif res["clearGlobalKeysResult"]["jobStatus"] == "FAILED":
1846-
raise lbox.exceptions.LabelboxError(
1847-
"Job clearGlobalKeys failed."
1848-
)
1842+
raise LabelboxError("Job clearGlobalKeys failed.")
18491843
current_time = time.time()
18501844
if current_time - start_time > timeout_seconds:
1851-
raise lbox.exceptions.TimeoutError(
1845+
raise TimeoutError(
18521846
"Timed out waiting for clear_global_keys job to complete."
18531847
)
18541848
time.sleep(sleep_time)
@@ -1913,14 +1907,14 @@ def is_feature_schema_archived(
19131907
if filtered_feature_schema_nodes:
19141908
return bool(filtered_feature_schema_nodes[0]["archived"])
19151909
else:
1916-
raise lbox.exceptions.LabelboxError(
1910+
raise LabelboxError(
19171911
"The specified feature schema was not in the ontology."
19181912
)
19191913

19201914
elif response.status_code == 404:
1921-
raise lbox.exceptions.ResourceNotFoundError(Ontology, ontology_id)
1915+
raise ResourceNotFoundError(Ontology, ontology_id)
19221916
else:
1923-
raise lbox.exceptions.LabelboxError(
1917+
raise LabelboxError(
19241918
"Failed to get the feature schema archived status."
19251919
)
19261920

@@ -1947,7 +1941,7 @@ def get_model_slice(self, slice_id) -> ModelSlice:
19471941
"""
19481942
res = self.execute(query_str, {"id": slice_id})
19491943
if res is None or res["getSavedQuery"] is None:
1950-
raise lbox.exceptions.ResourceNotFoundError(ModelSlice, slice_id)
1944+
raise ResourceNotFoundError(ModelSlice, slice_id)
19511945

19521946
return Entity.ModelSlice(self, res["getSavedQuery"])
19531947

@@ -1994,7 +1988,7 @@ def delete_feature_schema_from_ontology(
19941988
result.deleted = bool(response_json["deleted"])
19951989
return result
19961990
else:
1997-
raise lbox.exceptions.LabelboxError(
1991+
raise LabelboxError(
19981992
"Failed to remove feature schema from ontology, message: "
19991993
+ str(response.json()["message"])
20001994
)
@@ -2022,11 +2016,9 @@ def unarchive_feature_schema_node(
20222016
response = self.connection.patch(ontology_endpoint)
20232017
if response.status_code == requests.codes.ok:
20242018
if not bool(response.json()["unarchived"]):
2025-
raise lbox.exceptions.LabelboxError(
2026-
"Failed unarchive the feature schema."
2027-
)
2019+
raise LabelboxError("Failed unarchive the feature schema.")
20282020
else:
2029-
raise lbox.exceptions.LabelboxError(
2021+
raise LabelboxError(
20302022
"Failed unarchive the feature schema node, message: ",
20312023
response.text,
20322024
)
@@ -2255,7 +2247,7 @@ def get_embedding_by_name(self, name: str) -> Embedding:
22552247
for e in embeddings:
22562248
if e.name == name:
22572249
return e
2258-
raise lbox.exceptions.ResourceNotFoundError(Embedding, dict(name=name))
2250+
raise ResourceNotFoundError(Embedding, dict(name=name))
22592251

22602252
def upsert_label_feedback(
22612253
self, label_id: str, feedback: str, scores: Dict[str, float]
@@ -2378,7 +2370,7 @@ def get_task_by_id(self, task_id: str) -> Union[Task, DataUpsertTask]:
23782370
result = self.execute(query, {"userId": user.uid, "taskId": task_id})
23792371
data = result.get("user", {}).get("createdTasks", [])
23802372
if not data:
2381-
raise lbox.exceptions.ResourceNotFoundError(
2373+
raise ResourceNotFoundError(
23822374
message=f"The task {task_id} does not exist."
23832375
)
23842376
task_data = data[0]

libs/labelbox/src/labelbox/data/annotation_types/geometry/rectangle.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class RectangleUnit(Enum):
9494
INCHES = "INCHES"
9595
PIXELS = "PIXELS"
9696
POINTS = "POINTS"
97+
PERCENT = "PERCENT"
9798

9899

99100
class DocumentRectangle(Rectangle):

0 commit comments

Comments
 (0)