Cock
Cock stands for «configuration file with click». It is a configuration aggregator, which stands on shiny click library.
Reason
No module for click with flat configuration file, which will mimic actual click options. There are click-config and click-config-file, but they targets another goals.
Features
- Aggregate configuration file and cli options into flat configuration object.
- Respect all click checks and conversions (
requiredattribute forbidden, since it breaks internal logic). dict-like, flat, sorted, dot-accessed configuration object.- Entrypoint builder.
License
cock is offered under MIT license.
Requirements
- python 3.7+
Usage
from cock import build_entrypoint, Config, Option
def main(config: Config):
print(config)
options = [
Option("a_b_c", default="foo"),
Option("b_c_d", default="bar"),
]
entrypoint = build_entrypoint(main, options, auto_envvar_prefix="EXAMPLE", show_default=True)
if __name__ == "__main__":
entrypoint(prog_name="example")
This is almost pure click setup:
$ python example.py --help
Usage: example [OPTIONS] [CONFIGURATION_FILE]
Options:
--a-b-c TEXT [default: foo]
--b-c-d TEXT [default: bar]
--help Show this message and exit. [default: False]
But there is a CONFIGURATION_FILE argument. Lets see use cases.
All deafults
$ python example.py
{'configuration_file': None, 'a_b_c': 'foo', 'b_c_d': 'bar'}
From environment variable
$ EXAMPLE_A_B_C=foo-env python example.py
{'configuration_file': None, 'a_b_c': 'foo-env', 'b_c_d': 'bar'}
From cli arguments
$ EXAMPLE_A_B_C=foo-env python example.py --a-b-c foo-cli
{'a_b_c': 'foo-cli', 'configuration_file': None, 'b_c_d': 'bar'}
From configuration yaml file
a-b-c: foo-file
$ EXAMPLE_A_B_C=foo-env python example.py --a-b-c foo-cli config-example.yml
{'a_b_c': 'foo-file', 'configuration_file': '/absolute/path/to/config-example.yml', 'b_c_d': 'bar'}
Priority is obvious: file > cli arguments > env variables
Note: for file a-b-c is the same as a_b_c or a-b_c. Use whatever you prefer.
As described in features paragraph, configuration is flattened before chaining with click options. So all configuration files listed below are equal:
a_b_c: foo-file
a:
b:
c: foo-file
a-b:
c: foo-file
If provided file have key crossings:
a-b_c: foo-file1
a:
b-c: foo-file2
Then RuntimeError will be raised.
cock uses pyyaml library for config loading, so it supports yaml and json formats, but this can be improved later if someone will need more configuration file types.
Configuration can be defined as dictionary too:
from cock import build_entrypoint, Option, Config
def main(config: Config):
print(config)
options = {
"a": {
"b": {
"c": Option(default="foo"),
},
},
"a-b_d": Option(default="bar"),
}
entrypoint = build_entrypoint(main, options, auto_envvar_prefix="EXAMPLE", show_default=True)
if __name__ == "__main__":
entrypoint(prog_name="example")
Note: for dictionaries you can use same rules in naming and structure as for files.
Configuration can be defined as multiple sources:
from cock import build_entrypoint, Option, Config
def main(config: Config):
print(config)
dict_options = {"a-b-c": Option(default="foo")}
list_options = [Option("b_c-d", default="bar")]
entrypoint = build_entrypoint(main, dict_options, list_options,
auto_envvar_prefix="EXAMPLE", show_default=True)
if __name__ == "__main__":
entrypoint(prog_name="example")
You can also gather all defaults from options as a Config:
from cock import get_options_defaults, Option
options = {
"a": {
"b": {
"c": Option(default="foo"),
},
},
}
config = get_options_defaults(options)
assert config == {"a_b_c": "foo"}
assert config.a_b_c == "foo"
Config is an extended (with dot-access) version of sortedcontainers.SortedDict:
>>> from cock import Config
>>> c = Config(b=1, a=2)
Config({'a': 2, 'b': 1})
>>> c["a"], c.b
(2, 1)
>>> c.z
...
KeyError: 'z'
>>> c.items()
SortedItemsView(Config({'a': 2, 'b': 1}))
>>> c["0"] = 0
>>> c
Config({'0': 0, 'a': 2, 'b': 1})
API
def build_entrypoint(
main: Callable[[Config], Any],
*options_stack: Union[dict, List[Union[Option, click.option]]],
**context_settings
) -> Callable[..., Any]:
mainis a user-space function of exactly one argument, a dot-accessed config wrapper.*options_stackis a sequence of dicts and/or lists described above.**context_settingspropagated toclick.commanddecorator.
def get_options_defaults(
*options_stack: Union[dict, List[Union[Option, click.option]]]
) -> Config:
*options_stackis a sequence of dicts and/or lists described above.
class Option(
name: Optional[str] = None,
**attributes)
nameis a name in resultingConfigobject, which passed tomain.namecan be set only once, further set will lead to exception.namefield will be converted to «underscore» view (e.g.a-b_cinternaly will be converted toa_b_c).
**attributespropagated toclick.optiondecorator.requiredattribute forbidden, since it breaks internal logic.
Deprecations and removals
0.11.0
Deprecations:
- Usage of
click.optionas option. build_options_from_dictfunction, since it is obsolete with new api.
Metadata
Release files for cock 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cock-0.11.0.tar.gz | 5.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cock-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.5 kB
Release files / cock-0.11.0.tar.gz
| Download URL | cock-0.11.0.tar.gz |
|---|---|
| Size | 5.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1e2f1a171013b187043baa8dcd99c5ef757c58b4d08dbe83c36c45e15813da8e
|
|
BLAKE2b-256 checksum How to use checksums |
a19e319ae8aa6101ba8c5f5f7d0af9828070719d151e1eadb02a47c16f143b5d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.7
|
Release files / cock-0.11.0-py3-none-any.whl
| Download URL | cock-0.11.0-py3-none-any.whl |
|---|---|
| Size | 5.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d983fdea27556c66e17154ca883e7b3ca2af2d0058fc07b9fea3bb66ba9c3363
|
|
BLAKE2b-256 checksum How to use checksums |
ebccc9147eaa8c2083c37a54e9455b838a5933671ab723a2c02488b575a537df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.7
|
Security for cock 0.11.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.