Skip to main content

Addict dictionary enhanced with ability to track changes -- currently only supports field additions

Project description

addict-tracking-changes

Python versions Tests Status Coverage Status Flake8 Status

Documentation PyPI Downloads Downloads per week GitHub stars

Introduction

HEADS UP Before using the library carefully read the Known bugs and Caveats section below.

Originally, this repository was a fork of addict by Mats Julian Olsen. Overtime, it has substatially diverged in functionality and codebase that it made sense to breakout as its own repository.

The original addict: provides an alternative and succient interface to manipulate a dictionary. This is especially useful when dealing with heavily nested dictionaries. As example (taken from https://github.com/mewwts/addict) a dictionary created using standard python dictionary interface looks as follows:

body = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}`

can be summarized to following three lines:

body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'

This repo builds on original addict and adds contraptions to track key additions in the dictionary. This features comes in quite handy in building reactive webapps where one has to respond to all the changes made on the browser. Addict-tracking-changes is the underpinning data-structure in ofjustpy: a python based webframework build from justpy

The functions relevant to tracking changed history are: get_changed_history and clear_changed_history. The get_changed_history returns an iterator of XPath style paths like /a/b/c/e (see Demo example).

Usage and examples

Installation

This project is not on PyPI. Its a simple package with no third party dependency. Simply clone from github and include the source directory in your PYTHONPATH.

Demo example

from addict import Dict
body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'

for changed_path in body.get_changed_history():
    #<work with changed_path>

body.clear_changed_history()

Behaviour when values are instances of container types

addict works as expected when the values of keys are simple data types (such as string, int, float, etc.). However, for container types such as dict, list, tuples, etc. the behaviour is somewhat differs.

  • dicts are treated as opaque object just like simple data types
from addict import Dict

mydict = Dict()
mydict.a.b.c = {'kk': 1}
mydict.a.b.e = {'dd': 1}

for _ in mydict.get_changed_history():
    print(_) 

will print

/a/b/c
/a/b/e

and not

/a/b/cc/kk
/a/b/e/dd
  • lists are seen as container, i.e., get_changed_history will report path for each element of the list
from addict import Dict

mydict = Dict()

mydict.a.b = [1, [1]]
mydict.a.c = [2, [2, [3]]]

get_changed_history will report following paths:

/a/b/0,
/a/b/1/0,
/a/c/0,
/a/c/1/0,
/a/c/1/1/"
  • tuple, namedtuple, sets tuple behave same as dict and are treated as opaque data structure

Known bugs and Caveats

  1. Only tracks field additions. Deletions and updates are not tracked.
  2. freeze doesn't guards against deletions
  3. building dict from another dict as shown in following expression wont' work
cjs_cfg = Dict(other_dict, track_changes=True)

instead use

cjs_cfg = Dict(track_changes = True)
with open("other_dict.pickle", "rb") as fh:
    x = pickle.load(fh)
for _ in oj.dictWalker(x):
    oj.dnew(cjs_cfg, _[0], _[1])
  1. Use TrackedList for tracking nested list
from addict_tracking_changes import Dict, TrackedList


trackerprop = Dict(track_changes = True)
trackerprop.a.b = [1, TrackedList([1], track_changes=True)]
trackerprop.a.c = [2, TrackedList([2, TrackedList([3], track_changes=True)
                                   ], track_changes=True)
                   ]

which when asked changed history will output as follows:

print(list(trackerprop.get_changed_history()))

output

['/a/b/0', '/a/b/1/0', '/a/c/0', '/a/c/1/0', '/a/c/1/1/0']

APIs

API Description
Dict(*args, **kwargs) Initializes a new Dict object
to_dict(self) Converts the Dict object to a regular dictionary
freeze(self, shouldFreeze=True) Freezes the Dict object, making it immutable
unfreeze(self) Unfreezes the Dict object, making it mutable again
get_changed_history(self, prefix="", path_guards=None) Returns an iterator with the changed history of keys
clear_changed_history(self) Clears the changed history of the Dict object
set_tracker(self, track_changes=False) Sets or resets the change tracker for the Dict object

EndNotes

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

addict-tracking-changes-1.0.4.tar.gz (51.0 kB view details)

Uploaded Source

Built Distribution

addict_tracking_changes-1.0.4-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file addict-tracking-changes-1.0.4.tar.gz.

File metadata

File hashes

Hashes for addict-tracking-changes-1.0.4.tar.gz
Algorithm Hash digest
SHA256 b96abf91f76cbbc64f1ebd662e67007f6bcc40f5e4284d32d97f0c60e6e06d2f
MD5 2039ebf5214af282e5b91879580dfce4
BLAKE2b-256 e3bdd01d4fd3497776fa578efe263a0f4e98495c08c3b31f5f55533131f02959

See more details on using hashes here.

File details

Details for the file addict_tracking_changes-1.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for addict_tracking_changes-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 93b423d06fced021801d548a63d06afa2db090a3d98fc9b5ba71f36e771cec37
MD5 e6bb57b57ad2c316e9db964a54b474b9
BLAKE2b-256 f5c18c30da4c94933be217e81e6912106edbd2a6c41efa08f5d8f57994d02e87

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