Skip to content

Commit 421b596

Browse files
committed
Add a new converter to the default DataConverter for datetimes
1 parent 1b136a0 commit 421b596

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

temporalio/converter.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,35 @@ def from_payload(
485485
raise RuntimeError("Failed parsing") from err
486486

487487

488+
class ISO8601DatetimePayloadConverter(EncodingPayloadConverter):
489+
"""Converter for 'binary/iso8601' payloads supporting datetime values."""
490+
491+
@property
492+
def encoding(self) -> str:
493+
"""See base class."""
494+
return "binary/iso8601"
495+
496+
def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]:
497+
"""See base class."""
498+
if isinstance(value, datetime):
499+
return temporalio.api.common.v1.Payload(
500+
metadata={"encoding": self.encoding.encode()},
501+
data=value.isoformat().encode(),
502+
)
503+
return None
504+
505+
def from_payload(
506+
self,
507+
payload: temporalio.api.common.v1.Payload,
508+
type_hint: Optional[Type] = None,
509+
) -> Any:
510+
"""See base class."""
511+
try:
512+
return datetime.fromisoformat(payload.data.decode())
513+
except ValueError as err:
514+
raise RuntimeError("Failed parsing ISO8601 datetime") from err
515+
516+
488517
class AdvancedJSONEncoder(json.JSONEncoder):
489518
"""Advanced JSON encoder.
490519
@@ -1132,7 +1161,8 @@ async def decode_failure(
11321161
BinaryPlainPayloadConverter(),
11331162
JSONProtoPayloadConverter(),
11341163
BinaryProtoPayloadConverter(),
1135-
JSONPlainPayloadConverter(),
1164+
ISO8601DatetimePayloadConverter(),
1165+
JSONPlainPayloadConverter(), # JSON Plain needs to remain in last because it throws on unknown types
11361166
)
11371167

11381168
DataConverter.default = DataConverter()

tests/test_converter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ async def assert_payload(
178178
type_hint=RawValue,
179179
)
180180

181+
await assert_payload(
182+
datetime(2020, 1, 1, 1, 1, 1), "binary/iso8601", "2020-01-01T01:01:01"
183+
)
184+
await assert_payload(
185+
datetime(2020, 1, 1, 1, 1, 1, 1), "binary/iso8601", "2020-01-01T01:01:01.000001"
186+
)
187+
181188

182189
def test_binary_proto():
183190
# We have to test this separately because by default it never encodes

0 commit comments

Comments
 (0)