https://github.com/brahmlower/json-cerealizer
A tiny library to make json encoding non-serializable objects easier.
https://github.com/brahmlower/json-cerealizer
Last synced: over 1 year ago
JSON representation
A tiny library to make json encoding non-serializable objects easier.
- Host: GitHub
- URL: https://github.com/brahmlower/json-cerealizer
- Owner: brahmlower
- Created: 2017-08-22T04:57:33.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2018-01-29T10:15:29.000Z (over 8 years ago)
- Last Synced: 2025-03-10T21:50:00.622Z (over 1 year ago)
- Language: Python
- Size: 7.81 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# JSON Cerealizer
[](https://api.travis-ci.org/bplower/json-cerealizer.svg?branch=master)
[](https://coveralls.io/github/bplower/json-cerealizer?branch=master)
A simple library for monkey patching the python json library, thereby making it
easier to add serializers for objects that cannot be encoded using the default
JSONEncoder.
## Install
```
pip install json-cerealizer
```
## TL;DR Example
Import the library, run the monkey patch, then register functions to handle
class serialization. Call json.dumps as usual and receive output for your
typically un-encodable objects.
```python
>>> from datetime import datetime
>>> import json
>>> import json_cerealizer
>>>
>>> json_cerealizer.patch()
>>> json_cerealizer.add_serializer(datetime, datetime.isoformat)
>>>
>>> time_dict = {"now": datetime.now()}
>>> json.dumps(time_dict)
'{"now": "2017-08-21T19:57:31.761091"}'
```
## Use Case
The JSON standard can only represent a handful of data types. If you attempt to
serialize a non-standard type, you receive a TypeError. The following is an
example showing that datetime objects cannot be serialized by the default
JSON encoder.
```python
>>> import json
>>> from datetime import datetime
>>>
>>> time_dict = {"now": datetime.now()}
>>> time_dict
{'now': datetime.datetime(2017, 8, 21, 19, 47, 17, 785813)}
>>> json.dumps(time_dict)
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python3.5/json/encoder.py", line 198, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.5/json/encoder.py", line 256, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python3.5/json/encoder.py", line 179, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 8, 21, 19, 47, 17, 785813) is not JSON serializable
```
This issue is easily resolved by subclassing the json.JSONEncoder class,
allowing you to specify how objects should be serialized.
```python
>>> import json
>>> from datetime import datetime
>>>
>>> class MyEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, datetime):
... return obj.isoformat()
...
>>> time_dict = {"now": datetime.now()}
>>> json.dumps(time_dict, cls=MyEncoder)
'{"now": "2017-08-21T19:57:31.761091"}'
```
While this works fine in small cases, it becomes bloated when you want to add
support for several more types. This is where json-cerealizer shines. Here we
monkey patch the json library, then register a function to handle instances of
a particular class. In this case, we are saying instances of `datetime` should
be passed into the function `datetime.isoformat`, which will return a value
that is natively serializable.
```python
>>> from datetime import datetime
>>> import json
>>> import json_cerealizer
>>>
>>> json_cerealizer.patch()
>>> json_cerealizer.add_serializer(datetime, datetime.isoformat)
>>>
>>> time_dict = {"now": datetime.now()}
>>> json.dumps(time_dict)
'{"now": "2017-08-21T19:57:31.761091"}'
```
To solidify our understanding, lets handle a class of our own.
```python
>>> import json
>>> import json_cerealizer
>>>
>>> class Rectangle(object):
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> def rectangle_to_dict(rec):
... return {"x": rec.x, "y": rec.y, "area": rec.x * rec.y}
...
>>> json_cerealizer.patch()
>>> json_cerealizer.add_serializer(Rectangle, rectangle_to_dict)
>>> r = Rectangle(3, 4)
>>> json.dumps(r)
'{"x": 3, "y": 4, "area": 12}'
```