Skip to content

Commit

Permalink
Support timestamp and decimal types in sanitize_for_serialization (#24)
Browse files Browse the repository at this point in the history
* Sanitize datetime.time as isoformat

* Sanitize decimal.Decimal as string

* Add sanitize for serialization test

---------

Co-authored-by: enewnham <enewnham@mparticle.com>
  • Loading branch information
enewnham and enewnham-mp authored May 3, 2023
1 parent 2f9e807 commit ca4cbfc
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
10 changes: 8 additions & 2 deletions mparticle/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

from datetime import datetime
from datetime import date
from datetime import time
from decimal import Decimal

# python 2 and python 3 compatibility library
from six import iteritems
Expand Down Expand Up @@ -203,8 +205,10 @@ def sanitize_for_serialization(obj):
If obj is None, return None.
If obj is str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date
If obj is datetime.datetime, datetime.date, datetime.time
convert to string in iso8601 format.
if obj is decimal.Decimal
convert to string
If obj is list, sanitize each element in the list.
If obj is dict, return the dict.
If obj is swagger model, return the properties dict.
Expand All @@ -220,8 +224,10 @@ def sanitize_for_serialization(obj):
elif isinstance(obj, list):
return [ApiClient.sanitize_for_serialization(sub_obj)
for sub_obj in obj]
elif isinstance(obj, (datetime, date)):
elif isinstance(obj, (datetime, date, time)):
return obj.isoformat()
elif isinstance(obj, Decimal):
return str(obj)
else:
if isinstance(obj, dict):
obj_dict = obj
Expand Down
49 changes: 49 additions & 0 deletions test/test_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

from __future__ import absolute_import

import datetime
import decimal
import json
import os
import sys
import unittest
Expand All @@ -46,6 +49,52 @@ def test_validate_custom_attributes(self):
self.assertFalse(ApiClient.validate_attribute_bag_values({"foo":"bar", "foo-2":5, "foo-3":[3.14], "foo-4":None}))
pass

def test_sanitize_for_serialization(self):
obj = {
"a_string": "foo",
"a_int": 123,
"a_float": 1.23,
"a_bool": True,
"a_null": None,
"a_date": datetime.date(2023, 5, 3),
"a_datetime": datetime.datetime(2023, 5, 3, 10, 58, 16, 123),
"a_time": datetime.time(10, 58, 16, 123),
"a_decimal": decimal.Decimal('5.2E+7'),
"a_dict": {
"a_string": "foo",
"a_int": 123,
},
"a_array": [
"hello",
"world",
],
}

sanitized_obj = ApiClient.sanitize_for_serialization(obj)
assert sanitized_obj == {
"a_string": "foo",
"a_int": 123,
"a_float": 1.23,
"a_bool": True,
"a_null": None,
"a_date": '2023-05-03',
"a_datetime": '2023-05-03T10:58:16.000123',
"a_time": '10:58:16.000123',
"a_decimal": '5.2E+7',
"a_dict": {
"a_string": "foo",
"a_int": 123,
},
"a_array": [
"hello",
"world",
],
}

serialized_obj = json.dumps(sanitized_obj)
assert serialized_obj == '{"a_string": "foo", "a_int": 123, "a_float": 1.23, "a_bool": true, "a_null": null, ' \
'"a_date": "2023-05-03", "a_datetime": "2023-05-03T10:58:16.000123", "a_time": "10:58:16.000123", ' \
'"a_decimal": "5.2E+7", "a_dict": {"a_string": "foo", "a_int": 123}, "a_array": ["hello", "world"]}'


if __name__ == '__main__':
Expand Down

0 comments on commit ca4cbfc

Please sign in to comment.