Package: rin-jsonutils
rin-jsonutilsrin-jsonutilsis a toolkit that adds custom JSON coders and provides functions to set/get the default JSON codersLinksGitHubPyPIInstallationpipinstallrin-jsonutilsGetting StartedUse the advanced encoderThis package default provides an advanced encoderimportjsonimportnumpyasnpfromdatetimeimportdatetimefromrinimportjsonutilsjsonutils.use_advanced_coders()# switch to advanced encoder# jsonutils.use_basic_coders()  # switch back to original json codersassertjson.dumps({1,2,3})=='[1, 2, 3]'# built-in setassertjson.dumps(np.arange(6).reshape((2,3)))=='[[0, 1, 2], [3, 4, 5]]'# numpy arrayassertjson.dumps(datetime.fromordinal(1))=='"0001-01-01T00:00:00"'# datetimeContext in the advanced encoderContext is a dict store some option for resolvers.
For example, setting the 'datetime.format' can affect the behavior when encoding datetime objects.importjsonfromrinimportjsonutilsfromdatetimeimportdatetimejsonutils.use_advanced_coders()encoder:jsonutils.AdvancedJSONEncoder=jsonutils.get_current_coder().encoderassertjson.dumps(datetime.fromordinal(1))=='"0001-01-01T00:00:00"'# default format is isoformat# change the format of the datetime resolver in the encoderencoder.context['datetime.format']="%Y-%m-%d"assertjson.dumps(datetime.fromordinal(1))=='"0001-01-01"'Add Custom resolver to the advanced encoderYou can write your own custom resolver to encode the object.fromtypingimportDict,AnyfromrinimportjsonutilsclassMyObject:def__init__(self,i:int):self.i=iclassMyObjectResolver(jsonutils.IResolver):def__init__(self,show_name:bool):self.show_name=show_namedefget_priority(self)->int:returnjsonutils.ResolverPriority.MEDIUMdefinitialize(self)->bool:""":return: False if initialization failed"""returnTruedefresolve(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)ifshow_name:return{"name":"MyObject","i":o.i}else:return{"i":o.i}encoder=jsonutils.get_coder("advanced").encoderencoder.add_resolver("my_object",MyObjectResolver(True))# register the resolver to the encoderassertencoder.encode(MyObject(1))=='{"name": "MyObject", "i": 1}'encoder.context['my_object.show_name']=False# change contextassertencoder.encode(MyObject(1))=='{"i": 1}'Simpler way to make object JSON serializableYou can write method__json__for an object. Instead of create a resolver.fromtypingimportDict,AnyfromrinimportjsonutilsclassMyObject(jsonutils.JSONSerializable):# inherit from JSONSerializable is optional.show_name:bool=Truedef__init__(self,i:int):self.i=idef__json__(self,context:Dict[str,Any])->jsonutils.JSONType:# implement this method is required.show_name=context.get("my_object.show_name",self.show_name)ifshow_name:return{"name":"MyObject","i":self.i}else:return{"i":self.i}encoder=jsonutils.get_coder("advanced").encoderassertencoder.encode(MyObject(1))=='{"name": "MyObject", "i": 1}'encoder.context['my_object.show_name']=Falseassertencoder.encode(MyObject(1))=='{"i": 1}'Register custom coders into code switchimportjsonfromrinimportjsonutilsclassMyJSONEncoder(json.JSONEncoder):...classMyJsonDecoder(json.JSONDecoder):...jsonutils.register_coder("my_coder",MyJSONEncoder(),MyJsonDecoder())...jsonutils.use("my_coder")