A tool for mapping and transforming dictionaries based on predefined rules.
Project description
Dictionary Mapper
Table of Contents
Usage
This library can map a source dictionary and generate a target new one following dot notation in source and target dictionaries.
Example:
- Define a SpecEntry dict, keys are the source dict paths, values are the target dict paths:
from dictionary_mapper import SpecEntry
spec: SpecEntry = {
"body.int_field": "int_field",
"body.str_field": "str_field",
"body.complex_field.nested_int": {
"path": "complex_field.nested_int",
"default": 0,
"transform": lambda x: cast("int", x) * 2,
},
"body.complex_field.nested_str": "complex_field.nested_str",
"body.list[0].str_field": "list_field",
"body.int_list": "int_list",
"body.str_list": "str_list",
}
- For raw dict output, then use the RawDictionaryMapper class
...
from typing import cast
from dictionary_mapper import RawDictionaryMapper
...
src: dict[str, object] = {
"body": {
"int_field": 10,
"str_field": "hello",
"complex_field": {
"nested_int": 5,
"nested_str": "world",
},
"list": [
{
"str_field": "test field",
},
],
"int_list": [1, 2, 3],
"str_list": ["1", "2", "3"],
},
}
dm: RawDictionaryMapper = RawDictionaryMapper()
maped_dict: dict[str, object] = dm.create_transformed_dict(src, spec)
assert maped_dict["int_field"] == 10
assert maped_dict["str_field"] == "hello"
assert cast("dict[str, object]", maped_dict["complex_field"])["nested_int"] == 10 # Transformed
assert cast("dict[str, object]", maped_dict["complex_field"])["nested_str"] == "world"
assert maped_dict["list_field"] == "test field"
assert maped_dict["int_list"] == [1, 2, 3]
assert maped_dict["str_list"] == ["1", "2", "3"]
- For TypedDicts you can use the TypedDictionaryMapper as follows
...
from dictionary_mapper import TypedDictionaryMapper
...
class MyNestedDict(TypedDict):
nested_int: int
nested_str: str
class MyTypedDict(TypedDict):
int_field: int
str_field: str
complex_field: MyNestedDict
list_field: str
int_list: list[int]
str_list: list[str]
...
dm: TypedDictionaryMapper[MyTypedDict] = TypedDictionaryMapper()
maped_dict: MyTypedDict = dm.create_transformed_dict(src, spec)
assert maped_dict["int_field"] == 10
assert maped_dict["str_field"] == "hello"
assert maped_dict["complex_field"]["nested_int"] == 10 # Transformed
assert maped_dict["complex_field"]["nested_str"] == "world"
assert maped_dict["list_field"] == "test field"
assert maped_dict["int_list"] == [1, 2, 3]
assert maped_dict["str_list"] == ["1", "2", "3"]
- You can add complex lists on the target, but you'll need to add allways the index to that lists, otherwhise will be recognized as primitive value.
src = {
...
"complex_list": [
{
"nested_int": 10,
"nested_str": "complex",
},
{"nested_int": 5},
{},
{
"nested_str": "double complex",
},
],
...
}
...
spec = {
...
"body.complex_list[0].nested_int": "complex_list[1].secondary_field[0].secondary_int",
"body.complex_list[0].nested_str": "complex_list[1].secondary_field[3].secondary_str",
"body.complex_list[2].nested_int": "complex_list[1].secondary_field[1].secondary_int",
"body.complex_list[3].nested_str": "complex_list[1].secondary_field[2].secondary_str",
"body.complex_list[1].nested_int": {
"path": "complex_list[0].secondary_field[1].secondary_int",
"default": 0,
"transform": lambda x: cast("int", x) * 2,
},
...
}
...
EXPECTED_INT_FIELD = 10
assert maped_dict["complex_list"][1]["secondary_field"][0]["secondary_int"] == EXPECTED_INT_FIELD
assert maped_dict["complex_list"][1]["secondary_field"][3]["secondary_str"] == "complex"
assert maped_dict["complex_list"][1]["secondary_field"][1]["secondary_int"] is None
assert maped_dict["complex_list"][1]["secondary_field"][2]["secondary_str"] == "double complex"
assert maped_dict["complex_list"][0]["secondary_field"][1]["secondary_int"] == EXPECTED_INT_FIELD # Transformed
Installation
Add recommended extensions at .vscode/extensions.json. Then run:
pip install hatch hatch-pip-deepfreeze
hatch shell
These two commands creates everithing for you and vscode to start working ASAP.
License
dictionary-mapper is distributed under the terms of the MIT license.
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dictionary_mapper-0.3.0.tar.gz.
File metadata
- Download URL: dictionary_mapper-0.3.0.tar.gz
- Upload date:
- Size: 4.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0258afe269562701394e1d95685ada0e16b2846d5f69a5c5498fe8aa8fd97999
|
|
| MD5 |
03dfac919de2c8b5bd28e46ab48e2cf9
|
|
| BLAKE2b-256 |
0c111bf265b7c2591e10df2f69ad8735b3003b363d719e2d09415719b62513f7
|
File details
Details for the file dictionary_mapper-0.3.0-py3-none-any.whl.
File metadata
- Download URL: dictionary_mapper-0.3.0-py3-none-any.whl
- Upload date:
- Size: 4.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94f2fee6f3e34822558704690d847a5cf7d4f881e46b71c9342ee5389174e80a
|
|
| MD5 |
0f8387035f21d83c450089084014a393
|
|
| BLAKE2b-256 |
87608f3d4ef90e2bbce7f02e4b433a959a36259713d6ff62985118c9f5c3ab5d
|