Skip to content

Commit dab5d9e

Browse files
authored
Merge pull request #113 from Labelbox/develop
repair-tests
2 parents 97b4a5a + eded4ee commit dab5d9e

File tree

11 files changed

+51
-45
lines changed

11 files changed

+51
-45
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
env:
6868
# make sure to tell tox to use these environs in tox.ini
6969
#
70-
# randall@labelbox.com
70+
# msokoloff+prod-python@labelbox.com
7171
LABELBOX_TEST_API_KEY_PROD: ${{ secrets.LABELBOX_API_KEY }}
7272

7373

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
* Comparing a Labelbox object (e.g. Project) to None doesn't raise an exception
77
* Adding `order_by` to `Project.labels` doesn't raise an exception
88

9-
## Version 2.4.10 (2021-01-05)
9+
## Version 2.4.11 (2021-03-07)
10+
### Fix
11+
* Increase query timeout
12+
* Retry 502s
13+
14+
## Version 2.4.10 (2021-02-05)
1015
### Added
1116
* SDK version added to request headers
1217

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
FROM python:3.6
1+
FROM python:3.7
2+
3+
RUN pip install pytest
24

35
COPY . /usr/src/labelbox
46
WORKDIR /usr/src/labelbox
57

6-
RUN pip install pytest
78
RUN python setup.py install

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ build:
55
test-staging: build
66
docker run -it -v ${PWD}:/usr/src -w /usr/src \
77
-e LABELBOX_TEST_ENVIRON="staging" \
8-
-e LABELBOX_TEST_API_KEY_STAGING="<REPLACE>" \
8+
-e LABELBOX_TEST_API_KEY_STAGING=${LABELBOX_TEST_API_KEY_STAGING} \
99
local/labelbox-python:test pytest $(PATH_TO_TEST) -svvx
1010

1111
test-prod: build
1212
docker run -it -v ${PWD}:/usr/src -w /usr/src \
1313
-e LABELBOX_TEST_ENVIRON="prod" \
14-
-e LABELBOX_TEST_API_KEY_PROD="<REPLACE>" \
14+
-e LABELBOX_TEST_API_KEY_PROD=${LABELBOX_TEST_API_KEY_PROD} \
1515
local/labelbox-python:test pytest $(PATH_TO_TEST) -svvx

labelbox/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "labelbox"
2-
__version__ = "2.4.10"
2+
__version__ = "2.4.11"
33

44
from labelbox.client import Client
55
from labelbox.schema.bulk_import_request import BulkImportRequest
@@ -15,4 +15,4 @@
1515
from labelbox.schema.asset_metadata import AssetMetadata
1616
from labelbox.schema.webhook import Webhook
1717
from labelbox.schema.prediction import Prediction, PredictionModel
18-
from labelbox.schema.ontology import Ontology
18+
from labelbox.schema.ontology import Ontology

labelbox/client.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ def __init__(self,
7171
'X-User-Agent': f'python-sdk {SDK_VERSION}'
7272
}
7373

