JSON Encoder
json-encoder is a Python library (version 0.4.4) designed to simplify JSON serialization by using the `singledispatch` pattern, eliminating the need for extensive `json.dumps(data, cls=MyJSONEncoder)` calls. It offers default serialization for common types like `time`, `date`, `datetime`, `UUID`, and `Decimal`, and can parse JSON float numbers into `Decimal` objects to mitigate Python float precision issues. The library is designed to be largely independent of specific underlying JSON implementations (e.g., `json`, `simplejson`, `ujson`), allowing users to choose their preferred backend.
Common errors
-
TypeError: Object of type <YourType> is not JSON serializable
cause You are trying to serialize an object whose type (`<YourType>`) does not have a registered serialization function with `json-encoder`.fixRegister a serialization function for `YourType` using the `@json_encoder.register(<YourType>)` decorator. For example: `from json_encoder.encoder import json_encoder` `@json_encoder.register(YourType)` `def encode_your_type(obj: YourType):` `return {'value': str(obj)}` -
json.dumps is not using my preferred JSON library (e.g., ujson or simplejson).
cause By default, `json-encoder` attempts to use `simplejson` if available, then falls back to the standard `json` library. Your preferred library might not be installed or explicitly configured.fixEnsure your desired JSON library (e.g., `ujson`) is installed (`pip install ujson`), then explicitly configure `json-encoder` to use it: `from json_encoder import use_json_library` `import ujson # or simplejson` `use_json_library(ujson)`
Warnings
- gotcha The `json-encoder` library uses a `singledispatch` pattern for serialization, which differs from the standard library's `json.JSONEncoder` subclassing approach. Users accustomed to `json.dumps(obj, cls=MyEncoder)` should instead register handlers using `@json_encoder.register`.
- deprecated The project's PyPI metadata lists its 'Development Status' as '3 - Alpha' and the last release was in September 2016. While functional for its intended purpose, it may not be actively maintained or receive updates for new Python features or critical bug fixes.
- gotcha The PyPI classifiers explicitly list support for Python 2.7 and 3.5. While it might work on newer Python versions, explicit compatibility beyond 3.5 is not guaranteed or tested by the project maintainers due to its maintenance status.
Install
-
pip install json-encoder
Imports
- json
from json_encoder import json
- use_json_library
from json_encoder import use_json_library
- json_encoder.register
from json_encoder.encoder import json_encoder @json_encoder.register(MyCustomType)
Quickstart
from datetime import datetime, date
from decimal import Decimal
from fractions import Fraction
from uuid import UUID
from json_encoder import json
from json_encoder import use_json_library
from json_encoder.encoder import json_encoder
# Optionally configure a specific JSON backend (e.g., ujson if installed)
try:
import ujson
use_json_library(ujson)
print("Using ujson backend")
except ImportError:
print("ujson not found, using default json backend")
# 1. Basic usage with built-in enhanced types
data = {
'now': datetime.now(),
'today': date.today(),
'money': Decimal('123.45'),
'id': UUID('12345678-1234-5678-1234-567812345678'),
'value': 1.23 # will be handled as Decimal due to float parsing
}
encoded_data = json.dumps(data, indent=2)
print("\nEncoded data with default handlers:")
print(encoded_data)
# 2. Registering a custom type handler using singledispatch
class MyCustomType:
def __init__(self, name, value):
self.name = name
self.value = value
@json_encoder.register(MyCustomType)
def encode_my_custom_type(obj: MyCustomType):
return {
'custom_name': obj.name,
'custom_value': obj.value,
'type_info': 'MyCustomType serialized'
}
custom_data = {'item': MyCustomType('test', 100)}
encoded_custom_data = json.dumps(custom_data, indent=2)
print("\nEncoded data with custom type handler:")
print(encoded_custom_data)
# 3. Example for Fraction (from PyPI docs)
@json_encoder.register(Fraction)
def encode_fraction(obj: Fraction):
return float(obj)
fraction_data = {'ratio': Fraction(1, 3)}
encoded_fraction = json.dumps(fraction_data, indent=2)
print("\nEncoded Fraction:")
print(encoded_fraction)