Safely navigate through unsafe data: dicts, tuples, lists, strings and objects
Project description
py-data-digger
Safely navigate through unsafe data: dicts, tuples, lists, strings and objects
Inspired on Ruby's dig.
Why?
TLDR:
Sometimes you don't want to deal with Python exceptions when accessing lists and dicts. If the data you need isn't there, you just want to move on...
No ifs, no try-excepts!
from py_data_digger import dig
components: list | None = dig(nasty_dict, "machines", 0, "engine", "components")
Detailed explanation
In some occasions (like when web scrapping) you need to grab some data from a deeply nested structure like this:
nasty_dict = {
"machines": [
{
"machine_id": "1234567890",
"engine": {
"id": "321abcde",
"name": "Motor XPTO",
"components": [
{"id": "0942323", "name": "Cog"},
{"id": "1642723", "name": "Piston"},
{"id": "8412321", "name": "Bar", "extras": ["Foo"]},
],
},
}
]
}
Suppose we want to take the list of components of the engine of a machine (the only present).
🚨 The unsafe strategy:
components: list = nasty_dict["machines"][0]["engine"]["components"]
This is unsafe because it is highly prone to raise IndexError
, KeyError
, TypeError
if you use the wrong key/index or if the data just isn't there.
😴 The safe (but boring) strategy:
machines: list | None = nasty_dict.get("machines", None)
machine: dict | None = next(iter(machines), None) if machines else None
engine: dict | None = machine.get("engine", None) if machine is not None else None
components: list | None: engine.get("components", None) if engine is not None else None
This is not only tedious but labourious! At least, it's safe. We would not raise errors to break our code.
Introducing dig
With this tool we may quickly and securely navigate through all sorts of nested data.
Let's consider the nasty_dict
from the past section and that we also want to access the list of components.
from py_data_digger import dig
components: list | None = dig(nasty_dict, "machines", 0, "engine", "components")
That's it! All the access problems are solved. If the data you want isn't there, it returns None
and you can just move on!
components: list | None = dig(nasty_dict, "machines", 0, "engine_2", "components")
if components is None:
return None
Introducing seek
Not satisfied with None
returns?
The seek
function works just like dig
, but it will raise an error if the path informed could not be found.
from py_data_digger import seek
components: list = seek(nasty_dict, "machines", 0, "engine_2", "components")
>>> SeekError: Data digger can't go any further: KeyError
Path traveled: dict -> machines -> 0 -> engine_2
The cool thing is, you would need to handle just one exception (SeekError
). It also shows where it failed to seek 😎
Seeking/digging objects
And there is more! If you also want to look inside object attributes, you may do it by passing a special flag. This way it will be compatible with any nested objects like Pydantic models and dataclasses!
person = Person(name='John Doe')
my_dict = {
'item_with_object': person
}
dig(my_dict, 'item_with_object', 'name', dig_objects=True)
>>> 'John Doe'
dig(my_dict, 'item_with_object', 'age', dig_objects=True)
>>> None
seek(my_dict, 'item_with_object', 'name', seek_objects=True)
>>> 'John Doe'
seek(my_dict, 'item_with_object', 'age', seek_objects=True)
>>> SeekError
⚠️ The special flag is required because attribute names may conflict with other mapped keys. Use with caution.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file py_data_digger-0.1.1.tar.gz
.
File metadata
- Download URL: py_data_digger-0.1.1.tar.gz
- Upload date:
- Size: 4.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.0 CPython/3.12.0 Linux/5.15.0-119-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0d97760b3417d846ae0bef83ffa12fe799251823f8e2d810aebcc50660cadf38 |
|
MD5 | 0630a64c09c9fcd030832924b6756dc1 |
|
BLAKE2b-256 | 87d314e1626dfbe261ae432b08db5c6202b419e1ae0a7cbaa86538e89ca5ea25 |
File details
Details for the file py_data_digger-0.1.1-py3-none-any.whl
.
File metadata
- Download URL: py_data_digger-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.0 CPython/3.12.0 Linux/5.15.0-119-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 86d1e112b1e412959aedf585a2f2571fef04cf4cb93f3cc0c9a5649c8bced7bf |
|
MD5 | 14e86d391dcbc39fe3c744b0863f66b6 |
|
BLAKE2b-256 | ac4515c342b3f75589d753e38ae64abeb741836ad1387e6a1aab554806376399 |