Skip to content
This repository was archived by the owner on Sep 12, 2024. It is now read-only.

Commit c0634f3

Browse files
author
Norberto Lopes
authored
Merge pull request #220 from duffelhq/nlopes-fix-datetime-payment-requirements
Fix datetime payment requirements
2 parents e1f96f9 + 93e22ee commit c0634f3

File tree

7 files changed

+39
-53
lines changed

7 files changed

+39
-53
lines changed

duffel_api/models/offer.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Optional, Sequence
44

55
from duffel_api.models import Aircraft, Airline, Airport, LoyaltyProgrammeAccount, Place
6-
from duffel_api.utils import get_and_transform
6+
from duffel_api.utils import get_and_transform, parse_datetime
77

88

99
@dataclass
@@ -96,9 +96,7 @@ def from_json(cls, json: dict):
9696
"""Construct a class instance from a JSON response."""
9797
return cls(
9898
payment_required_by=get_and_transform(
99-
json,
100-
"payment_required_by",
101-
lambda value: datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ"),
99+
json, "payment_required_by", parse_datetime
102100
),
103101
price_guarantee_expires_at=get_and_transform(
104102
json,
@@ -499,12 +497,3 @@ def from_json(cls, json: dict):
499497
total_currency=json["total_currency"],
500498
total_emissions_kg=json["total_emissions_kg"],
501499
)
502-
503-
504-
def parse_datetime(value: str) -> datetime:
505-
# There are inconsistent formats used for this field depending on the
506-
# endpoint
507-
if len(value) == 20:
508-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
509-
else:
510-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

duffel_api/models/order_cancellation.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from datetime import datetime
33
from typing import Optional
44

5-
from duffel_api.utils import get_and_transform
5+
from duffel_api.utils import get_and_transform, parse_datetime
66

77

88
@dataclass
@@ -57,12 +57,3 @@ def from_json(cls, json: dict):
5757
confirmed_at=get_and_transform(json, "confirmed_at", parse_datetime),
5858
created_at=datetime.strptime(json["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ"),
5959
)
60-
61-
62-
def parse_datetime(value: str) -> datetime:
63-
# There are inconsistent formats used for this field depending on the
64-
# endpoint
65-
if len(value) == 20:
66-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
67-
else:
68-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

duffel_api/models/order_change.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Optional, Sequence
44

55
from duffel_api.models import Aircraft, Airline, Place
6-
from duffel_api.utils import get_and_transform
6+
from duffel_api.utils import get_and_transform, parse_datetime
77

88

99
@dataclass
@@ -164,12 +164,3 @@ def from_json(cls, json: dict):
164164
created_at=datetime.strptime(json["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ"),
165165
slices=OrderChangeSlices.from_json(json["slices"]),
166166
)
167-
168-
169-
def parse_datetime(value: str) -> datetime:
170-
# There are inconsistent formats used for this field depending on the
171-
# endpoint
172-
if len(value) == 20:
173-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
174-
else:
175-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

duffel_api/models/order_change_offer.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Optional, Sequence
44

55
from duffel_api.models import Aircraft, Airline, Place, Airport
6-
from duffel_api.utils import get_and_transform
6+
from duffel_api.utils import get_and_transform, parse_datetime
77

88

99
@dataclass
@@ -175,12 +175,3 @@ def from_json(cls, json: dict):
175175
expires_at=parse_datetime(json["expires_at"]),
176176
slices=OrderChangeOfferSlices.from_json(json["slices"]),
177177
)
178-
179-
180-
def parse_datetime(value: str) -> datetime:
181-
# There are inconsistent formats used for this field depending on the
182-
# endpoint
183-
if len(value) == 20:
184-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
185-
else:
186-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

duffel_api/models/payment_intent.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Optional, Sequence
44

55
from duffel_api.models import Refund
6-
from duffel_api.utils import get_and_transform
6+
from duffel_api.utils import get_and_transform, parse_datetime
77

88

99
@dataclass
@@ -62,12 +62,3 @@ def from_json(cls, json: dict):
6262
created_at=datetime.strptime(json["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ"),
6363
updated_at=datetime.strptime(json["updated_at"], "%Y-%m-%dT%H:%M:%S.%fZ"),
6464
)
65-
66-
67-
def parse_datetime(value: str) -> datetime:
68-
# There are inconsistent formats used for this field depending on the
69-
# endpoint
70-
if len(value) == 20:
71-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
72-
else:
73-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

duffel_api/utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Assorted auxiliary functions"""
2+
from datetime import datetime
23
from typing import Any
34

45

@@ -25,3 +26,13 @@ def version() -> str:
2526
import pkg_resources
2627

2728
return pkg_resources.require("duffel_api")[0].version
29+
30+
31+
def parse_datetime(value: str) -> datetime:
32+
"""Parse a datetime string regardless of having milliseconds or not"""
33+
# There are inconsistent formats used for the field, therefore we try to accomodate
34+
# instead of making an API breaking change.
35+
if len(value) == 20:
36+
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
37+
else:
38+
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")

tests/test_utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from datetime import datetime
2+
3+
import pytest
4+
5+
from duffel_api.utils import parse_datetime
6+
7+
8+
def test_parse_datetime():
9+
assert parse_datetime("2022-11-02T12:24:52Z") == datetime(2022, 11, 2, 12, 24, 52)
10+
assert parse_datetime("2022-11-02T12:24:52.012Z") == datetime(
11+
2022, 11, 2, 12, 24, 52, 12000
12+
)
13+
with pytest.raises(
14+
ValueError,
15+
match="time data '2022-11-02T-2:24:52Z' does not match format '%Y-%m-%dT%H:%M:%SZ'", # noqa: E501
16+
):
17+
parse_datetime("2022-11-02T-2:24:52Z")
18+
with pytest.raises(
19+
ValueError,
20+
match="time data '2022-11-02T12:24:52' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'", # noqa: E501
21+
):
22+
parse_datetime("2022-11-02T12:24:52")

0 commit comments

Comments
 (0)