Fix Error: "Object of type datetime is not JSON serializable" in Python

This article summarizes how to fix the following error that occurs when using Python's json module for JSON conversion:

"Object of type datetime is not JSON serializable"

Introduction

The json module allows handling JSON in Python. However, data types not natively supported by JSON cannot be directly converted.

While trying to convert data containing datetime objects to JSON, I encountered the following error:

"Object of type datetime is not JSON serializable"

This article outlines the solutions.

Note: This article was translated from my original post.

Background

Look at the situation in which this error occurred.

Using AWS Python SDK Boto3's describe_instances(), I retrieved EC2 instance information as a dictionary and attempted to convert it to JSON using json.dumps():

import json
import boto3

ec2_client = boto3.client('ec2')
response = ec2_client.describe_instances()
    
json.dumps(response)

This resulted in the following error:

"errorMessage": "Object of type datetime is not JSON serializable",
"errorType": "TypeError",

This error occurs because the dictionary passed to json.dumps() contains a datetime object, which cannot be directly converted to JSON.

Below, I introduce two solutions to this problem.

Solutions

Preliminary: The default Parameter

First, briefly explain the default parameter of json.dumps(). (Both solutions use this parameter.)

According to the official documentation:

If specified, default should be a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If not specified, TypeError is raised.

This means you can specify a function to handle objects that cannot be serialized by default.

By providing an appropriate function to default, we can convert unsupported data types into a format that can be serialized.

Solution 1: Convert to String

The simplest workaround is to pass str to the default parameter:

json.dumps(response, default=str)

This will convert all unsupported objects to strings with the str() function.

Although this is a quick and rough solution, it easily avoids the error.

Solution 2: Custom Conversion

A more structured approach is to define a custom function for conversion.

For example, the following function json_serial() converts datetime and date objects to ISO format:

from datetime import date, datetime

def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError(f'Type {obj} not serializable')

json.dumps(response, default=json_serial)

This approach allows specifying how various data types should be converted.

If there are no specific reasons to use the first method, this approach is recommended.

Conclusion

This article covered how to handle unsupported objects when converting to JSON.

Once understood, the solution is straightforward, but it took some trial and error to get there.

I hope this helps others facing the same issue.

References