alphaconf


Namealphaconf JSON
Version 0.5.0 PyPI version JSON
download
home_page
SummaryWrite simple scripts leveraging omegaconf
upload_time2023-12-04 22:24:01
maintainer
docs_urlNone
author
requires_python>=3.9
licenseBSD License
keywords configuration omegaconf pydantic script
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # AlphaConf

[![PyPI version](https://badge.fury.io/py/alphaconf.svg)](https://pypi.org/project/alphaconf/)

A small library to ease writing parameterized scripts.
The goal is to execute a single script and be able to overwrite the parameters
easily.
The configuration is based on [OmegaConf].
Optionally, loading from toml or using [pydantic] is possible.

To run multiple related tasks, there is an integration with
[invoke](https://www.pyinvoke.org).
If you need something more complex, like running multiple instances of the
script, take a look at [hydra-core](https://hydra.cc) or use another script
to launch multiple instances.

## Demo and application

To run an application, you need...

```python
# myapp.py
import alphaconf
import logging
# define the default values and helpers
alphaconf.setup_configuration({
    "server.url": "http://default",
}, {
    "server.url": "The URL to show here",
})

def main():
    log = logging.getLogger()
    log.info('server.url:', alphaconf.get('server.url'))
    log.info('has server.user:', alphaconf.get('server.user', bool, default=False))

if __name__ == '__main__':
    alphaconf.cli.run(main)
```

Invoking:
```bash
python myapp.py server.url=http://github.com
```

During an *interactive session*, you can set the application in the current
context.
```python
# import other modules
import alphaconf.interactive
alphaconf.interactive.mount()
alphaconf.interactive.load_configuration_file('path')
```

Check the [DEMO](./demo.ipynb) for more examples.

## How the configuration is loaded

When running a program, first dotenv is used to load environment variables
from a `.env` file - this is optional.

Then configuration is built from:

- default configurations defined using (`alphaconf.setup_configuration`)
- `application` key is generated
- `PYTHON_ALPHACONF` environment variable may contain a path to load
- configuration files from configuration directories (using application name)
- environment variables based on key prefixes,
  except "BASE" and "PYTHON"; \
  if you have a configuration key "abc", all environment variables starting
  with "ABC_" will be loaded, for example "ABC_HELLO=a" would set "abc.hello=a"
- key-values from the program arguments

Finally, the configuration is fully resolved and logging is configured.

## Configuration templates and resolvers

Configuration values are resolved by [OmegaConf].
Some of the resolvers (standard and custom):
- `${oc.env:USER,me}`: resolve the environment variable USER
  with a default value "me"
- `${oc.select:config_path}`: resolve to another configuration value
- `${read_text:file_path}`: read text contents of a file as `str`
- `${read_bytes:file_path}`: read contents of a file as `bytes`
- `${read_strip:file_path}`: read text contents of a file as strip spaces

The *oc.select* is used to build multiple templates for configurations
by providing base configurations.
An argument `--select key=template` is a shortcut for
`key=${oc.select:base.key.template}`.
So, `logging: ${oc.select:base.logging.default}` resolves to the configuration
dict defined in base.logging.default and you can select it using
`--select logging=default`.

## Configuration values and integrations

### Typed-configuration

You can use [OmegaConf] with [pydantic] to *get* typed values.
```python
class MyConf(pydantic.BaseModel):
    value: int = 0

    def build(self):
        # use as a factory pattern to create more complex objects
        # for example, a connection to the database
        return self.value * 2

# setup the configuration
alphaconf.setup_configuration(MyConf, prefix='a')
# read the value
alphaconf.get('a', MyConf)
v = alphaconf.get(MyConf)  # because it's registered as a type
```

### Secrets

When showing the configuration, by default configuration keys which are
secrets, keys or passwords will be masked.
You can read values or passwords from files, by using the template
`${read_strip:/path_to_file}`
or, more securely, read the file in the code
`alphaconf.get('secret_file', Path).read_text().strip()`.

### Inject parameters

We can inject default values to functions from the configuration.
Either one by one, where we can map a factory function or a configuration key.
Or inject all automatically base on the parameter name.

```python
from alphaconf.inject import inject, inject_auto

@inject('name', 'application.name')
@inject_auto(ignore={'name'})
def main(name: str, example=None):
    pass

# similar to
def main(name: str=None, example=None):
    if name is None:
        name = alphaconf.get('application.name', str)
    if example is None:
        example = alphaconf.get('example', default=example)
    ...
```

### Invoke integration

Just add the lines below to parameterize invoke.
Note that the argument parsing to overwrite configuration will work only
when the script is directly called.

```python
import alphaconf.invoke
ns = alphaconf.invoke.collection(globals())
alphaconf.setup_configuration({'backup': 'all'})
alphaconf.invoke.run(__name__, ns)
```

## Way to 1.0
- Run a specific function `alphaconf my.module.main`:
  find functions and inject args
- Install completions for bash `alphaconf --install-autocompletion`

[OmegaConf]: https://omegaconf.readthedocs.io/
[pydantic]: https://docs.pydantic.dev/latest/

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "alphaconf",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "",
    "keywords": "configuration,omegaconf,pydantic,script",
    "author": "",
    "author_email": "Krzysztof Magusiak <chrmag@poczta.onet.pl>",
    "download_url": "https://files.pythonhosted.org/packages/65/63/4d4244599ef94fb1f7bf35f55d2304067f3b742315ec8ebd9d1a9ce577b8/alphaconf-0.5.0.tar.gz",
    "platform": null,
    "description": "# AlphaConf\n\n[![PyPI version](https://badge.fury.io/py/alphaconf.svg)](https://pypi.org/project/alphaconf/)\n\nA small library to ease writing parameterized scripts.\nThe goal is to execute a single script and be able to overwrite the parameters\neasily.\nThe configuration is based on [OmegaConf].\nOptionally, loading from toml or using [pydantic] is possible.\n\nTo run multiple related tasks, there is an integration with\n[invoke](https://www.pyinvoke.org).\nIf you need something more complex, like running multiple instances of the\nscript, take a look at [hydra-core](https://hydra.cc) or use another script\nto launch multiple instances.\n\n## Demo and application\n\nTo run an application, you need...\n\n```python\n# myapp.py\nimport alphaconf\nimport logging\n# define the default values and helpers\nalphaconf.setup_configuration({\n    \"server.url\": \"http://default\",\n}, {\n    \"server.url\": \"The URL to show here\",\n})\n\ndef main():\n    log = logging.getLogger()\n    log.info('server.url:', alphaconf.get('server.url'))\n    log.info('has server.user:', alphaconf.get('server.user', bool, default=False))\n\nif __name__ == '__main__':\n    alphaconf.cli.run(main)\n```\n\nInvoking:\n```bash\npython myapp.py server.url=http://github.com\n```\n\nDuring an *interactive session*, you can set the application in the current\ncontext.\n```python\n# import other modules\nimport alphaconf.interactive\nalphaconf.interactive.mount()\nalphaconf.interactive.load_configuration_file('path')\n```\n\nCheck the [DEMO](./demo.ipynb) for more examples.\n\n## How the configuration is loaded\n\nWhen running a program, first dotenv is used to load environment variables\nfrom a `.env` file - this is optional.\n\nThen configuration is built from:\n\n- default configurations defined using (`alphaconf.setup_configuration`)\n- `application` key is generated\n- `PYTHON_ALPHACONF` environment variable may contain a path to load\n- configuration files from configuration directories (using application name)\n- environment variables based on key prefixes,\n  except \"BASE\" and \"PYTHON\"; \\\n  if you have a configuration key \"abc\", all environment variables starting\n  with \"ABC_\" will be loaded, for example \"ABC_HELLO=a\" would set \"abc.hello=a\"\n- key-values from the program arguments\n\nFinally, the configuration is fully resolved and logging is configured.\n\n## Configuration templates and resolvers\n\nConfiguration values are resolved by [OmegaConf].\nSome of the resolvers (standard and custom):\n- `${oc.env:USER,me}`: resolve the environment variable USER\n  with a default value \"me\"\n- `${oc.select:config_path}`: resolve to another configuration value\n- `${read_text:file_path}`: read text contents of a file as `str`\n- `${read_bytes:file_path}`: read contents of a file as `bytes`\n- `${read_strip:file_path}`: read text contents of a file as strip spaces\n\nThe *oc.select* is used to build multiple templates for configurations\nby providing base configurations.\nAn argument `--select key=template` is a shortcut for\n`key=${oc.select:base.key.template}`.\nSo, `logging: ${oc.select:base.logging.default}` resolves to the configuration\ndict defined in base.logging.default and you can select it using\n`--select logging=default`.\n\n## Configuration values and integrations\n\n### Typed-configuration\n\nYou can use [OmegaConf] with [pydantic] to *get* typed values.\n```python\nclass MyConf(pydantic.BaseModel):\n    value: int = 0\n\n    def build(self):\n        # use as a factory pattern to create more complex objects\n        # for example, a connection to the database\n        return self.value * 2\n\n# setup the configuration\nalphaconf.setup_configuration(MyConf, prefix='a')\n# read the value\nalphaconf.get('a', MyConf)\nv = alphaconf.get(MyConf)  # because it's registered as a type\n```\n\n### Secrets\n\nWhen showing the configuration, by default configuration keys which are\nsecrets, keys or passwords will be masked.\nYou can read values or passwords from files, by using the template\n`${read_strip:/path_to_file}`\nor, more securely, read the file in the code\n`alphaconf.get('secret_file', Path).read_text().strip()`.\n\n### Inject parameters\n\nWe can inject default values to functions from the configuration.\nEither one by one, where we can map a factory function or a configuration key.\nOr inject all automatically base on the parameter name.\n\n```python\nfrom alphaconf.inject import inject, inject_auto\n\n@inject('name', 'application.name')\n@inject_auto(ignore={'name'})\ndef main(name: str, example=None):\n    pass\n\n# similar to\ndef main(name: str=None, example=None):\n    if name is None:\n        name = alphaconf.get('application.name', str)\n    if example is None:\n        example = alphaconf.get('example', default=example)\n    ...\n```\n\n### Invoke integration\n\nJust add the lines below to parameterize invoke.\nNote that the argument parsing to overwrite configuration will work only\nwhen the script is directly called.\n\n```python\nimport alphaconf.invoke\nns = alphaconf.invoke.collection(globals())\nalphaconf.setup_configuration({'backup': 'all'})\nalphaconf.invoke.run(__name__, ns)\n```\n\n## Way to 1.0\n- Run a specific function `alphaconf my.module.main`:\n  find functions and inject args\n- Install completions for bash `alphaconf --install-autocompletion`\n\n[OmegaConf]: https://omegaconf.readthedocs.io/\n[pydantic]: https://docs.pydantic.dev/latest/\n",
    "bugtrack_url": null,
    "license": "BSD License",
    "summary": "Write simple scripts leveraging omegaconf",
    "version": "0.5.0",
    "project_urls": {
        "Homepage": "https://github.com/kmagusiak/alphaconf"
    },
    "split_keywords": [
        "configuration",
        "omegaconf",
        "pydantic",
        "script"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ed56568a060f7a8da17a4cdbac3e291396ee13d422dd16e8de77a0cf1cbad1f1",
                "md5": "5ee560f98648690fbe2517009f4d7938",
                "sha256": "b61cc075ccfe07a7aaf22090d13cca5d546dfb571b47406d9e8809f0e45719b2"
            },
            "downloads": -1,
            "filename": "alphaconf-0.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5ee560f98648690fbe2517009f4d7938",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 25047,
            "upload_time": "2023-12-04T22:23:59",
            "upload_time_iso_8601": "2023-12-04T22:23:59.377359Z",
            "url": "https://files.pythonhosted.org/packages/ed/56/568a060f7a8da17a4cdbac3e291396ee13d422dd16e8de77a0cf1cbad1f1/alphaconf-0.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "65634d4244599ef94fb1f7bf35f55d2304067f3b742315ec8ebd9d1a9ce577b8",
                "md5": "ffa8226ceb7db770eb405636f5e5e55c",
                "sha256": "153b57289355601d34eb5569ed5031b711204524c5598cf071ed49e0c20e8ce9"
            },
            "downloads": -1,
            "filename": "alphaconf-0.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "ffa8226ceb7db770eb405636f5e5e55c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 31552,
            "upload_time": "2023-12-04T22:24:01",
            "upload_time_iso_8601": "2023-12-04T22:24:01.380131Z",
            "url": "https://files.pythonhosted.org/packages/65/63/4d4244599ef94fb1f7bf35f55d2304067f3b742315ec8ebd9d1a9ce577b8/alphaconf-0.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-04 22:24:01",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "kmagusiak",
    "github_project": "alphaconf",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "alphaconf"
}
        
Elapsed time: 0.33467s