Reading and writing JSON

This module provides small tools to make reading and writing JSON data simpler. The standard library’s json module does all the heavy lifting here, but some shortcomings are addressed.

One of these shortcomings is missing support for datetime objects. This can be remedied using the functions format() and parse() as follows:

>>> from datetime import datetime
>>> from clldutils.jsonlib import parse, format
>>> from json import JSONEncoder, loads, dumps
>>> class DateTimeEncoder(JSONEncoder):
...     def default(self, obj):
...         return format(obj)
...
>>> dumps({'start': datetime.now(), 'end': 5}, cls=DateTimeEncoder)
'{"start": "2022-12-15T14:32:45.637522", "end": 5}'
>>> parse(json.loads(json.dumps({'start': datetime.now(), 'end': 5}, cls=DateTimeEncoder)))
{'start': datetime.datetime(2022, 12, 15, 14, 33, 17, 323973), 'end': 5}
clldutils.jsonlib.parse(d)[source]

Convert iso formatted timestamps found as values in the dict d to datetime objects.

Note

This works with nested dict`s and `list values, too.

>>> parse({"start": {'from': "2022-12-15T14:32:45.637522", 'to': 7}})['start']['from']
datetime.datetime(2022, 12, 15, 14, 32, 45, 637522)
>>> parse({"start": ["2022-12-15T14:32:45.637522"]})['start'][0]
datetime.datetime(2022, 12, 15, 14, 32, 45, 637522)
Return type:

dict

Returns:

A shallow copy of d with converted timestamps.

Parameters:

d (dict) –

clldutils.jsonlib.format(value)[source]

Format a value as ISO timestamp if it is a datetime.date(time) instance, otherwise return it unchanged.

clldutils.jsonlib.dump(obj, path, **kw)[source]

json.dump which understands filenames.

Parameters:
  • obj – The object to be dumped.

  • path (typing.Union[typing.TextIO, str, pathlib.Path]) – The path of the JSON file to be written.

  • kw – Keyword parameters are passed to json.dump

clldutils.jsonlib.load(path, **kw)[source]

json.load which understands filenames.

Parameters:
  • kw – Keyword parameters are passed to json.load

  • path (typing.Union[typing.TextIO, str, pathlib.Path]) –

Returns:

The python object read from path.

clldutils.jsonlib.update(path, default=None, load_kw=None, **kw)[source]

An update-able JSON file

>>> with update('/tmp/t.json', default={}) as o:
...     o['x'] = 5
...
>>> load('/tmp/t.json')['x']
5