Extending Python's JSON Encoder
K Fuquay
Posted on March 11, 2022
I recently ran into a situation where I needed to ensure consistent formatting of datetimes as I serialized a dict to JSON using python’s built-in json library.
The JSON specification does not specify how to handle dates - so it follows that the JSON encoder does not, by default, include any date formatting.
Attempting to convert a dict which includes a datetime to JSON using the default JSON Encoder will raise a TypeError.
import json
from datetime import datetime
obj = {
"name": "test",
"created": datetime.utcnow()
}
obj_default_encoder = json.dumps(obj)
print(obj_default_encoder)
# TypeError: Object of type datetime is not JSON serializable
I was able to achieve the behavior I wanted by defining a class which extends json.JSONEncoder
. In this class I included instructions for handling dates - you could also include other modifications to the default behavior of JSONEncoder. Finally, I passed the custom encoder class to the cls
kwarg of json.dumps
From the python docs:
To use a custom
JSONEncoder
subclass (e.g. one that overrides thedefault()
method to serialize additional types), specify it with the cls kwarg; otherwiseJSONEncoder
is used.
Usage Example
import json
from datetime import datetime
#
# Defining a custom JSON encoder class
#
# Custom class extends json.JSONEncoder
class CustomJSONEncoder(json.JSONEncoder):
# Override default() method
def default(self, obj):
# Datetime to string
if isinstance(obj, datetime):
# Format datetime - `Fri, 21 Aug 2020 17:59:59 GMT`
obj = obj.strftime('%a, %d %b %Y %H:%M:%S GMT')
return obj
# Default behavior for all other types
return super().default(obj)
#
# Using custom class to serialize a dict to JSON
#
obj = {
"name": "test",
"created": datetime.utcnow()
}
obj_custom_encoder = json.dumps(obj, cls=CustomJSONEncoder)
print(obj_custom_encoder)
# {"name": "test", "created": "Fri, 11 Mar 2022 19:11:51 GMT"}
Posted on March 11, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.