Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/illuin-tech/configue
A YAML parser with advanced functionalities to ease your application configuration
https://github.com/illuin-tech/configue
configuration environment-variables python yaml
Last synced: about 23 hours ago
JSON representation
A YAML parser with advanced functionalities to ease your application configuration
- Host: GitHub
- URL: https://github.com/illuin-tech/configue
- Owner: illuin-tech
- License: mit
- Created: 2020-02-13T18:22:38.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2025-01-29T12:30:45.000Z (1 day ago)
- Last Synced: 2025-01-29T13:29:48.128Z (1 day ago)
- Topics: configuration, environment-variables, python, yaml
- Language: Python
- Size: 261 KB
- Stars: 33
- Watchers: 7
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
Awesome Lists containing this project
README
Configue
========![CI](https://github.com/illuin-tech/configue/workflows/CI/badge.svg)
[![codecov](https://codecov.io/gh/illuin-tech/configue/branch/master/graph/badge.svg)](https://codecov.io/gh/illuin-tech/configue)A YAML parser with advanced functionalities to ease your application configuration.
# Who is this library for ?
This library is meant to be used in medium to large-scale applications, that have a lot of parameters to configure.Modular applications especially can greatly benefit from using `configue` to easily inject new modules.
# Installation
Run `pip install configue` to install from PyPI.
Run `pip install .` to install from sources.
This project follows the (Semantic Versioning Specification)[https://semver.org/].
All breaking changes are described in the [Changelog](CHANGELOG.md).# Usage
### Basic usage
This library uses [PyYAML](https://github.com/yaml/pyyaml) to parse the YAML files and return the file content.```python
import configueconfig = configue.load("/path/to/yaml/file.yml")
```### Loading a sub path
If you are not interested in loading the whole file, you can only load a subpath:
```yaml
# config.yml
some_key:
some_list:
- first_item
- second_item:
item_key: item_valuenot_loaded_key: not_loaded_value
``````python
import configueconfig = configue.load("config.yml", "some_key.some_list.1.item_key")
assert config == "item_value"
```### Instantiating classes
Use `()` in your YAML files to instantiate classes:
```yaml
# config.yml
(): "my_project.MyAwesomeClass"
my_argument: "my_value"
my_other_argument:
(): "my_project.my_module.MyOtherClass"
``````python
import configue
from my_project import MyAwesomeClass
from my_project.my_module import MyOtherClassmy_instance = configue.load("config.yml")
assert isinstance(my_instance, MyAwesomeClass)
assert my_instance.my_argument == "my_value"
assert isinstance(my_instance.my_other_argument, MyOtherClass)
```This syntax also works to call functions:
```yaml
# config.yml
(): "my_project.my_function"
my_argument: "world"
``````python
import configuedef my_function(my_argument: str) -> str:
return "Hello " + my_argumentmy_value = configue.load("config.yml")
assert my_value == "Hello world"
```### Loading external variables
```yaml
# config.yml
my_argument: !ext my_project.my_module.my_variable
my_argument: !ext my_project.my_module.my_instance.my_attribute
```When using the `!ext` tag, the value will be imported from the corresponding python module.
### Loading internal variables
```yaml
# config.yml
my_object:
my_instance:
(): my_project.MyClass
my_instance_shortcut: !cfg my_object.my_instance
my_attribute_shortcut: !cfg my_object.my_instance.my_attribute
```When using the `!cfg` tag, the value will be loaded from the same configuration file (useful for a DRY configuration).
### Environment variables
If you want to load an environment variable in your YAML config file, you can use this syntax:
```yaml
# config.yml
my_key: ${VAR_NAME}
```
This will resolve as `"my_value"` if the environment variable `VAR_NAME` is set to this value.If you need a default value in case the environment variable is not set:
```yaml
# config.yml
my_key: ${VAR_NAME-default}
```You can insert this syntax in the middle of a string:
```yaml
# config.yml
my_key: prefix${VAR_NAME-default}suffix
```
This will resolve as `"prefixmy_value_suffix"` if the value is set, `"prefixdefaultsuffix"` if it is not.If your environment variable resolves to a yaml value, it will be cast (unless you are using quotes):
```yaml
# config.yml
my_key: ${VAR_NAME}
my_quoted_key: "${VAR_NAME}"
```
This will resolve as `True` if the value is set to `true`, `yes` or `y`, `None` if the value is set to `~` or `null`.### Relative paths
If you want to expand a relative path in your YAML config file:
````yaml
# config.yml
my_path: !path my_folder/my_file.txt
````
Assuming your file structure looks like this:
```
root/
├── config.yml
└── my_folder
└── my_file.txt
```The path is resolved starting from the folder containing the parent yml file, this example will resolve to
`/root/my_folder/my_file.txt`Do not start the path with `/` as it will be treated as an absolute path instead.
You can use environment variables in your file path.
### Importing other files
You can import another file directly in your YAML config file:
````yaml
# config.yml
my_import: !import my_folder/my_other_config.yml
```````yaml
# my_other_config.yml
some_key:
- var_1
- var_2
```By default, the path is resolved starting from the folder containing the parent yml file, this example will resolve to
`"my_import": {"some_key": [var_1, var_2]}`If you want to import only a section of the file, use the path in the tag suffix `!import:some_key.0`
Do not start the import path with `/` as it will be treated as an absolute path instead.
You can use environment variables in your import path.
### Logging configuration
You can load the logging configuration for your application by using the `logging_config_path` parameter:
```yaml
# config.yml
logging_config:
version: 1
handlers:
console:
class : logging.StreamHandler
stream : ext://sys.stdout
custom_handler:
\(): my_app.CustomHandler
some_param: some_value
level: ERROR
root:
level: INFO
handlers:
- consoleapp_config:
some_key: some_valuenot_loaded_key: not_loaded_value
``````python
import loggingimport configue
app_config = configue.load("config.yml", "app_config", logging_config_path="logging_config")
assert app_config == {"some_key": "some_value"}logger = logging.getLogger(__name__)
logger.info("Hello world!") # Uses the console handler
```The logging configuration should follow the format of `logging.config.dictConfig`
(check [the documentation](https://docs.python.org/3/library/logging.config.html#logging-config-dictschema) for more
details).
Make sure to escape the constructors with `\()` instead of `()` for handlers, formatters and filters.# Testing
Install the development dependencies with `pip install -r dev.requirements.txt`.
Run `python -m unitttest discover` to run the tests.
Run `pylint configue` to check the files linting.