Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def to_bytes(self, data: Any) -> bytes:
f"Failed to serialize data to JSON: {str(e)}"
)

def _default_handler(self, obj: Any) -> str:
def _default_handler(self, obj: Any) -> float:
"""Handle non-permitive objects."""
if isinstance(obj, datetime):
return obj.isoformat()
return obj.timestamp()
# Raise TypeError for unsupported types
raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")

Expand Down
50 changes: 25 additions & 25 deletions tests/web/serialization_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import pytest
import json
from datetime import datetime
from datetime import datetime, timezone

from aws_durable_execution_sdk_python_testing.exceptions import (
InvalidParameterValueException,
Expand Down Expand Up @@ -404,23 +404,23 @@ def test_serialize_simple_dict():
def test_serialize_datetime():
"""Test serialization of datetime objects."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9, 895000)
now = datetime(2025, 11, 5, 16, 30, 9, 895000, tzinfo=timezone.utc)
data = {"timestamp": now}

result = serializer.to_bytes(data)
expected = b'{"timestamp":"2025-11-05T16:30:09.895000"}'
expected = b'{"timestamp":1762360209.895}'

assert result == expected
assert isinstance(result, bytes)

deserialized = json.loads(result.decode("utf-8"))
assert deserialized["timestamp"] == "2025-11-05T16:30:09.895000"
assert deserialized["timestamp"] == now.timestamp()


def test_serialize_nested_datetime():
"""Test serialization of nested structures with datetime."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9)
now = datetime(2025, 11, 5, 16, 30, 9, tzinfo=timezone.utc)
data = {
"event": "user_login",
"timestamp": now,
Expand All @@ -430,45 +430,45 @@ def test_serialize_nested_datetime():
result = serializer.to_bytes(data)
expected = (
b'{"event":"user_login",'
b'"timestamp":"2025-11-05T16:30:09",'
b'"metadata":{"created_at":"2025-11-05T16:30:09",'
b'"updated_at":"2025-11-05T16:30:09"}}'
b'"timestamp":1762360209.0,'
b'"metadata":{"created_at":1762360209.0,'
b'"updated_at":1762360209.0}}'
)

assert result == expected

deserialized = json.loads(result.decode("utf-8"))
assert deserialized["timestamp"] == now.isoformat()
assert deserialized["metadata"]["created_at"] == now.isoformat()
assert deserialized["timestamp"] == now.timestamp()
assert deserialized["metadata"]["created_at"] == now.timestamp()


def test_serialize_list_with_datetime():
"""Test serialization of list containing datetime."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9)
now = datetime(2025, 11, 5, 16, 30, 9, tzinfo=timezone.utc)
data = {
"events": [{"time": now, "action": "login"}, {"time": now, "action": "logout"}]
}

result = serializer.to_bytes(data)
expected = (
b'{"events":['
b'{"time":"2025-11-05T16:30:09","action":"login"},'
b'{"time":"2025-11-05T16:30:09","action":"logout"}'
b'{"time":1762360209.0,"action":"login"},'
b'{"time":1762360209.0,"action":"logout"}'
b"]}"
)

assert result == expected

deserialized = json.loads(result.decode("utf-8"))
assert deserialized["events"][0]["time"] == now.isoformat()
assert deserialized["events"][1]["time"] == now.isoformat()
assert deserialized["events"][0]["time"] == now.timestamp()
assert deserialized["events"][1]["time"] == now.timestamp()


def test_serialize_mixed_types():
"""Test serialization of mixed data types."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9)
now = datetime(2025, 11, 5, 16, 30, 9, tzinfo=timezone.utc)
data = {
"string": "test",
"number": 42,
Expand All @@ -487,7 +487,7 @@ def test_serialize_mixed_types():
b'"boolean":true,'
b'"null":null,'
b'"list":[1,2,3],'
b'"datetime":"2025-11-05T16:30:09"}'
b'"datetime":1762360209.0}'
)

assert result == expected
Expand All @@ -499,7 +499,7 @@ def test_serialize_mixed_types():
assert deserialized["boolean"] is True
assert deserialized["null"] is None
assert deserialized["list"] == [1, 2, 3]
assert deserialized["datetime"] == now.isoformat()
assert deserialized["datetime"] == now.timestamp()


def test_serialize_returns_bytes():
Expand Down Expand Up @@ -546,35 +546,35 @@ def test_serialize_circular_reference_raises_exception():
def test_serialize_datetime_with_microseconds():
"""Test serialization of datetime with microseconds."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9, 123456)
now = datetime(2025, 11, 5, 16, 30, 9, 123456, tzinfo=timezone.utc)
data = {"timestamp": now}

result = serializer.to_bytes(data)
expected = b'{"timestamp":"2025-11-05T16:30:09.123456"}'
expected = b'{"timestamp":1762360209.123456}'

assert result == expected


def test_serialize_datetime_without_microseconds():
"""Test serialization of datetime without microseconds."""
serializer = JSONSerializer()
now = datetime(2025, 11, 5, 16, 30, 9)
now = datetime(2025, 11, 5, 16, 30, 9, tzinfo=timezone.utc)
data = {"timestamp": now}

result = serializer.to_bytes(data)
expected = b'{"timestamp":"2025-11-05T16:30:09"}'
expected = b'{"timestamp":1762360209.0}'

assert result == expected


def test_serialize_multiple_datetimes():
"""Test multiple datetime objects."""
serializer = JSONSerializer()
dt1 = datetime(2025, 1, 1, 0, 0, 0)
dt2 = datetime(2025, 12, 31, 23, 59, 59)
dt1 = datetime(2025, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
dt2 = datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)

data = {"start": dt1, "end": dt2}
result = serializer.to_bytes(data)
expected = b'{"start":"2025-01-01T00:00:00",' b'"end":"2025-12-31T23:59:59"}'
expected = b'{"start":1735689600.0,"end":1767225599.0}'

assert result == expected