74+
#TODO: Add exponential backoff so we don'tt overwhelm the api
7475
@retry.Retry(predicate=retry.if_exception_type(
7576
labelbox.exceptions.InternalServerError))
76-
def execute(self, query, params=None, timeout=10.0):
77+
def execute(self, query, params=None, timeout=30.0):
7778
""" Sends a request to the server for the execution of the
7879
given query.
7980
@@ -126,25 +127,23 @@ def convert_value(value):
126127
logger.debug("Response: %s", response.text)
127128
except requests.exceptions.Timeout as e:
128129
raise labelbox.exceptions.TimeoutError(str(e))
129-
130130
except requests.exceptions.RequestException as e:
131131
logger.error("Unknown error: %s", str(e))
132132
raise labelbox.exceptions.NetworkError(e)
133-
134133
except Exception as e:
135134
raise labelbox.exceptions.LabelboxError(
136135
"Unknown error during Client.query(): " + str(e), e)
137-
138136
try:
139137
r_json = response.json()
140138
except:
141-
error_502 = '502 Bad Gateway'
142-
if error_502 in response.text:
143-
raise labelbox.exceptions.InternalServerError(error_502)
144139
if "upstream connect error or disconnect/reset before headers" \
145140
in response.text:
146141
raise labelbox.exceptions.InternalServerError(
147142
"Connection reset")
143+
elif response.status_code == 502:
144+
error_502 = '502 Bad Gateway'
145+
raise labelbox.exceptions.InternalServerError(error_502)
146+
148147
raise labelbox.exceptions.LabelboxError(
149148
"Failed to parse response as JSON: %s" % response.text)
150149

@@ -189,6 +188,7 @@ def check_errors(keywords, *path):
189188

190189
# Check if API limit was exceeded
191190
response_msg = r_json.get("message", "")
191+
192192
if response_msg.startswith("You have exceeded"):
193193
raise labelbox.exceptions.ApiLimitError(response_msg)
194194

@@ -292,7 +292,6 @@ def upload_data(self,
292292
"1": (filename, content, content_type) if
293293
(filename and content_type) else content
294294
})
295-
296295
try:
297296
file_data = response.json().get("data", None)
298297
except ValueError as e: # response is not valid JSON

labelbox/schema/ontology.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def from_json(cls, json_dict):
6666
class Ontology(DbObject):
6767
"""An ontology specifies which tools and classifications are available
6868
to a project. This is read only for now.
69-
7069
Attributes:
7170
name (str)
7271
description (str)
@@ -75,7 +74,6 @@ class Ontology(DbObject):
7574
normalized (json)
7675
object_schema_count (int)
7776
classification_schema_count (int)
78-
7977
projects (Relationship): `ToMany` relationship to Project
8078
created_by (Relationship): `ToOne` relationship to User
8179
"""

tests/integration/test_client_errors.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from multiprocessing.dummy import Pool
22
import os
33
import time
4-
54
import pytest
65

76
from labelbox import Project, Dataset, User
@@ -111,21 +110,24 @@ def test_invalid_attribute_error(client, rand_gen):
111110
project.delete()
112111

113112

114-
@pytest.mark.slow
115-
# TODO improve consistency
116-
@pytest.mark.skip(reason="Inconsistent test")
117-
def test_api_limit_error(client, rand_gen):
118-
project_id = client.create_project(name=rand_gen(str)).uid
113+
@pytest.mark.skip("timeouts cause failure before rate limit")
114+
def test_api_limit_error(client):
119115

120116
def get(arg):
121117
try:
122-
return client.get_project(project_id)
118+
return client.get_user()
123119
except labelbox.exceptions.ApiLimitError as e:
124120
return e
125121

126-
with Pool(300) as pool:
127-
results = pool.map(get, list(range(2000)))
122+
#Rate limited at 1500 + buffer
123+
n = 1600
124+
#max of 30 concurrency before the service becomes unavailable
125+
with Pool(30) as pool:
126+
start = time.time()
127+
results = list(pool.imap(get, range(n)), total=n)
128+
elapsed = time.time() - start
128129

130+
assert elapsed < 60, "Didn't finish fast enough"
129131
assert labelbox.exceptions.ApiLimitError in {type(r) for r in results}
130132

131133
# Sleep at the end of this test to allow other tests to execute.

tests/integration/test_data_upload.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
import requests
33

44

5-
# TODO it seems that at some point Google Storage (gs prefix) started being
6-
# returned, and we can't just download those with requests. Fix this
7-
@pytest.mark.skip
8-
def test_file_upload(client, rand_gen):
5+
def test_file_upload(client, rand_gen, dataset):
96
data = rand_gen(str)
10-
url = client.upload_data(data.encode())
11-
assert requests.get(url).text == data
7+
uri = client.upload_data(data.encode())
8+
data_row = dataset.create_data_row(row_data=uri)
9+
assert requests.get(data_row.row_data).text == data

tests/integration/test_label.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from labelbox.schema.labeling_frontend import LabelingFrontend
12
import time
23

34
import pytest
@@ -30,18 +31,22 @@ def test_labels(label_pack):
3031
assert list(data_row.labels()) == []
3132

3233

33-
# TODO check if this is supported or not
34-
@pytest.mark.skip
35-
def test_label_export(label_pack):
34+
def test_label_export(client, label_pack):
3635
project, dataset, data_row, label = label_pack
37-
project.create_label(data_row=data_row, label="l2")
38-
39-
exported_labels_url = project.export_labels(5)
36+
#Old create_label works even with projects setup using the new editor.
37+
#It will appear in the export, just not in the new editor
38+
project.create_label(data_row=data_row, label="export_label")
39+
#Project has to be setup for export to be possible
40+
editor = list(
41+
client.get_labeling_frontends(
42+
where=LabelingFrontend.name == "editor"))[0]
43+
empty_ontology = {"tools": [], "classifications": []}
44+
project.setup(editor, empty_ontology)
45+
exported_labels_url = project.export_labels()
4046
assert exported_labels_url is not None
41-
if exported_labels_url is not None:
42-
exported_labels = requests.get(exported_labels_url)
43-
# TODO check content
44-
assert False
47+
exported_labels = requests.get(exported_labels_url)
48+
labels = [example['Label'] for example in exported_labels.json()]
49+
assert 'export_label' in labels
4550

4651

4752
def test_label_update(label_pack):

tests/integration/test_webhook.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
from labelbox import Webhook
44

55

6-
# TODO investigate why this fails
7-
@pytest.mark.skip
86
def test_webhook_create_update(project, rand_gen):
97
client = project.client
108
url = "https:/" + rand_gen(str)

0 commit comments

Comments
 (0)