Skip to main content

Traversing and manipulating hierarchical info sets (JSON) using pythonic JSON Path-like expressions

Project description

Traversing and manipulating hierarchical data (JSON) using pythonic JSON Path-like expressions

Importing

>>> from aweson import JP, find_all

Iterating over hierarchical data

>>> content = {"employees": [
...     {"name": "Doe, John", "age": 32, "account": "johndoe"},
...     {"name": "Doe, Jane", "age": -23, "account": "janedoe"},
...     {"name": "Deer, Jude", "age": 42, "account": "judedeer"},
... ]}
>>> list(find_all(content, JP.employees[:].name))
['Doe, John', 'Doe, Jane', 'Deer, Jude']

Note that the JSON Path-like expression JP.employees[:].name is not a string, it’s a Python expression, i.e. your IDE will be of actual help.

Furthermore, to address all items in a list, Pythonic slice expression [:] is used. Naturally, other indexing and slice expressions also work in the conventional Pythonic way:

>>> list(find_all(content, JP.employees[-1].name))
['Deer, Jude']
>>> list(find_all(content, JP.employees[:2].name))
['Doe, John', 'Doe, Jane']

Paths to items iterated

You may be interested in the actual path of an item being returned, just like you get an index alongside items when using enumerate(). For instance, you may want to verify ages being non-negative, and report accurately the path of failure items:

>>> path, item = next(tup for tup in find_all(content, JP.employees[:].age, enumerate=True) if tup[1] < 0)
>>> item
-23

The offending path, then, in human-readable format:

>>> str(path)
'.employees[1].age'

The enclosing record, using .parent attribute of the path obtained for the offending age:

>>> next(find_all(content, path.parent))
{'name': 'Doe, Jane', 'age': -23, 'account': 'janedoe'}

Note, with argument enumerate=True passed, find_all() yields tuples instead of single items.

Selecting sub-items

You can select sub-items of iterated items, comes handy into turning one structure into another, like a list of records into a dict:

>>> {tup[0]: tup[1] for tup in find_all(content, JP.employees[:](JP.account, JP.name))}
{'johndoe': 'Doe, John', 'janedoe': 'Doe, Jane', 'judedeer': 'Deer, Jude'}

or, to make your processing logic within the same comprehension expression more readable:

>>> {account: name for account, name in find_all(content, JP.employees[:](JP.account, JP.name))}
{'johndoe': 'Doe, John', 'janedoe': 'Doe, Jane', 'judedeer': 'Deer, Jude'}

You can also make a sub-items selection produce named tuples by explicitly naming sub-paths:

>>> list(find_all(content, JP.employees[:](account=JP.account, name=JP.name)))
[SubSelect(account='johndoe', name='Doe, John'), SubSelect(account='janedoe', name='Doe, Jane'), SubSelect(account='judedeer', name='Deer, Jude')]

Now, the processing code could be elsewhere than the find_all() invocation, as named tuples will carry the field names with them. The produced named tuples will all be called SubSelect but they will be different named tuples for each invocation.

Variable field name selection

The forms JP["field_name"] and JP.field_name are equivalent:

>>> from functools import reduce
>>> def my_sum(content, field_name, initial):
...     return reduce(
...         lambda x, y: x + y,
...         find_all(content, JP.employees[:][field_name]),
...         initial
...     )
>>> my_sum(content, "age", 0)
51
>>> my_sum(content, "account", "")
'johndoejanedoejudedeer'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aweson-1.1.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

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

aweson-1.1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file aweson-1.1.0.tar.gz.

File metadata

  • Download URL: aweson-1.1.0.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.18

File hashes

Hashes for aweson-1.1.0.tar.gz
Algorithm Hash digest
SHA256 36d458bf44f5d151e43f0f4e8ec60f74d9c9ede5ecbc6a9959f9da010baf5a25
MD5 1e829a95d38c4023148e7bd02cc5fb44
BLAKE2b-256 a29199c7937712ec60f147f1c6a12ed7e2436d74bdecfb00116bbba45e02f142

See more details on using hashes here.

File details

Details for the file aweson-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: aweson-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.18

File hashes

Hashes for aweson-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6dc94d16f7facbceeed571efb37f22cb653367c33d31e0f7833e15510f33ef8c
MD5 23fe582102d5bfdd5c2ef0755c532a84
BLAKE2b-256 ef9a07f4d13f58977c66abd18c631f6d942b2f4a5a0367f1f82f19ff4cb4a4a9

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