-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New JSON renderer that handles datetime objects
Based on the default json serializer from pyramid but it formats datetime objects as isoformat(). It special cases datetimes without datetime information and assumes they are in UTC. This commit introduces this seralizer as a new one on top of the default `json` as `json_iso_utc` an starts using it on the assignments API. Short term we'll use this serializer in all dashboard related routes and longer term we'll replace all uses of json by this seralizer and then will make it the default.
- Loading branch information
Showing
5 changed files
with
68 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from datetime import UTC, datetime | ||
|
||
from pyramid.renderers import JSON | ||
|
||
|
||
def json_iso_utc(): | ||
"""Return a JSON renderer that formats dates as `isoformat`. | ||
This renderer assumes datetimes without tz info are in UTC and | ||
includes that in the datetime objects so the resulting string | ||
includes tz information. | ||
""" | ||
|
||
renderer = JSON() | ||
|
||
def _datetime_adapter(obj: datetime, _request) -> str: | ||
if not obj.tzinfo: | ||
obj = obj.replace(tzinfo=UTC) | ||
return obj.isoformat() | ||
|
||
renderer.add_adapter(datetime, _datetime_adapter) | ||
|
||
return renderer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from datetime import UTC, datetime | ||
from unittest.mock import sentinel | ||
from zoneinfo import ZoneInfo | ||
|
||
import pytest | ||
|
||
from lms.renderers import json_iso_utc | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"time,expected", | ||
[ | ||
# No timezone, UTC is assumed | ||
(datetime(2024, 1, 1), "2024-01-01T00:00:00+00:00"), | ||
# UTC, UTC is left intact | ||
(datetime(2024, 1, 1, tzinfo=UTC), "2024-01-01T00:00:00+00:00"), | ||
# Non-UTC, timezone is also left intact | ||
( | ||
datetime(2024, 1, 1, tzinfo=ZoneInfo("Europe/Madrid")), | ||
"2024-01-01T00:00:00+01:00", | ||
), | ||
], | ||
) | ||
def test_json_iso_utc(time, expected): | ||
assert ( | ||
json_iso_utc()(sentinel.info)({"time": time}, {}) | ||
== f"""{{"time": "{expected}"}}""" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters