Source code for fixie.jsonutils

"""Standard fixie tools for dealing with JSON."""
import json
import uuid
import base64
from collections.abc import Set


[docs]def default(obj): """For custom object serialization.""" if isinstance(obj, Set): return {'__set__': True, 'elements': sorted(obj)} elif isinstance(obj, bytes): return {'__bytes__': 'base64', 'value': base64.standard_b64encode(obj).decode('utf-8')} elif isinstance(obj, uuid.UUID): return {'__UUID__': True, 'value': str(obj)} raise TypeError(repr(obj) + " is not JSON serializable")
[docs]def object_hook(dct): """For custom object deserialization.""" if '__set__' in dct: return set(dct['elements']) elif '__bytes__' in dct: return base64.standard_b64decode(dct['value'].encode('utf-8')) elif '__UUID__' in dct: return uuid.UUID(dct['value']) return dct
[docs]def dumps(obj, sort_keys=True, separators=(',', ':'), default=default, **kwargs): """Returns a JSON string from a Python object.""" return json.dumps(obj, sort_keys=sort_keys, separators=separators, default=default, **kwargs)
[docs]def dump(obj, fp, sort_keys=True, separators=(',', ':'), default=default, **kwargs): """Returns a JSON string from a Python object.""" return json.dump(obj, fp, sort_keys=sort_keys, separators=separators, default=default, **kwargs)
[docs]def encode(obj, **kwargs): """Encodes JSON with forward slash encoding, such as in Tornado.""" return dumps(obj, **kwargs).replace("</", "<\\/")
[docs]def appendline(obj, f, **kwargs): """Appends a line to a line-oriented JSON file (either str path or file handle).""" if isinstance(f, str): with open(f, 'a+') as fp: dump(obj, fp, **kwargs) fp.write('\n') else: dump(obj, f, **kwargs) f.write('\n')
[docs]def loads(s, object_hook=object_hook, **kwargs): """Loads a string as JSON, with approriate object hooks""" return json.loads(s, object_hook=object_hook, **kwargs)
[docs]def load(fp, object_hook=object_hook, **kwargs): """Loads a file object as JSON, with appropriate object hooks.""" return json.load(fp, object_hook=object_hook, **kwargs)
[docs]def decode(s, **kwargs): if hasattr(s, 'decode'): # handle bytes, if needed s = s.decode("utf-8") return loads(s, **kwargs)
[docs]def loadlines(f, **kwargs): """Loads lines from a file (either str path of file handle).""" if isinstance(f, str): with open(f) as fp: lines = [loads(line, **kwargs) for line in fp] else: lines = [loads(line, **kwargs) for line in f] return lines