schrodinger.models.json module¶
This is a module that extends Python’s standard builtin json module. It offers the following additional features:
JsonableClassMixin
, a mixin that helps with creating serializable classesAn extended JSON encoder that can handle classes derived from
JsonableClassMixin
dump
anddumps
functions that use the extended encoder by default.
- exception schrodinger.models.json.JSONEncodeError¶
Bases:
ValueError
- class schrodinger.models.json.AttributableType(iterable=(), /)¶
Bases:
list
- class schrodinger.models.json.JsonableClassMixin¶
Bases:
object
A mixin that aids in making a class Jsonable. Users must define
toJsonImplementation(self)
andfromJsonImplementation(cls, json_dict)
. For example:class Person(JsonableClassMixin, object): def __init__(self, full_name, age): self.full_name = full_name self.age = age def toJsonImplementation(self): return {'full_name':self.full_name, 'age':self.age} @classmethod def fromJsonImplementation(cls, json_dict): return cls(json_dict['full_name'], json_dict['age'])
Now
dump
anddumps
can encodePerson
:# Encode to a file abe = Person('Abraham Lincoln', 208) with open('abe.json', 'w') as out_file: json.dump(abe, out_file) # Encode to a string abe_json_string = json.dumps(abe)
If you want to decode the json string or file, you’ll have to use
loads
orload
and then feed in the result to your class’ public class methodfromJson()
:# Loading an object from a json file with open('abe.json', 'r') as in_file: abe = json.load(in_file, DataClass=Person) # Loading an object from a json string abe = json.loads(abe_json_string, DataClass=Person)
- toJsonImplementation()¶
Abstract method that must be defined by all derived classes. Converts an instance of the derived class into a jsonifiable object.
- Returns
A dict made up of JSON native datatypes or Jsonable objects. See the link below for a table of such types. https://docs.python.org/2/library/json.html#encoders-and-decoders
- classmethod fromJsonImplementation(json_dict)¶
Abstract method that must be defined by all derived classes. Takes in a dictionary and constructs an instance of the derived class.
- Parameters
json_dict (dict) – A dictionary loaded from a JSON string or file.
- Returns
An instance of the derived class.
- Return type
cls
- toJson(_mark_version=True)¶
Create and returns a data structure made up of jsonable items.
- Return type
An instance of one the classes from NATIVE_JSON_DATATYPES
- classmethod fromJson(json_obj)¶
A factory method which constructs a new object from a given dict loaded from a json string or file.
- Parameters
json_obj (dict) – A json-loaded dictionary to create an object from.
- Returns
An instance of this class.
- Return type
cls
- get_version()¶
Method to get the version of a particular object. Defaults to the current version of mmshare. This class can be overridden for custom versioning behavior.
- schrodinger.models.json.adapter(version)¶
This function is a decorator used to define an adapter function that takes in a
json_obj
from an older version of aJsonableClassMixin
and returns it modified such that it can be read in by the version of the class specified by theversion
argument (typically the current version at the time the adapter is written).As a example, imagine we define a simple class:
class Person: # mmshare version: 40000 def __init__(self, full_name): self.full_name = full_name
If, in mmshare version 41000, we split
full_name
into attributesfirst_name
andlast_name
, we could define an adapter like so:class Person: # mmshare version: 41000 def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name @json.adapter(version=41000) def _JsonAdapter(self, json_dict): full_name = json_dict.pop(full_name) fname, lname = full_name.split(' ') json_dict['first_name'] = fname json_dict['last_name'] = lname return json_dict
Note
An adapter function only needs to bring the
json_dict
up-to-date with the class at the time that the adapter is written. The next time the class is changed in a way that breaks json decoding, a new adapter function should be added to the class that takes in the previous adapter’s output and makes it compatible with the current class. In this way the json framework can decode any older version by automatically passing it through the appropriate chain of adapter functions.- Parameters
version (int, str, or list of str or ints) – The data version to which an older
json_dict
will be adapted (typically the current version when the adapter is writte).- Raises
TypeError – if
version
is not an int, str, or list
- schrodinger.models.json.get_json_version_from_file(json_fh)¶
Get the version information from a json file serialized from
JsonableClassMixin
objects. Returns None if no version information is found.
- schrodinger.models.json.get_json_version_from_string(json_str)¶
Get the version information from a json string serialized from
JsonableClassMixin
objects. Returns None if no version information is found.
- schrodinger.models.json.decode(obj, DataClass=None, serializer=None)¶
Decode the
obj
from a json structure to the original object that encoded it. This is done using the following methods in order of priority:Detecting whether the jsoned object originally implemented
JsonableClassMixin
. If it was, decode it into a normal json object and retrieve the version number.- Using
DataClass
if it’s atyping
annotation generic (e.g. typing.List
,typing.Tuple
, etc)
- Using
Using the supplied
serializer
Inferring a serializer using
DataClass
- schrodinger.models.json.dumps(obj, serializer=None, **kwargs)¶
A wrapper that automatically encodes objects derived from
JsonableClassMixin
.- Parameters
serializer (jsonable.AbstractJsonSerializer) – A custom serializer to use for serializing the object. This should not be used at the same time as the
DataClass
argument.
If
obj
does not subclassJsonableClassMixin
, then this function will behave exactly like the builtinjson.dumps
.
- schrodinger.models.json.dump(obj, fp, serializer=None, **kwargs)¶
A wrapper that automatically encodes objects derived from
JsonableClassMixin
.- Parameters
serializer (jsonable.AbstractJsonSerializer) – A custom serializer to use for serializing the object. This should not be used at the same time as the
DataClass
argument.
If
obj
does not subclassJsonableClassMixin
, then this function will behave exactly like the builtinjson.dump
.
- schrodinger.models.json.loads(json_str, DataClass=None, serializer=None, **kwargs)¶
A wrapper that automatically decodes json strings serialized from
JsonableClassMixin
objects.- param DataClass
The class of the object that was serialized into
json_str
. The class must either be in JSONABLE_DATATYPES or a type that’s been registered inschrodinger.models.jsoable
.
- Parameters
serializer (jsonable.AbstractJsonSerializer) – A custom serializer to use for deserializing the string. This should not be used at the same time as the
DataClass
argument.
If the json string was not encoded
JsonableClassMixin
object, this function will behave exactly like the builtinjson.loads
.
- schrodinger.models.json.load(fp, DataClass=None, serializer=None, **kwargs)¶
A wrapper that automatically decodes json files serialized from
JsonableClassMixin
objects.- param DataClass
The class of the object that was serialized into
fp
. The class must either be in JSONABLE_DATATYPES or a type that’s been registered inschrodinger.models.jsonable
.
- Parameters
serializer (jsonable.AbstractJsonSerializer) – A custom serializer to use for deserializing the file. This should not be used at the same time as the
DataClass
argument.
If the json file was not encoded
JsonableClassMixin
object, this function will behave exactly like the builtinjson.load
.