diff --git a/pillarsdk/utils.py b/pillarsdk/utils.py index 57d6b93..396bd97 100644 --- a/pillarsdk/utils.py +++ b/pillarsdk/utils.py @@ -20,6 +20,22 @@ else: text_type = unicode +class PillarJSONEncoder(json.JSONEncoder): + """JSON encoder with support for Pillar resources.""" + + def default(self, obj): + # Late import to prevent circular references. + from .resource import Resource + + if isinstance(obj, datetime): + return obj.isoformat(' ') + if isinstance(obj, Resource): + return obj.to_dict() + + # Let the base class default method raise the TypeError + return json.JSONEncoder.default(self, obj) + + def join_url(url, *paths): """ Joins individual URL strings together, and returns a single string. diff --git a/tests/test_utils.py b/tests/test_utils.py index 4b8542f..766ff21 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,7 @@ # -*- encoding: utf-8 -*- +import datetime +import json import unittest try: @@ -9,6 +11,7 @@ except ImportError: from urllib import quote_plus from pillarsdk import utils +from pillarsdk.resource import Resource class PillarUtilsTests(unittest.TestCase): @@ -59,3 +62,10 @@ class PillarUtilsTests(unittest.TestCase): self.assertEqual({'foo': 'bar'}, utils.merge_dict(None, {'foo': 'bar'})) self.assertEqual({}, utils.merge_dict(None, None)) + + def test_json_encoding(self): + resource = Resource() + resource['datetime'] = datetime.datetime(2016, 3, 22, 12, 35, 16) + + as_json = json.dumps(resource, cls=utils.PillarJSONEncoder, sort_keys=True) + self.assertEqual('{"datetime": "2016-03-22 12:35:16"}', as_json)