:yarn: pydlib 
The python dictionary library to get into complex nested python dictionary structures (e.g. json) in a safe and clean way. We take inspiration from Greek myth of Minotaur, where Ariadne with the help of a thread escaped the labyrinth with his beloved Theseus.
Why use pydlib
Sometimes you have to navigate deep json dicts from remote sources, like elastic logs: you can make a series of .get() and check for None every time; or you can do obj["path"]["to"]["nested"]["field"] and wrap everything in a try/except...
Or you can use pydlib and write:
pydlib.get(obj, "path.to.nested.field")
to get the value of field, or None if anything is not a dict along the given path.
Installation
To install pydlib, simply use pip:
$ pip install pydlib
or install from the repository:
$ git clone https://github.com/aitechnologies-it/dlib.git
$ cd dlib
$ python setup.py install
Basic usage
get()
You can get the value from a nested field, just by indicating the path to the nested sub-structure as follows:
>>> import pydlib as dl
>>> dictionary = {
>>> 'path': {
>>> 'to': {
>>> 'nested': {
>>> 'field': 42
>>> }
>>> }
>>> }
>>> }
>>> dl.get(dictionary, path='path.to.nested.field', default=0)
42
Instead, if the field we are looking for doesn't exists, or, if it exists but has a None value, then:
>>> ...
>>> dl.get(dictionary, path='path.to.nested.nonexisting.field', default=0)
0
has()
You can also test for a field simply calling:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.has(dictionary, path='path.to.nested.field')
True
update()
Furthermore, the pydlib comes with built-in functions to also update and delete fields. For example, to update:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.update(dictionary, path='path.to.nested.field', value=1)
{
'path': {
'to': {
'nested': {
'field': 1
}
}
}
}
delete()
Instead, to delete:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.delete(dictionary, path='path.to.nested.field')
{
'path': {
'to': {
'nested': {}
}
}
}
Type-safety
pydlib is type safe, in fact you don't have to manually check the type of inputs, pydlib does it for you:
>>> import pydlib as dl
>>> res = dl.get("not a dictionary", path="nowhere", default=None)
>>> res is None
True
Advanced features
Custom separator
It may happen that a dictionary has a string key with . in it. In this case you should use a different separator:
>>> import pydlib as dl
>>> d = {"a": {"b.c": 42}}
# Separator conflict
>>> dl.get(d, "a.b.c")
None
# This works!
>>> dl.get(d, "a/b.c", sep="/")
42
Search inside lists
has() and get() (but not update and delete!) can handle lists. This means that, if a list is encountered, the search for the rest of the path continues for each element of the list. A few examples are needed:
-
bis a list, get() will return a list with all dictionaries containing the rest of the pathc.d:>>> d = {"a": {"b": [ {"c": {"d": 1}}, # <-- this {"bad": {"d": 2}}, {"c": {"d": 3}}, # <-- this {"c": {"bad": 4}} ] } } >>> dl.get(d, "a.b.c.d") [1, 3]
-
this works also for nested lists. In this case a nested list of matching depth is returned:
>>> d = {"a": {"b": [ {"c": {"d": [ {"e": 1}, {"e": 2}, {"bad": 3}, ]} }, {"bad": {"d": [ {"e": 4}, ]} }, {"c": {"d": [ {"e": 5}, ]} }, ] } } >>> dl.get(d, "a.b.c.d.e") [[1, 2], [5]]
-
In this case the elements of list
bare of different types,(1)and(3)are dictionaries,(2)is a list:>>> d = {"a": {"b": [ {"c": {"d": 1}}, # (1) [ {"c": {"d": 3}} ], # (2) {"c": {"d": 4}}, # (3) ] } } >>> dl.get(d, "a.b.c.d") [1, [3], 4]
-
Handling of lists can be disabled by setting
search_lists=False. Here's different behaviours forsearch_lists:>>> d = {"a": {"b": [ {"c": {"d": 1}}, {"bad": {"d": 2}}, {"c": {"d": 3}}, {"c": {"bad": 4}} ] } } >>> dl.get(d, "a.b.c.d", search_lists=True) [1, 3] >>> dl.get(d, "a.b.c.d", search_lists=False) None # But if instead we want to get `a.b`, no lists are traversed and both return the value of `b` >>> dl.get(d, "a.b", search_lists=True) [{'c': {'d': 1}}, [{'c': {'d': 3}}], {'c': {'d': 4}}] >>> dl.get(d, "a.b", search_lists=False) [{'c': {'d': 1}}, [{'c': {'d': 3}}], {'c': {'d': 4}}]
Metadata
Release files for pydlib 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pydlib-0.3.2.tar.gz | 4.6 kB | Without provenance | Details for pydlib-0.3.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pydlib-0.3.2-py3-none-any.whl | Python 3 | none | any | Details for pydlib-0.3.2-py3-none-any.whl |
Total release size: 9.3 kB
Release files / pydlib-0.3.2.tar.gz
| Download URL | pydlib-0.3.2.tar.gz |
|---|---|
| Size | 4.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51e6e9a41aa461952f79451a68d53ab85b75362f3951ec46498407b6c54b779a
|
|
BLAKE2b-256 checksum How to use checksums |
153bab4fbb084c28cff308ab806645b20b10012004f044300b8f84cfa62a4c49
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.11.2
|
Release files / pydlib-0.3.2-py3-none-any.whl
| Download URL | pydlib-0.3.2-py3-none-any.whl |
|---|---|
| Size | 4.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3017f508752bdd91690581f9d5548f59b38cff2a146d6e7a378ef0bd447344bc
|
|
BLAKE2b-256 checksum How to use checksums |
b916d6c5b8dfa9a95af40dde645d1136c4203c75ef4626ab5059d88acd309b8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.11.2
|
Security for pydlib 0.3.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.