dynamic-yaml


Namedynamic-yaml JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryEnables self referential yaml entries
upload_time2024-04-09 20:52:43
maintainerNone
docs_urlNone
authorNone
requires_python>=3.0
licenseMIT License Copyright (c) 2022 Liam H. Childs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords yaml configuration
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![](https://github.com/childsish/dynamic-yaml/workflows/Project%20Tests/badge.svg)

dynamic-yaml
============

Dynamic YAML is a couple of classes and functions that add extra functionality to YAML that turns it into a great configuration language for Python. If you prefer JSON, then see [dynamic-json][dynamic-json].

YAML already provides:

* A very readable and clean syntax
* Infinitely nestable key:value pairs
* Sequence types
* A regulated portable syntax that conforms to strict standards

In addition, the PyYAML parser provides:

* Automatic type identification (a result of implementing the YAML standard)

Finally, the classes introduced by Dynamic YAML enable:

* Dynamic string resolution

Dynamic PyYAML requires PyYAML (https://bitbucket.org/xi/pyyaml).

Usage
-----

The key feature that was introduced is the ability for a string scalar to reference other parts of the configuration tree.
This is done using the Python string formatting syntax.
The characters '{' and '}' enclose a reference to another entry in the configuration structure.
The reference takes the form key1.key2 where key1 maps to another mapping object and can be found in the root mapping, and key2 can be found in key1's mapping object.
Multiple levels of nesting can be used (eg. key1.key2.key3 etc...).
If you need brace literals, they can be escaped by doubling them up, as described by the Python format string [documentation](https://docs.python.org/3/library/string.html#formatstrings). 

An example yaml configuration:
```yaml
project_name: hello-world
dirs:
    home: /home/user
    venv: "{dirs.home}/venvs/{project_name}"
    bin: "{dirs.venv}/bin"
    data: "{dirs.venv}/data"
    errors: "{dirs.data}/errors"
    sessions: "{dirs.data}/sessions"
    databases: "{dirs.data}/databases"
    output: "{dirs.data}/output-{parameters.parameter1}-{parameters.parameter2}"
exes:
    main: "{dirs.bin}/main"
    test: tests
parameters:
    parameter1: a
    parameter2: b
```

Reading in a yaml file:

```python
import dynamic_yaml

with open('/path/to/file.yaml') as fileobj:
    cfg = dynamic_yaml.load(fileobj)
    assert cfg.dirs.venv == '/home/user/venvs/hello-world'
    assert cfg.dirs.output == '/home/user/venvs/hello-world/data/output-a-b'
```

As the variables are dynamically resolved, it is also possible to combine this with `argparse`:

```python
import dynamic_yaml

from argparse import ArgumentParser

with open('/path/to/file.yaml') as fileobj:
    cfg = dynamic_yaml.load(fileobj)
    parser = ArgumentParser()
    parser.add_argument('--parameter1')
    parser.add_argument('--parameter2')
    parser.parse_args('--parameter1 c --parameter2 d'.split(), namespace=cfg.parameters)
    assert cfg.dirs.output == '/home/user/venvs/hello-world/data/output-c-d'
```

Writing yaml will resolve all references:

```python
import dynamic_yaml
import yaml

with open('/path/to/file.yaml') as fileobj:
    cfg = dynamic_yaml.load(fileobj)
    assert yaml.safe_load(dynamic_yaml.dump(cfg)) == yaml.safe_load('''
project_name: hello-world
dirs:
    home: /home/user
    venv: /home/user/venvs/hello-world
    bin: /home/user/venvs/hello-world/bin
    data: /home/user/venvs/hello-world/data
    errors: /home/user/venvs/hello-world/data/errors
    sessions: /home/user/venvs/hello-world/data/sessions
    databases: /home/user/venvs/hello-world/data/databases
    output: /home/user/venvs/hello-world/data/output-a-b}
exes:
    main: /home/user/venvs/hello-world/bin/main
    test: tests
parameters:
  - 0.5
  - 0.1
''')
```

Installation
------------

To install, simply run:

```bash
pip install dynamic-yaml
```

Restrictions
------------

Due to the short amount of time I was willing to spend on working upon this, there are a few restrictions that I could not overcome.

* **Wild card strings must be surrounded by quotes.**
Braces ('{' and '}') in a YAML file usually enclose a mapping object.
However, braces are also used by the Python string formatting syntax to enclose a reference.
As there is no way to change either of these easily, strings that look like a yaml mapping must be explicitly declared using single or double quotes to enclose them.
For example:
  ```yaml
  quotes_needed: '{variable}'
  ```
* **Certain keys can only be used via `__getitem__` and not `__getattr__`.**
Because `dict` comes with it's own set of attributes that are always resolved first, the values for the following keys must be gotten using the item getter rather than the attribute getter (eg. config['items'] vs. config.items):
  * append
  * extend
  * insert
  * remove
  * pop
  * clear
  * index
  * count
  * sort
  * reverse
  * copy 

[dynamic-json]: https://github.com/childsish/dynamic-json

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "dynamic-yaml",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.0",
    "maintainer_email": null,
    "keywords": "yaml, configuration",
    "author": null,
    "author_email": "\"Liam H. Childs\" <liam.h.childs@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e1/7e/161521ea880a2e224430bc8adac8b272a11809240f4bd15ed9680fde27a3/dynamic-yaml-2.0.0.tar.gz",
    "platform": null,
    "description": "![](https://github.com/childsish/dynamic-yaml/workflows/Project%20Tests/badge.svg)\n\ndynamic-yaml\n============\n\nDynamic YAML is a couple of classes and functions that add extra functionality to YAML that turns it into a great configuration language for Python. If you prefer JSON, then see [dynamic-json][dynamic-json].\n\nYAML already provides:\n\n* A very readable and clean syntax\n* Infinitely nestable key:value pairs\n* Sequence types\n* A regulated portable syntax that conforms to strict standards\n\nIn addition, the PyYAML parser provides:\n\n* Automatic type identification (a result of implementing the YAML standard)\n\nFinally, the classes introduced by Dynamic YAML enable:\n\n* Dynamic string resolution\n\nDynamic PyYAML requires PyYAML (https://bitbucket.org/xi/pyyaml).\n\nUsage\n-----\n\nThe key feature that was introduced is the ability for a string scalar to reference other parts of the configuration tree.\nThis is done using the Python string formatting syntax.\nThe characters '{' and '}' enclose a reference to another entry in the configuration structure.\nThe reference takes the form key1.key2 where key1 maps to another mapping object and can be found in the root mapping, and key2 can be found in key1's mapping object.\nMultiple levels of nesting can be used (eg. key1.key2.key3 etc...).\nIf you need brace literals, they can be escaped by doubling them up, as described by the Python format string [documentation](https://docs.python.org/3/library/string.html#formatstrings). \n\nAn example yaml configuration:\n```yaml\nproject_name: hello-world\ndirs:\n    home: /home/user\n    venv: \"{dirs.home}/venvs/{project_name}\"\n    bin: \"{dirs.venv}/bin\"\n    data: \"{dirs.venv}/data\"\n    errors: \"{dirs.data}/errors\"\n    sessions: \"{dirs.data}/sessions\"\n    databases: \"{dirs.data}/databases\"\n    output: \"{dirs.data}/output-{parameters.parameter1}-{parameters.parameter2}\"\nexes:\n    main: \"{dirs.bin}/main\"\n    test: tests\nparameters:\n    parameter1: a\n    parameter2: b\n```\n\nReading in a yaml file:\n\n```python\nimport dynamic_yaml\n\nwith open('/path/to/file.yaml') as fileobj:\n    cfg = dynamic_yaml.load(fileobj)\n    assert cfg.dirs.venv == '/home/user/venvs/hello-world'\n    assert cfg.dirs.output == '/home/user/venvs/hello-world/data/output-a-b'\n```\n\nAs the variables are dynamically resolved, it is also possible to combine this with `argparse`:\n\n```python\nimport dynamic_yaml\n\nfrom argparse import ArgumentParser\n\nwith open('/path/to/file.yaml') as fileobj:\n    cfg = dynamic_yaml.load(fileobj)\n    parser = ArgumentParser()\n    parser.add_argument('--parameter1')\n    parser.add_argument('--parameter2')\n    parser.parse_args('--parameter1 c --parameter2 d'.split(), namespace=cfg.parameters)\n    assert cfg.dirs.output == '/home/user/venvs/hello-world/data/output-c-d'\n```\n\nWriting yaml will resolve all references:\n\n```python\nimport dynamic_yaml\nimport yaml\n\nwith open('/path/to/file.yaml') as fileobj:\n    cfg = dynamic_yaml.load(fileobj)\n    assert yaml.safe_load(dynamic_yaml.dump(cfg)) == yaml.safe_load('''\nproject_name: hello-world\ndirs:\n    home: /home/user\n    venv: /home/user/venvs/hello-world\n    bin: /home/user/venvs/hello-world/bin\n    data: /home/user/venvs/hello-world/data\n    errors: /home/user/venvs/hello-world/data/errors\n    sessions: /home/user/venvs/hello-world/data/sessions\n    databases: /home/user/venvs/hello-world/data/databases\n    output: /home/user/venvs/hello-world/data/output-a-b}\nexes:\n    main: /home/user/venvs/hello-world/bin/main\n    test: tests\nparameters:\n  - 0.5\n  - 0.1\n''')\n```\n\nInstallation\n------------\n\nTo install, simply run:\n\n```bash\npip install dynamic-yaml\n```\n\nRestrictions\n------------\n\nDue to the short amount of time I was willing to spend on working upon this, there are a few restrictions that I could not overcome.\n\n* **Wild card strings must be surrounded by quotes.**\nBraces ('{' and '}') in a YAML file usually enclose a mapping object.\nHowever, braces are also used by the Python string formatting syntax to enclose a reference.\nAs there is no way to change either of these easily, strings that look like a yaml mapping must be explicitly declared using single or double quotes to enclose them.\nFor example:\n  ```yaml\n  quotes_needed: '{variable}'\n  ```\n* **Certain keys can only be used via `__getitem__` and not `__getattr__`.**\nBecause `dict` comes with it's own set of attributes that are always resolved first, the values for the following keys must be gotten using the item getter rather than the attribute getter (eg. config['items'] vs. config.items):\n  * append\n  * extend\n  * insert\n  * remove\n  * pop\n  * clear\n  * index\n  * count\n  * sort\n  * reverse\n  * copy \n\n[dynamic-json]: https://github.com/childsish/dynamic-json\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2022 Liam H. Childs  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Enables self referential yaml entries",
    "version": "2.0.0",
    "project_urls": {
        "Homepage": "https://github.com/childsish/dynamic-yaml"
    },
    "split_keywords": [
        "yaml",
        " configuration"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "036694c3754092db07aad97213c11be8e699c1aac5e031232974be0bb303d59a",
                "md5": "39cfdb45caa96020cecaf12791f88391",
                "sha256": "1df58ccb4e43a25e2dbbc795d830a5bc548a2de58a14f8b902e7a20545574d0d"
            },
            "downloads": -1,
            "filename": "dynamic_yaml-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "39cfdb45caa96020cecaf12791f88391",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.0",
            "size": 6266,
            "upload_time": "2024-04-09T20:52:42",
            "upload_time_iso_8601": "2024-04-09T20:52:42.192935Z",
            "url": "https://files.pythonhosted.org/packages/03/66/94c3754092db07aad97213c11be8e699c1aac5e031232974be0bb303d59a/dynamic_yaml-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e17e161521ea880a2e224430bc8adac8b272a11809240f4bd15ed9680fde27a3",
                "md5": "a7af466189c1c87ea58980f4a0a8da69",
                "sha256": "7dd6cf3ed4dbeb5e068bf156eeb0808ac5cb92df397a436346b4b849f303b60b"
            },
            "downloads": -1,
            "filename": "dynamic-yaml-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a7af466189c1c87ea58980f4a0a8da69",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.0",
            "size": 6873,
            "upload_time": "2024-04-09T20:52:43",
            "upload_time_iso_8601": "2024-04-09T20:52:43.526274Z",
            "url": "https://files.pythonhosted.org/packages/e1/7e/161521ea880a2e224430bc8adac8b272a11809240f4bd15ed9680fde27a3/dynamic-yaml-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-09 20:52:43",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "childsish",
    "github_project": "dynamic-yaml",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "dynamic-yaml"
}
        
Elapsed time: 0.25314s