"TypeError: Object of type int64 is not JSON serializable" while trying to convert a nested dict to JSON

Question:

I have a nested dictionary that I am trying to convert to JSON using json.dumps(unserialized_data), indent=2). The dictionary currently looks like this:

{
  "status": "SUCCESS",
  "data": {
    "cal": [
      {
        "year": 2022,
        "month": 8,
        "a": [
          {
            "a_id": 1,
            "b": [
              {
                "abc_id": 1,
                "val": 2342
              }
            ]
          }
        ]
      },
      {
        "year": 2022,
        "month": 9,
        "a": [
          {
            "a_id": 2,
            "b": [
              {
                "abc_id": 3,
                "val": 2342
              }
            ]
          }
        ]
      }
    ]
  }
}

How can I convert all integers of type int64 to int while leaving the structure of the dict and values of any other data type unaffected?

Asked By: Somnath Rakshit

||

Answers:

If the only objects in your dict that aren’t JSON-serializable are all of type int64, you can easily serialize them by making int the default function for converting objects that JSON can’t serialize:

json.dumps(unserialized_data, indent=2, default=int)
Answered By: blhsing

If blhsing’s condition doesn’t apply, you can drill down recursively into the dictionary and cast any np.int64 to int:

def cast_type(container, from_types, to_types):
    if isinstance(container, dict):
        # cast all contents of dictionary 
        return {cast_type(k, from_types, to_types): cast_type(v, from_types, to_types) for k, v in container.items()}
    elif isinstance(container, list):
        # cast all contents of list 
        return [cast_type(item, from_types, to_types) for item in container]
    else:
        for f, t in zip(from_types, to_types):
            # if item is of a type mentioned in from_types,
            # cast it to the corresponding to_types class
            if isinstance(container, f):
                return t(container)
        # None of the above, return without casting 
        return container

from_types and to_types are containers where corresponding elements give the type to convert from, and the type to convert to.
Run your dictionary through this function, then dump it to json:

import numpy as np
import json

d = {
  "str_data": "foo bar",
  "lst": [ np.int64(1000), np.float64(1.234) ],
  "dct": {"foo": "bar", "baz": np.float64(6.789), "boo": np.int64(10)}
}

print(json.dumps(d, indent=2)) # throws error

print(json.dumps(
         cast_type(d, 
             [np.int64, np.float64],
             [int,      float]), 
         indent=2))

Prints the dictionary as JSON:

{
  "str_data": "foo bar",
  "lst": [
    1000,
    1.234
  ],
  "dct": {
    "foo": "bar",
    "baz": 6.789,
    "boo": 10
  }
}

Try online

Answered By: Pranav Hosangadi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.