Custom JSON Encoder with python

The json package can encode python objects as strings with the json.JSONEncoder class, and decodes strings into python objects using the json.JSONDecoder class.

Here is an example :

import json

# Convert a dict to a string
json.dumps({"name": "Paul", "age": 24})

# Convert a string to a dict
json.loads('{"name": "Paul", "age": 24}')

By default, these class supports dict, list, tuple, str, int, float, bool and None values. But it’s possible to overload JsonEncoder and JsonDecoder to support Datetime, Decimal or any of your classes.

It can be useful when you want to serialize or deserialize objects. I like to use it when I store mongodb queries (which are json objects) as a string in database.

Let’s start with json encoding.

# extend the json.JSONEncoder class
class JSONEncoder(json.JSONEncoder):

# overload method default
def default(self, obj):

# Match all the types you want to handle in your converter
if isinstance(obj, datetime):
return arrow.get(obj).isoformat()
# Call the default method for other types
return json.JSONEncoder.default(self, obj)

In the above example, we convert datetime objects to isoformat string.

We can also convert Decimal or any other object

elif isinstance(obj, Decimal):
return float(Decimal(obj).quantize(Decimal("0.01"), ROUND_UP))
elif isinstance(obj, MyClass):
return JSONEncoder().encode({
"value1": obj.value_1,
"value2": obj.value_2
})

And let’s do the opposite with JSONDecoder. It’s a little bit different here, we have to pass a method to object_hook in the constructor. We will implement our custom deserializations conditions in this method.

class JSONDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)

def object_hook(self, obj):

# handle your custom classes
if isinstance(obj, dict):
if "value1" in obj and "value2" in obj:
print(obj)
return MyClass(obj.get("value_1"), obj.get("value_2"))

# handling the resolution of nested objects
if isinstance(obj, dict):
for key in list(obj):
obj[key] = self.object_hook(obj[key])

return obj

if isinstance(obj, list):
for i in range(0, len(obj)):
obj[i] = self.object_hook(obj[i])

return obj

# resolving simple strings objects
# dates
if isinstance(obj, str):
obj = self._extract_date(obj)

return obj

We can add two shortcuts for a more readable code.

def json_encode(data):
return JSONEncoder().encode(data)
def json_decode(string):
return JSONDecoder().decode(string)

And use it this way

from JsonEncoder import json_encode, json_decodemy_obj = MyClass("value1", "value2")
json_encode(my_obj)
my_str = '{"name": "Paul", "birthdate": "1992-02-22T00:00:00+00:00", "int_number": 122}'
json_decode(my_str)

You can find all the code, with examples on Github : JsonEncoder.

If you want like to read more about the json package, you can refer to the documentation.

--

--

--

I work at yper. I’m a python developer, learning data science. I’ve made a www.blindfoldchesstactic.com app

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Some Useful Things Should Know About JavaScript

Let’s add a side menu and a toast to an Ionic React application

6 things to consider before you start with React Native

Numerical Value, Reveal Your True Self!

Some CSS Important Concept

How to create a firebase project and write to multiple real-time firebase databases in Angular?

Here Is Why React Native Is The Future Of Mobile Development

A Quick Guides for React Lifecycle

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alexis Gomes

Alexis Gomes

I work at yper. I’m a python developer, learning data science. I’ve made a www.blindfoldchesstactic.com app

More from Medium

Introduction to Automated Testing with Python

MongoDB 101: For beginners (part 2)

A simple API using Flask

Python Unit Testing Start Guide — 1