Skip to main content

Add custom JSON coders and provide functions to set and get the default json coders

Project description

rin-jsonutils

rin-jsonutils is a toolkit that adds custom JSON coders and provides functions to set/get the default JSON coders

Links

Installation

pip install rin-jsonutils

Getting Started

Use the advanced encoder

This package default provides an advanced encoder

import json
import numpy as np
from datetime import datetime
from rin import jsonutils

jsonutils.use_advanced_coders()  # switch to advanced encoder
# jsonutils.use_basic_coders()  # switch back to original json coders 

assert json.dumps({1, 2, 3}) == '[1, 2, 3]'  # built-in set
assert json.dumps(np.arange(6).reshape((2, 3))) == '[[0, 1, 2], [3, 4, 5]]'  # numpy array

assert json.dumps(datetime.fromordinal(1)) == '"0001-01-01T00:00:00"' # datetime

Context in the advanced encoder

Context is a dict store some option for resolvers. For example, setting the 'datetime.format' can affect the behavior when encoding datetime objects.

import json
from rin import jsonutils
from datetime import datetime

jsonutils.use_advanced_coders()
encoder: jsonutils.AdvancedJSONEncoder = jsonutils.get_current_coder().encoder

assert json.dumps(datetime.fromordinal(1)) == '"0001-01-01T00:00:00"' # default format is isoformat
# change the format of the datetime resolver in the encoder 
encoder.context['datetime.format'] = "%Y-%m-%d"
assert json.dumps(datetime.fromordinal(1)) == '"0001-01-01"'

Add Custom resolver to the advanced encoder

You can write your own custom resolver to encode the object.

from typing import Dict, Any
from rin import jsonutils


class MyObject:
    def __init__(self, i: int):
        self.i = i


class MyObjectResolver(jsonutils.IResolver):
    def __init__(self, show_name: bool):
        self.show_name = show_name

    def get_priority(self) -> int:
        return jsonutils.ResolverPriority.MEDIUM

    def initialize(self) -> bool:
        """
        :return: False if initialization failed
        """
        return True

    def resolve(self, o, context: Dict[str, Any]) -> jsonutils.JSONType:
        """
        :raises ResolveError when cannot resolve the object.
                 If you aren't resolves the object, you MUST raise this exception.
        """
        show_name = context.get("my_object.show_name", self.show_name)
        if show_name:
            return {"name": "MyObject", "i": o.i}
        else:
            return {"i": o.i}


encoder = jsonutils.get_coder("advanced").encoder
encoder.add_resolver("my_object", MyObjectResolver(True))  # register the resolver to the encoder

assert encoder.encode(MyObject(1)) == '{"name": "MyObject", "i": 1}'
encoder.context['my_object.show_name'] = False  # change context
assert encoder.encode(MyObject(1)) == '{"i": 1}'

Simpler way to make object JSON serializable

You can write method __json__ for an object. Instead of create a resolver.

from typing import Dict, Any
from rin import jsonutils


class MyObject(jsonutils.JSONSerializable):  # inherit from JSONSerializable is optional.
    show_name: bool = True

    def __init__(self, i: int):
        self.i = i

    def __json__(self, context: Dict[str, Any]) -> jsonutils.JSONType:  # implement this method is required.
        show_name = context.get("my_object.show_name", self.show_name)
        if show_name:
            return {"name": "MyObject", "i": self.i}
        else:
            return {"i": self.i}

encoder = jsonutils.get_coder("advanced").encoder
assert encoder.encode(MyObject(1)) == '{"name": "MyObject", "i": 1}'
encoder.context['my_object.show_name'] = False
assert encoder.encode(MyObject(1)) == '{"i": 1}'

Register custom coders into code switch

import json
from rin import jsonutils


class MyJSONEncoder(json.JSONEncoder):
    ...


class MyJsonDecoder(json.JSONDecoder):
    ...


jsonutils.register_coder("my_coder", MyJSONEncoder(), MyJsonDecoder())
...
jsonutils.use("my_coder")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

rin_jsonutils-1.1.0-py3-none-any.whl (7.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page