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 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) -> jsonutils.JSONType:  # implement this method is required.
        if self.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}'
MyObject.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

If you're not sure about the file name format, learn more about wheel file names.

rin_jsonutils-1.0.2-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file rin_jsonutils-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: rin_jsonutils-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.12

File hashes

Hashes for rin_jsonutils-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ed8a9382d362f904083ffc43182c03302472664bba6197a9988bc5a66fad1988
MD5 ba3c3fd5cef21d50c30bf18af931231f
BLAKE2b-256 14e0cb8756e2d3ad9a16315a85753c759afa4ef75ecc50c1406add3a6165e61e

See more details on using hashes here.

Supported by

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