Skip to content

Commit 12abdeb

Browse files
committed
Devices: Added support for previous versions of Python on datetime conversions
1 parent 48de78f commit 12abdeb

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

shellhub/models/device.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,25 @@ def __init__(self, api_object: shellhub.models.base.ShellHub, device_json): # t
7272

7373
@staticmethod
7474
def _safe_isoformat_to_datetime(date_string: str) -> datetime:
75+
# Replace "Z" with "+00:00" to indicate UTC in a format compatible with Python 3.7-3.10.
76+
if date_string.endswith("Z"):
77+
date_string = date_string[:-1] + "+00:00"
7578
try:
79+
# Direct conversion using fromisoformat
7680
return datetime.fromisoformat(date_string)
77-
except ValueError as e:
78-
raise ShellHubApiError(f"Invalid date string: {date_string} (Couldn't convert to datetime)") from e
81+
except ValueError:
82+
try:
83+
# For Python versions that do not handle offset-aware datetimes well in fromisoformat
84+
# This part is more of a catch-all to ensure even non-standard or unexpected formats
85+
# might be parsed, but primarily, the first attempt should work for ISO 8601 formats.
86+
# Note: strptime might not be necessary if fromisoformat works after the 'Z' to '+00:00' replacement,
87+
# but it's here as an example if further customization is needed.
88+
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S%z")
89+
except ValueError as e:
90+
# If the first attempt fails due to the format not being exactly ISO 8601 after 'Z' replacement,
91+
# this additional attempt can catch other variations. This might not be strictly necessary,
92+
# depending on your input formats.
93+
raise ShellHubApiError(f"Invalid date string: {date_string} (Couldn't convert to datetime)") from e
7994

8095
def delete(self) -> bool:
8196
"""

tests/test_devices.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime
2+
from datetime import timezone
23

34
import pytest
45

@@ -106,6 +107,7 @@ def test_get_device(self, shellhub, requests_mock):
106107
}
107108
requests_mock.get(f"{MOCKED_DOMAIN_URL}/api/devices/1", json=mock_response)
108109
device = shellhub.get_device("1")
110+
origin_time = datetime(1970, 1, 1, 0, 0, tzinfo=timezone.utc)
109111

110112
assert device.uid == "1"
111113
assert device.name == "default"
@@ -120,12 +122,12 @@ def test_get_device(self, shellhub, requests_mock):
120122
== "-----BEGIN RSA PUBLIC KEY-----\nxxx\nxxx\nxxx\nxxx\nxxx\nxxx\n-----END RSA PUBLIC KEY-----\n"
121123
)
122124
assert device.tenant_id == "1"
123-
assert device.last_seen == datetime.fromisoformat("1970-01-01T00:00:00Z")
125+
assert device.last_seen == origin_time
124126
assert device.online
125127
assert device.namespace == "dev"
126128
assert device.status == "accepted"
127-
assert device.status_updated_at == datetime.fromisoformat("1970-01-01T00:00:00Z")
128-
assert device.created_at == datetime.fromisoformat("1970-01-01T00:00:00Z")
129+
assert device.status_updated_at == origin_time
130+
assert device.created_at == origin_time
129131
assert device.remote_addr == "0.0.0.0"
130132
assert device.tags == []
131133
assert not device.acceptable

0 commit comments

Comments
 (0)