Skip to content

Commit 5b61ad9

Browse files
authored
[AL-5784] Remove backports because it failed to installed on Windows (#1119)
2 parents 19c670f + 2924dc9 commit 5b61ad9

File tree

8 files changed

+51
-28
lines changed

8 files changed

+51
-28
lines changed

labelbox/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
name = "labelbox"
22
__version__ = "3.47.1"
33

4-
from backports.datetime_fromisoformat import MonkeyPatch
5-
6-
MonkeyPatch.patch_fromisoformat()
7-
84
from labelbox.client import Client
95
from labelbox.schema.project import Project
106
from labelbox.schema.model import Model

labelbox/schema/data_row_metadata.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pydantic import BaseModel, conlist, constr
99

1010
from labelbox.schema.ontology import SchemaId
11-
from labelbox.utils import _CamelCaseMixin, format_iso_datetime
11+
from labelbox.utils import _CamelCaseMixin, format_iso_datetime, format_iso_from_string
1212

1313

1414
class DataRowMetadataKind(Enum):
@@ -466,7 +466,7 @@ def parse_metadata_fields(
466466
value=schema.uid)
467467
elif schema.kind == DataRowMetadataKind.datetime:
468468
field = DataRowMetadataField(schema_id=schema.uid,
469-
value=datetime.fromisoformat(
469+
value=format_iso_from_string(
470470
f["value"]))
471471
else:
472472
field = DataRowMetadataField(schema_id=schema.uid,
@@ -838,7 +838,7 @@ def _validate_parse_number(
838838
def _validate_parse_datetime(
839839
field: DataRowMetadataField) -> List[Dict[str, Union[SchemaId, str]]]:
840840
if isinstance(field.value, str):
841-
field.value = datetime.fromisoformat(field.value)
841+
field.value = format_iso_from_string(field.value)
842842
elif not isinstance(field.value, datetime):
843843
raise TypeError(
844844
f"Value for datetime fields must be either a string or datetime object. Found {type(field.value)}"

labelbox/utils.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import datetime
22
import re
3+
4+
from dateutil.tz import tzoffset
5+
from dateutil.parser import isoparse as dateutil_parse
6+
from dateutil.utils import default_tzinfo
7+
38
from urllib.parse import urlparse
49
from pydantic import BaseModel
510

611
UPPERCASE_COMPONENTS = ['uri', 'rgb']
712
ISO_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
13+
DFLT_TZ = tzoffset("UTC", 0000)
814

915

1016
def _convert(s, sep, title):
@@ -80,4 +86,14 @@ def format_iso_datetime(dt: datetime.datetime) -> str:
8086
Formats a datetime object into the format: 2011-11-04T00:05:23Z
8187
Note that datetime.isoformat() outputs 2011-11-04T00:05:23+00:00
8288
"""
83-
return dt.strftime(ISO_DATETIME_FORMAT)
89+
return dt.astimezone(datetime.timezone.utc).strftime(ISO_DATETIME_FORMAT)
90+
91+
92+
def format_iso_from_string(date_string: str) -> datetime.datetime:
93+
"""
94+
Converts a string even if offset is missing: 2011-11-04T00:05:23Z or 2011-11-04T00:05:23+00:00 or 2011-11-04T00:05:23
95+
to a datetime object.
96+
For missing offsets, the default offset is UTC.
97+
"""
98+
# return datetime.datetime.fromisoformat(date_string)
99+
return default_tzinfo(dateutil_parse(date_string), DFLT_TZ)

requirements.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
requests==2.22.0
21
backoff==1.10.0
3-
google-api-core>=1.22.1
4-
pydantic>=1.8,<2.0
5-
shapely
6-
tqdm
72
geojson
3+
google-api-core>=1.22.1
4+
imagesize
5+
nbconvert~=7.2.6
6+
nbformat~=5.7.0
87
numpy
9-
PILLOW
108
opencv-python
11-
imagesize
12-
pyproj
9+
PILLOW
10+
pydantic>=1.8,<2.0
1311
pygeotile
14-
typing-extensions==4.5.0
12+
pyproj
1513
pytest-xdist
16-
nbformat~=5.7.0
17-
nbconvert~=7.2.6
14+
python-dateutil>=2.8.2,<2.9.0
15+
requests==2.22.0
16+
shapely
17+
tqdm
1818
typeguard==2.13.3
19-
backports-datetime-fromisoformat~=2.0
19+
typing-extensions==4.5.0

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
packages=setuptools.find_packages(),
2222
install_requires=[
2323
"backoff==1.10.0", "requests>=2.22.0", "google-api-core>=1.22.1",
24-
"pydantic>=1.8,<2.0", "tqdm", "backports-datetime-fromisoformat~=2.0"
24+
"pydantic>=1.8,<2.0", "tqdm", "python-dateutil>=2.8.2,<2.9.0"
2525
],
2626
extras_require={
2727
'data': [
@@ -31,7 +31,6 @@
3131
],
3232
},
3333
classifiers=[
34-
'Development Status :: 3 - Alpha',
3534
'License :: OSI Approved :: Apache Software License',
3635
'Programming Language :: Python :: 3',
3736
'Programming Language :: Python :: 3.7',

tests/integration/test_data_row_metadata.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ def test_delete_schema(mdo):
445445

446446

447447
@pytest.mark.parametrize('datetime_str',
448-
['2011-11-04T00:05:23Z', '2011-05-07T14:34:14+00:00'])
448+
['2011-11-04T00:05:23Z', '2011-11-04T00:05:23+00:00'])
449449
def test_upsert_datarow_date_metadata(data_row, mdo, datetime_str):
450450
metadata = [
451451
DataRowMetadata(data_row_id=data_row.uid,
@@ -458,11 +458,11 @@ def test_upsert_datarow_date_metadata(data_row, mdo, datetime_str):
458458
assert len(errors) == 0
459459

460460
metadata = mdo.bulk_export([data_row.uid])
461-
assert metadata[0].fields[0].value == datetime.fromisoformat(datetime_str)
461+
assert f"{metadata[0].fields[0].value}" == "2011-11-04 00:05:23+00:00"
462462

463463

464464
@pytest.mark.parametrize('datetime_str',
465-
['2011-11-04T00:05:23Z', '2011-05-07T14:34:14+00:00'])
465+
['2011-11-04T00:05:23Z', '2011-11-04T00:05:23+00:00'])
466466
def test_create_data_row_with_metadata(dataset, image_url, datetime_str):
467467
client = dataset.client
468468
assert len(list(dataset.data_rows())) == 0
@@ -475,5 +475,4 @@ def test_create_data_row_with_metadata(dataset, image_url, datetime_str):
475475
metadata_fields=metadata_fields)
476476

477477
retrieved_data_row = client.get_data_row(data_row.uid)
478-
assert retrieved_data_row.metadata[0].value == datetime.fromisoformat(
479-
datetime_str)
478+
assert f"{retrieved_data_row.metadata[0].value}" == "2011-11-04 00:05:23+00:00"

tests/unit/test_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
from labelbox.utils import format_iso_datetime, format_iso_from_string
3+
4+
5+
@pytest.mark.parametrize('datetime_str, expected_datetime_str',
6+
[('2011-11-04T00:05:23Z', '2011-11-04T00:05:23Z'),
7+
('2011-11-04T00:05:23+00:00', '2011-11-04T00:05:23Z'),
8+
('2011-11-04T00:05:23+05:00', '2011-11-03T19:05:23Z'),
9+
('2011-11-04T00:05:23', '2011-11-04T00:05:23Z')])
10+
def test_datetime_parsing(datetime_str, expected_datetime_str):
11+
# NOTE I would normally not take 'expected' using another function from sdk code, but in this case this is exactly the usage in _validate_parse_datetime
12+
assert format_iso_datetime(
13+
format_iso_from_string(datetime_str)) == expected_datetime_str

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# content of: tox.ini , put in same dir as setup.py
22
[tox]
3-
envlist = py36, py37, py38
3+
envlist = py37, py38, py39
44

55
[testenv]
66
# install pytest in the virtualenv where commands will be executed

0 commit comments

Comments
 (0)