Skip to main content

A recursive subclass of ChainMap

Project description

DeepChainMap

PyPI codecov pre-commit.ci status Code style: black

A recursive subclass of the builtin Python class collections.ChainMap.

Installation

pip install deep-chainmap

Usage

The canonical use case for the builtin class collections.ChainMap is to aggregate configuration data from layered mapping (basically dictionaries) sources. However, it is not suited for non-flat (nested) mappings, the lookup mechanism only works for the top level of a mapping.

deep_chainmap.DeepChainMap provides a simple solution to this problem by making recurive lookups in arbitrarily deeply nested mappings. Let's illustrate this with a simple example. We will simulate 3 layers of mapping, and pretend they were obtained from different sources (a default configuration, a configuration file and the command line).

from deep_chainmap import DeepChainMap

default_layer = {
    "architecture": "gpu",
    "logging_level": "warning",
    "solver": "RK4",
    "database": {
        "url": "unset",
        "keep_in_sync": False,
    },
    "mesh": {
        "type": "rectangular",
        "resolution": {
            "x": {
                "npoints": 100,
                "spacing": "linear",
            },
            "y": {
                "npoints": 100,
                "spacing": "linear",
            },
            "z": {
                "npoints": 100,
                "spacing": "linear",
            },
        },
    },
}

config_file_layer = {
    "architecture": "cpu",
    "mesh": {
        "resolution": {
            "x": {
                "spacing": "log",
            },
            "z": {
                "npoints": 1,
            },
        },
    },
}

cli_layer = {
    "logging_level": "debug",
    "database": {
        "url": "https://my.database.api",
        "keep_in_sync": True
    },
}

# now building a DeepChainMap
cm = DeepChainMap(cli_layer, config_file_layer, default_layer)

Now when a single parameter is requested, it is looked up in each layer until a value is found, by order of insertion (here the cli_layer takes priority).

>>> cm["logging_level"]
'debug'
>>> cm["mesh"]["resolution"]["x"]["spacing"]
'log'
>>> cm["mesh"]["resolution"]["x"]["npoints"]
100

It is possible to produce a flat view of a DeepChainMap instance as a builtin dict:

>>> cm.flatten()
{
    'architecture': 'cpu',
    'logging_level': 'debug',
    'solver': 'RK4',
    'database': {
        'url': 'https://my.database.api',
        'keep_in_sync': True
    },
    'mesh': {
        'type': 'rectangular',
        'resolution': {
            'x': {'npoints': 100, 'spacing': 'log'},
            'y': {'npoints': 100, 'spacing': 'linear'},
            'z': {'npoints': 1, 'spacing': 'linear'}
        }
    }
}

Additionally, each submapping from any level can be retrieved as a new layered-mapping

>>> cm["mesh"]
DeepChainMap({'resolution': {'x': {'spacing': 'log'}, 'z': {'npoints': 1}}},
             {'resolution': {'x': {'npoints': 100, 'spacing': 'linear'},
                             'y': {'npoints': 100, 'spacing': 'linear'},
                             'z': {'npoints': 100, 'spacing': 'linear'}},
              'type': 'rectangular'})

Which implies that they can be flatten as well

>>> cm["mesh"].flatten()
{
    'type': 'rectangular',
    'resolution': {
        'x': {'npoints': 100, 'spacing': 'log'},
        'y': {'npoints': 100, 'spacing': 'linear'},
        'z': {'npoints': 1, 'spacing': 'linear'}
    }
}

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

deep_chainmap-0.0.2.tar.gz (4.3 kB view details)

Uploaded Source

Built Distribution

deep_chainmap-0.0.2-py3-none-any.whl (4.0 kB view details)

Uploaded Python 3

File details

Details for the file deep_chainmap-0.0.2.tar.gz.

File metadata

  • Download URL: deep_chainmap-0.0.2.tar.gz
  • Upload date:
  • Size: 4.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

File hashes

Hashes for deep_chainmap-0.0.2.tar.gz
Algorithm Hash digest
SHA256 161f80bcffbbd9ad6c5f5eb0bc443558623fe52ca48da11770b24272dfb923b6
MD5 4e02579a6fc92dd53d691238e204d03b
BLAKE2b-256 e487b7c2ef954188e302856378b0d59d39251e3590818180b3cbb60f9c401ad4

See more details on using hashes here.

File details

Details for the file deep_chainmap-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: deep_chainmap-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 4.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

File hashes

Hashes for deep_chainmap-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c8bfe4f154df0e55a3b98d4b272116e4d255fbfae86eb372a8cddc747fc72d2b
MD5 b1ce7e87f383caa915f5ecf1b0bb8339
BLAKE2b-256 8ec91e95f1c4b9d52f885283342b501163906bc8c60bc3ad74243e8f5db9564d

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page