diot


Namediot JSON
Version 0.2.3 PyPI version JSON
download
home_pagehttps://github.com/pwwang/diot
SummaryPython dictionary with dot notation.
upload_time2023-10-20 22:32:46
maintainer
docs_urlNone
authorpwwang
requires_python>=3.7,<4.0
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            ![Logo](https://raw.githubusercontent.com/pwwang/diot/master/logo.png)

[![pypi][1]][2] [![tag][3]][4] [![codacy quality][7]][8] [![coverage][9]][8] ![pyver][10] ![building][6] ![docs][5]

Python dictionary with dot notation (A re-implementation of [python-box](https://github.com/cdgriffith/Box) with some issues fixed and simplified)

```python
from diot import Diot

movie_data = {
  "movies": {
    "Spaceballs": {
      "imdb stars": 7.1,
      "rating": "PG",
      "length": 96,
      "director": "Mel Brooks",
      "stars": [{"name": "Mel Brooks", "imdb": "nm0000316", "role": "President Skroob"},
                {"name": "John Candy","imdb": "nm0001006", "role": "Barf"},
                {"name": "Rick Moranis", "imdb": "nm0001548", "role": "Dark Helmet"}
      ]
    },
    "Robin Hood: Men in Tights": {
      "imdb stars": 6.7,
      "rating": "PG-13",
      "length": 104,
      "director": "Mel Brooks",
      "stars": [
                {"name": "Cary Elwes", "imdb": "nm0000144", "role": "Robin Hood"},
                {"name": "Richard Lewis", "imdb": "nm0507659", "role": "Prince John"},
                {"name": "Roger Rees", "imdb": "nm0715953", "role": "Sheriff of Rottingham"},
                {"name": "Amy Yasbeck", "imdb": "nm0001865", "role": "Marian"}
      ]
    }
  }
}

# Box is a conversion_box by default, pass in `conversion_box=False` to disable that behavior
# Explicitly tell Diot to convert dict/list inside
movie_diot = Diot(movie_data)

movie_diot.movies.Robin_Hood_Men_in_Tights.imdb_stars
# 6.7

movie_diot.movies.Spaceballs.stars[0].name
# 'Mel Brooks'

# Different as box, you have to use Diot for new data in a list
movie_diot.movies.Spaceballs.stars.append(
	Diot({"name": "Bill Pullman", "imdb": "nm0000597", "role": "Lone Starr"}))
movie_diot.movies.Spaceballs.stars[-1].role
# 'Lone Starr'
```

## Install
```shell
pip install -U diot
```

## API

https://pwwang.github.io/diot/api/diot/


## Usage

### Diot

Instantiated the same ways as `dict`
```python
Diot({'data': 2, 'count': 5})
Diot(data=2, count=5)
Diot({'data': 2, 'count': 1}, count=5)
Diot([('data', 2), ('count', 5)])

# All will create
# Diot([('data', 2), ('count', 5)], diot_nest = True, diot_transform = 'safe')
```

Same as `python-box`, `Diot` is a subclass of dict which overrides some base functionality to make sure everything stored in the dict can be accessed as an attribute or key value.

```python
diot = Diot({'data': 2, 'count': 5})
diot.data == diot['data'] == getattr(diot, 'data')
```

By default, diot uses a safe transformation to transform keys into safe names that can be accessed by `diot.xxx`
```python
dt = Diot({"321 Is a terrible Key!": "yes, really"})
dt._321_Is_a_terrible_Key_
# 'yes, really'
```

Different as `python-box`, duplicate attributes are not allowed.
```python
dt = Diot({"!bad!key!": "yes, really", ".bad.key.": "no doubt"})
# KeyError
```

Use different transform functions:

```python
dt = Diot(oneTwo = 12, diot_transform = 'snake_case')
# or use alias:
# dt = SnakeDiot(oneTwo = 12)
dt.one_two == dt['one_two'] == dt['oneTwo'] == 12

dt = Diot(one_two = 12, diot_transform = 'camel_case')
# or use alias:
# dt = CamelDiot(one_two = 12)
dt.oneTwo == dt['one_two'] == dt['oneTwo'] == 12

dt = Diot(one_two = 12, diot_transform = 'upper')
dt.ONE_TWO == dt['one_two'] == dt['ONETWO'] == 12

dt = Diot(ONE_TWO = 12, diot_transform = 'lower')
dt.one_two == dt['ONE_TWO'] == dt['one_two'] == 12
```

Use your own transform function:

```python
import inflection

dt = Diot(post = 10, diot_transform = inflection.pluralize)
dt.posts == dt['posts'] == dt['post'] == 10
```

### OrderedDiot
```python
diot_of_order = OrderedDiot()
diot_of_order.c = 1
diot_of_order.a = 2
diot_of_order.d = 3

list(diot_of_order.keys()) == ['c', 'a', 'd']

# insertion allowed for OrderedDiot
od = OrderedDiot()
od.insert(0, "c", "d")
od.insert(None, "x", "y")
od.insert_before('c', "e", "f")
od.insert_after("a", ("g", "h"))

od2 = OrderedDiot()
od2.a1 = 'b1'
od2.c1 = 'd1'
od.insert(-1, od2)

od3 = OrderedDiot()
od3.a2 = 'b2'
od3.c2 = 'd2'
od.insert_before('c', od3)
```

### FrozenDiot

```python
fd = FrozenDiot(a=1, b=3)
fd.c = 3 # DiotFrozenError
with fd.thaw():
    fd.c = 3
fd.c == 3
```

### Missing key handler

```python
d = Diot(a=1, b=2, diot_missing=ValueError)
d['c'] # ValueError
d.c # AttributeError from ValueError

d = Diot(a=1, b=2, diot_missing=ValueError("Custom message"))

d = Diot(a=1, b=2, diot_missing=None)
# d.c is None

d = Diot(a=1, b=2, diot_missing=lambda key, diot: diot.a + diot.b)
# d.c == 3
```

[1]: https://img.shields.io/pypi/v/diot?style=flat-square
[2]: https://pypi.org/project/diot/
[3]: https://img.shields.io/github/tag/pwwang/diot?style=flat-square
[4]: https://github.com/pwwang/diot
[5]: https://img.shields.io/github/actions/workflow/status/pwwang/diot/docs.yml?label=docs&style=flat-square
[6]: https://img.shields.io/github/actions/workflow/status/pwwang/diot/build.yml?style=flat-square
[7]: https://img.shields.io/codacy/grade/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square
[8]: https://app.codacy.com/gh/pwwang/diot/dashboard
[9]: https://img.shields.io/codacy/coverage/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square
[10]: https://img.shields.io/pypi/pyversions/diot?style=flat-square

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/pwwang/diot",
    "name": "diot",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "pwwang",
    "author_email": "pwwang@pwwang.com",
    "download_url": "https://files.pythonhosted.org/packages/a7/cf/60841b2d548049a778ff2791648d66c49c39733cefbfdac5e4f6f7b22c41/diot-0.2.3.tar.gz",
    "platform": null,
    "description": "![Logo](https://raw.githubusercontent.com/pwwang/diot/master/logo.png)\n\n[![pypi][1]][2] [![tag][3]][4] [![codacy quality][7]][8] [![coverage][9]][8] ![pyver][10] ![building][6] ![docs][5]\n\nPython dictionary with dot notation (A re-implementation of [python-box](https://github.com/cdgriffith/Box) with some issues fixed and simplified)\n\n```python\nfrom diot import Diot\n\nmovie_data = {\n  \"movies\": {\n    \"Spaceballs\": {\n      \"imdb stars\": 7.1,\n      \"rating\": \"PG\",\n      \"length\": 96,\n      \"director\": \"Mel Brooks\",\n      \"stars\": [{\"name\": \"Mel Brooks\", \"imdb\": \"nm0000316\", \"role\": \"President Skroob\"},\n                {\"name\": \"John Candy\",\"imdb\": \"nm0001006\", \"role\": \"Barf\"},\n                {\"name\": \"Rick Moranis\", \"imdb\": \"nm0001548\", \"role\": \"Dark Helmet\"}\n      ]\n    },\n    \"Robin Hood: Men in Tights\": {\n      \"imdb stars\": 6.7,\n      \"rating\": \"PG-13\",\n      \"length\": 104,\n      \"director\": \"Mel Brooks\",\n      \"stars\": [\n                {\"name\": \"Cary Elwes\", \"imdb\": \"nm0000144\", \"role\": \"Robin Hood\"},\n                {\"name\": \"Richard Lewis\", \"imdb\": \"nm0507659\", \"role\": \"Prince John\"},\n                {\"name\": \"Roger Rees\", \"imdb\": \"nm0715953\", \"role\": \"Sheriff of Rottingham\"},\n                {\"name\": \"Amy Yasbeck\", \"imdb\": \"nm0001865\", \"role\": \"Marian\"}\n      ]\n    }\n  }\n}\n\n# Box is a conversion_box by default, pass in `conversion_box=False` to disable that behavior\n# Explicitly tell Diot to convert dict/list inside\nmovie_diot = Diot(movie_data)\n\nmovie_diot.movies.Robin_Hood_Men_in_Tights.imdb_stars\n# 6.7\n\nmovie_diot.movies.Spaceballs.stars[0].name\n# 'Mel Brooks'\n\n# Different as box, you have to use Diot for new data in a list\nmovie_diot.movies.Spaceballs.stars.append(\n\tDiot({\"name\": \"Bill Pullman\", \"imdb\": \"nm0000597\", \"role\": \"Lone Starr\"}))\nmovie_diot.movies.Spaceballs.stars[-1].role\n# 'Lone Starr'\n```\n\n## Install\n```shell\npip install -U diot\n```\n\n## API\n\nhttps://pwwang.github.io/diot/api/diot/\n\n\n## Usage\n\n### Diot\n\nInstantiated the same ways as `dict`\n```python\nDiot({'data': 2, 'count': 5})\nDiot(data=2, count=5)\nDiot({'data': 2, 'count': 1}, count=5)\nDiot([('data', 2), ('count', 5)])\n\n# All will create\n# Diot([('data', 2), ('count', 5)], diot_nest = True, diot_transform = 'safe')\n```\n\nSame as `python-box`, `Diot` is a subclass of dict which overrides some base functionality to make sure everything stored in the dict can be accessed as an attribute or key value.\n\n```python\ndiot = Diot({'data': 2, 'count': 5})\ndiot.data == diot['data'] == getattr(diot, 'data')\n```\n\nBy default, diot uses a safe transformation to transform keys into safe names that can be accessed by `diot.xxx`\n```python\ndt = Diot({\"321 Is a terrible Key!\": \"yes, really\"})\ndt._321_Is_a_terrible_Key_\n# 'yes, really'\n```\n\nDifferent as `python-box`, duplicate attributes are not allowed.\n```python\ndt = Diot({\"!bad!key!\": \"yes, really\", \".bad.key.\": \"no doubt\"})\n# KeyError\n```\n\nUse different transform functions:\n\n```python\ndt = Diot(oneTwo = 12, diot_transform = 'snake_case')\n# or use alias:\n# dt = SnakeDiot(oneTwo = 12)\ndt.one_two == dt['one_two'] == dt['oneTwo'] == 12\n\ndt = Diot(one_two = 12, diot_transform = 'camel_case')\n# or use alias:\n# dt = CamelDiot(one_two = 12)\ndt.oneTwo == dt['one_two'] == dt['oneTwo'] == 12\n\ndt = Diot(one_two = 12, diot_transform = 'upper')\ndt.ONE_TWO == dt['one_two'] == dt['ONETWO'] == 12\n\ndt = Diot(ONE_TWO = 12, diot_transform = 'lower')\ndt.one_two == dt['ONE_TWO'] == dt['one_two'] == 12\n```\n\nUse your own transform function:\n\n```python\nimport inflection\n\ndt = Diot(post = 10, diot_transform = inflection.pluralize)\ndt.posts == dt['posts'] == dt['post'] == 10\n```\n\n### OrderedDiot\n```python\ndiot_of_order = OrderedDiot()\ndiot_of_order.c = 1\ndiot_of_order.a = 2\ndiot_of_order.d = 3\n\nlist(diot_of_order.keys()) == ['c', 'a', 'd']\n\n# insertion allowed for OrderedDiot\nod = OrderedDiot()\nod.insert(0, \"c\", \"d\")\nod.insert(None, \"x\", \"y\")\nod.insert_before('c', \"e\", \"f\")\nod.insert_after(\"a\", (\"g\", \"h\"))\n\nod2 = OrderedDiot()\nod2.a1 = 'b1'\nod2.c1 = 'd1'\nod.insert(-1, od2)\n\nod3 = OrderedDiot()\nod3.a2 = 'b2'\nod3.c2 = 'd2'\nod.insert_before('c', od3)\n```\n\n### FrozenDiot\n\n```python\nfd = FrozenDiot(a=1, b=3)\nfd.c = 3 # DiotFrozenError\nwith fd.thaw():\n    fd.c = 3\nfd.c == 3\n```\n\n### Missing key handler\n\n```python\nd = Diot(a=1, b=2, diot_missing=ValueError)\nd['c'] # ValueError\nd.c # AttributeError from ValueError\n\nd = Diot(a=1, b=2, diot_missing=ValueError(\"Custom message\"))\n\nd = Diot(a=1, b=2, diot_missing=None)\n# d.c is None\n\nd = Diot(a=1, b=2, diot_missing=lambda key, diot: diot.a + diot.b)\n# d.c == 3\n```\n\n[1]: https://img.shields.io/pypi/v/diot?style=flat-square\n[2]: https://pypi.org/project/diot/\n[3]: https://img.shields.io/github/tag/pwwang/diot?style=flat-square\n[4]: https://github.com/pwwang/diot\n[5]: https://img.shields.io/github/actions/workflow/status/pwwang/diot/docs.yml?label=docs&style=flat-square\n[6]: https://img.shields.io/github/actions/workflow/status/pwwang/diot/build.yml?style=flat-square\n[7]: https://img.shields.io/codacy/grade/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square\n[8]: https://app.codacy.com/gh/pwwang/diot/dashboard\n[9]: https://img.shields.io/codacy/coverage/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square\n[10]: https://img.shields.io/pypi/pyversions/diot?style=flat-square\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python dictionary with dot notation.",
    "version": "0.2.3",
    "project_urls": {
        "Homepage": "https://github.com/pwwang/diot",
        "Repository": "https://github.com/pwwang/diot"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8e3498edb1a36df6dda6ebaa100e54e65dde5ccfb85e6efd0d7c23113c9604ef",
                "md5": "eb3366fe4cd537bceea6886d2990a161",
                "sha256": "defd4556bd961327cbfd497f63fcb9d0d79a649bbc8932f26d94dd25a7832e1c"
            },
            "downloads": -1,
            "filename": "diot-0.2.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "eb3366fe4cd537bceea6886d2990a161",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7,<4.0",
            "size": 11529,
            "upload_time": "2023-10-20T22:32:45",
            "upload_time_iso_8601": "2023-10-20T22:32:45.311209Z",
            "url": "https://files.pythonhosted.org/packages/8e/34/98edb1a36df6dda6ebaa100e54e65dde5ccfb85e6efd0d7c23113c9604ef/diot-0.2.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a7cf60841b2d548049a778ff2791648d66c49c39733cefbfdac5e4f6f7b22c41",
                "md5": "d9e773e1e0992a161fc2c369d61ee71a",
                "sha256": "0b8ccbe3813acda67665ea9025d4eea7f73b2df4e2ab16c5c3f1da8b0dbba4cf"
            },
            "downloads": -1,
            "filename": "diot-0.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "d9e773e1e0992a161fc2c369d61ee71a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7,<4.0",
            "size": 13370,
            "upload_time": "2023-10-20T22:32:46",
            "upload_time_iso_8601": "2023-10-20T22:32:46.747476Z",
            "url": "https://files.pythonhosted.org/packages/a7/cf/60841b2d548049a778ff2791648d66c49c39733cefbfdac5e4f6f7b22c41/diot-0.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-20 22:32:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "pwwang",
    "github_project": "diot",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "tox": true,
    "lcname": "diot"
}
        
Elapsed time: 0.28034s