addict-tracking-changes


Nameaddict-tracking-changes JSON
Version 1.0.6 PyPI version JSON
download
home_pageNone
SummaryAddict dictionary enhanced with ability to track changes -- currently only supports field additions
upload_time2023-08-31 04:50:42
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # [addict-tracking-changes](https://github.com/Monallabs-org/addict-tracking-changes)


[![Python versions](https://img.shields.io/badge/Python-3.11-green)](https://pypi.python.org/pypi/addict-tracking-changes)
[![Tests Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_tests.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)
[![Coverage Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_coverage.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)
[![Flake8 Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_flake8.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)

[![Documentation](https://img.shields.io/badge/doc-latest-blue.svg)](https://ofjustpy.github.io/addict-tracking-changes/)
[![PyPI](https://img.shields.io/pypi/v/addict-tracking-changes.svg)](https://pypi.python.org/pypi/addict-tracking-changes)
[![Downloads](https://pepy.tech/badge/addict-tracking-changes)](https://pepy.tech/project/addict-tracking-changes)
[![Downloads per week](https://pepy.tech/badge/addict-tracking-changes/week)](https://pepy.tech/project/addict-tracking-changes)
[![GitHub stars](https://img.shields.io/github/stars/ofjustpy/addict-tracking-changes.svg)](https://github.com/ofjustpy/addict-tracking-changes/stargazers)


## Introduction

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


Originally, this repository was a fork of [addict](https://github.com/mewwts/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:
```python
body = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}`

``` 
can be summarized to following three lines:

```python
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](https://github.com/Monallabs-org/ofjustpy): a python based webframework build from [justpy](https://github.com/justpy-org/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](#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

```python
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

```python
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 

```python
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
```python
cjs_cfg = Dict(other_dict, track_changes=True)
```
instead use
```python 
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])

```
4. Use TrackedList for tracking nested list

```python
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:
```python
print(list(trackerprop.get_changed_history()))
```
output
```bash
['/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
- Docs (in readthedocs format): https://monallabs-org.github.io/addict-tracking-changes/#introduction, https://webworks.monallabs.in/addict-tracking-changes

- Developed By: webworks.monallabs.in


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "addict-tracking-changes",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Kabira K <kabira@monallabs.in>",
    "keywords": null,
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/29/51/a92424df293e3d72ce1669d820707470edbfb040eb0e2eec707236e13987/addict-tracking-changes-1.0.6.tar.gz",
    "platform": null,
    "description": "# [addict-tracking-changes](https://github.com/Monallabs-org/addict-tracking-changes)\n\n\n[![Python versions](https://img.shields.io/badge/Python-3.11-green)](https://pypi.python.org/pypi/addict-tracking-changes)\n[![Tests Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_tests.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)\n[![Coverage Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_coverage.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)\n[![Flake8 Status](https://github.com/ofjustpy/addict-tracking-changes/blob/main/badge_flake8.svg)](https://github.com/ofjustpy/addict-tracking-changes/actions)\n\n[![Documentation](https://img.shields.io/badge/doc-latest-blue.svg)](https://ofjustpy.github.io/addict-tracking-changes/)\n[![PyPI](https://img.shields.io/pypi/v/addict-tracking-changes.svg)](https://pypi.python.org/pypi/addict-tracking-changes)\n[![Downloads](https://pepy.tech/badge/addict-tracking-changes)](https://pepy.tech/project/addict-tracking-changes)\n[![Downloads per week](https://pepy.tech/badge/addict-tracking-changes/week)](https://pepy.tech/project/addict-tracking-changes)\n[![GitHub stars](https://img.shields.io/github/stars/ofjustpy/addict-tracking-changes.svg)](https://github.com/ofjustpy/addict-tracking-changes/stargazers)\n\n\n## Introduction\n\n**HEADS UP** \nBefore using the library carefully read the Known bugs and Caveats section below. \n\n\nOriginally, this repository was a fork of [addict](https://github.com/mewwts/addict) by Mats Julian Olsen.\nOvertime, it has substatially diverged in functionality and codebase that it made\nsense to breakout as its own repository. \n\nThe original addict:  provides an alternative and succient interface to manipulate a dictionary. This is especially\nuseful when dealing with heavily nested dictionaries. As example (taken from https://github.com/mewwts/addict)\na dictionary created using standard python dictionary interface looks as follows:\n```python\nbody = {\n    'query': {\n        'filtered': {\n            'query': {\n                'match': {'description': 'addictive'}\n            },\n            'filter': {\n                'term': {'created_by': 'Mats'}\n            }\n        }\n    }\n}`\n\n``` \ncan be summarized to following three lines:\n\n```python\nbody = Dict()\nbody.query.filtered.query.match.description = 'addictive'\nbody.query.filtered.filter.term.created_by = 'Mats'\n```\n\nThis repo builds on original addict and adds contraptions to track key additions in the dictionary.\nThis features comes in quite handy in building reactive webapps where one has to respond \nto all the changes made on the browser. Addict-tracking-changes is the underpinning\ndata-structure in [ofjustpy](https://github.com/Monallabs-org/ofjustpy): a python based webframework build from [justpy](https://github.com/justpy-org/justpy)\n \nThe functions relevant to tracking changed history are:\n`get_changed_history` and `clear_changed_history`. \nThe `get_changed_history` returns an iterator of XPath style paths like `/a/b/c/e` (see [Demo example](#demo-example)). \n\n## Usage and examples\n\n### Installation\nThis project is not on PyPI. Its a simple package with no third party dependency. \nSimply clone from github and include the source directory in your PYTHONPATH. \n\n### Demo example\n\n```python\nfrom addict import Dict\nbody = Dict()\nbody.query.filtered.query.match.description = 'addictive'\nbody.query.filtered.filter.term.created_by = 'Mats'\n\nfor changed_path in body.get_changed_history():\n    #<work with changed_path>\n\nbody.clear_changed_history()\n```\n\n### Behaviour when values are instances of container types \naddict 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. \n\n* dicts are treated as opaque object just like simple data types\n\n```python\nfrom addict import Dict\n\nmydict = Dict()\nmydict.a.b.c = {'kk': 1}\nmydict.a.b.e = {'dd': 1}\n\nfor _ in mydict.get_changed_history():\n    print(_) \n```\nwill print\n```\n/a/b/c\n/a/b/e\n```\nand not \n```\n/a/b/cc/kk\n/a/b/e/dd\n```\n\n* lists\nare seen as container, i.e., `get_changed_history` will report path for each element of\nthe list \n\n```python\nfrom addict import Dict\n\nmydict = Dict()\n\nmydict.a.b = [1, [1]]\nmydict.a.c = [2, [2, [3]]]\n```\nget_changed_history will report following paths:\n```\n/a/b/0,\n/a/b/1/0,\n/a/c/0,\n/a/c/1/0,\n/a/c/1/1/\"\n```\n\n* tuple, namedtuple, sets\ntuple  behave same as dict and are treated as opaque data structure\n\n\n## Known bugs and Caveats\n1. Only tracks  field additions.  Deletions and updates are not tracked. \n2. freeze doesn't guards against deletions\n3. building dict from another dict as shown in following expression wont' work\n```python\ncjs_cfg = Dict(other_dict, track_changes=True)\n```\ninstead use\n```python \ncjs_cfg = Dict(track_changes = True)\nwith open(\"other_dict.pickle\", \"rb\") as fh:\n    x = pickle.load(fh)\nfor _ in oj.dictWalker(x):\n    oj.dnew(cjs_cfg, _[0], _[1])\n\n```\n4. Use TrackedList for tracking nested list\n\n```python\nfrom addict_tracking_changes import Dict, TrackedList\n\n\ntrackerprop = Dict(track_changes = True)\ntrackerprop.a.b = [1, TrackedList([1], track_changes=True)]\ntrackerprop.a.c = [2, TrackedList([2, TrackedList([3], track_changes=True)\n                                   ], track_changes=True)\n                   ]\n```\nwhich when asked changed history will output as follows:\n```python\nprint(list(trackerprop.get_changed_history()))\n```\noutput\n```bash\n['/a/b/0', '/a/b/1/0', '/a/c/0', '/a/c/1/0', '/a/c/1/1/0']\n```\n\n\n## APIs\n| API                                                  | Description                                        |\n|------------------------------------------------------|----------------------------------------------------|\n| `Dict(*args, **kwargs)`                              | Initializes a new Dict object                      |\n| `to_dict(self)`                                      | Converts the Dict object to a regular dictionary   |\n| `freeze(self, shouldFreeze=True)`                    | Freezes the Dict object, making it immutable       |\n| `unfreeze(self)`                                     | Unfreezes the Dict object, making it mutable again |\n| `get_changed_history(self, prefix=\"\", path_guards=None)` | Returns an iterator with the changed history of keys |\n| `clear_changed_history(self)`                        | Clears the changed history of the Dict object      |\n| `set_tracker(self, track_changes=False)`             | Sets or resets the change tracker for the Dict object |\n\n\n\n### EndNotes\n- Docs (in readthedocs format): https://monallabs-org.github.io/addict-tracking-changes/#introduction, https://webworks.monallabs.in/addict-tracking-changes\n\n- Developed By: webworks.monallabs.in\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Addict dictionary enhanced with ability to track changes -- currently only supports field additions",
    "version": "1.0.6",
    "project_urls": {
        "Documentation": "https://ofjustpy.github.io/addict-tracking-changes/",
        "Home": "https://webworks.monallabs.in/ofjustpy/addict-tracking-changes",
        "Source": "https://github.com/ofjustpy/addict-tracking-changes"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f622d4167d53453328f42441400e76cf30d0efebf7276ac903aeb6e5ab2cfa38",
                "md5": "2d92603e0895dabca3fa2d0000c338cf",
                "sha256": "2a6ba7d2b00dc681ea38bd2ffc60398bf8072ac02e7b91785c150de4ed8bd074"
            },
            "downloads": -1,
            "filename": "addict_tracking_changes-1.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2d92603e0895dabca3fa2d0000c338cf",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 10256,
            "upload_time": "2023-08-31T04:50:39",
            "upload_time_iso_8601": "2023-08-31T04:50:39.941467Z",
            "url": "https://files.pythonhosted.org/packages/f6/22/d4167d53453328f42441400e76cf30d0efebf7276ac903aeb6e5ab2cfa38/addict_tracking_changes-1.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2951a92424df293e3d72ce1669d820707470edbfb040eb0e2eec707236e13987",
                "md5": "3e5fcdd14e5542e0a4df3f0f95e7298e",
                "sha256": "8fecc7ad5ac7bb218f547a23497af3d9d08f5fd5557c9a0f084c57703bd59d47"
            },
            "downloads": -1,
            "filename": "addict-tracking-changes-1.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "3e5fcdd14e5542e0a4df3f0f95e7298e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 34713,
            "upload_time": "2023-08-31T04:50:42",
            "upload_time_iso_8601": "2023-08-31T04:50:42.902362Z",
            "url": "https://files.pythonhosted.org/packages/29/51/a92424df293e3d72ce1669d820707470edbfb040eb0e2eec707236e13987/addict-tracking-changes-1.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-08-31 04:50:42",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ofjustpy",
    "github_project": "addict-tracking-changes",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "addict-tracking-changes"
}
        
Elapsed time: 0.11044s