Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yukihiko-shinoda/yaml-dataclass-config
This project helps you to import config file writen by YAML to Python dataclass.
https://github.com/yukihiko-shinoda/yaml-dataclass-config
configuration-file dataclass dataclasses python type-safe yaml
Last synced: about 2 months ago
JSON representation
This project helps you to import config file writen by YAML to Python dataclass.
- Host: GitHub
- URL: https://github.com/yukihiko-shinoda/yaml-dataclass-config
- Owner: yukihiko-shinoda
- License: mit
- Created: 2019-06-29T21:09:06.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-08-17T07:14:33.000Z (over 4 years ago)
- Last Synced: 2024-11-14T22:52:54.487Z (3 months ago)
- Topics: configuration-file, dataclass, dataclasses, python, type-safe, yaml
- Language: Python
- Size: 94.7 KB
- Stars: 36
- Watchers: 2
- Forks: 5
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Contributing: docs/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# YAML Data Class Config
[![Test](https://github.com/yukihiko-shinoda/yaml-dataclass-config/workflows/Test/badge.svg)](https://github.com/yukihiko-shinoda/yaml-dataclass-config/actions?query=workflow%3ATest)
[![Test Coverage](https://api.codeclimate.com/v1/badges/9b89a5c842c2af41d02e/test_coverage)](https://codeclimate.com/github/yukihiko-shinoda/yaml-dataclass-config/test_coverage)
[![Maintainability](https://api.codeclimate.com/v1/badges/9b89a5c842c2af41d02e/maintainability)](https://codeclimate.com/github/yukihiko-shinoda/yaml-dataclass-config/maintainability)
[![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/yukihiko-shinoda/yaml-dataclass-config)](https://codeclimate.com/github/yukihiko-shinoda/yaml-dataclass-config)
[![Updates](https://pyup.io/repos/github/yukihiko-shinoda/yaml-dataclass-config/shield.svg)](https://pyup.io/repos/github/yukihiko-shinoda/yaml-dataclass-config/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/yamldataclassconfig)](https://pypi.org/project/yamldataclassconfig/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/yamldataclassconfig)](https://pypi.org/project/yamldataclassconfig/)
[![Twitter URL](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2Fyukihiko-shinoda%2Fyaml-dataclass-config)](http://twitter.com/share?text=YAML%20Data%20Class%20Config&url=https://pypi.org/project/yamldataclassconfig/&hashtags=python)This project helps you to import config file writen by YAML to
Python [Data Classes](https://docs.python.org/3/library/dataclasses.html).## Advantage
1. Type safe import from YAML to Data Classes
2. Global access and easy unit testing### 1. Type safe import from YAML to Data classes
When using pyyaml to import YAML, values be dict and list objects.
Using dict or list object will cause such confuses:- Reference non exist properties for unexpected instance type
- Typo of index or key nameTo prevent these confuse, one of good way is to use object as model,
and python has a good module
[Data Classes](https://docs.python.org/3/library/dataclasses.html) for this purpose.### 2. Global access and easy unit testing
You will want to refer config as global
because it's troublesome to pass config value as argument over and over like a bucket brigade.However, when unit testing,
if YAML file was loaded automatically on importing global definition,
you will face problem that
you can't replace config YAML file with the one for unit testing.
YAML Data Class Config can divide timings between definition global instance and
loading YAML file so you can replace YAML file for unit testing.## Quickstart
### 1. Install
```console
pip install yamldataclassconfig
```### 2. Prepare config YAML file
Put `config.yml`
YAML Data class Config loads `config.yml` on Python execution directory by default.```yaml
property_a: 1
property_b: '2'
part_config:
property_c: '2019-06-25 13:33:30'
```### 3. Create config class
Anywhere is OK, for example, I prefer to place on `myproduct/config.py`
```python
from dataclasses import dataclass, field
from datetime import datetime
from dataclasses_json import DataClassJsonMixin
from marshmallow import fields
from yamldataclassconfig.config import YamlDataClassConfig@dataclass
class PartConfig(DataClassJsonMixin):
property_c: datetime = field(metadata={'dataclasses_json': {
'encoder': datetime.isoformat,
'decoder': datetime.fromisoformat,
'mm_field': fields.DateTime(format='iso')
}})@dataclass
class Config(YamlDataClassConfig):
property_a: int = None
property_b: str = None
part_config: PartConfig = field(
default=None,
metadata={'dataclasses_json': {'mm_field': PartConfig}}
)
```### 4. Define as global
Also, anywhere is OK, for example, I prefer to place on `myproduct/__init__.py`
```python
from myproduct.config import ConfigCONFIG: Config = Config()
```### 5. Call load before reference config value
```python
from myproduct import CONFIGdef main():
CONFIG.load()
print(CONFIG.property_a)
print(CONFIG.property_b)
print(CONFIG.part_config.property_c)if __name__ == '__main__':
main()
```## How do I...
### Fix path to yaml file independent on the Python execution directory?
override `FILE_PATH` property.
Ex:
```python
from dataclasses import dataclass
from pathlib import Pathfrom yamldataclassconfig import create_file_path_field
from yamldataclassconfig.config import YamlDataClassConfig@dataclass
class Config(YamlDataClassConfig):
some_property: str = None
# ...FILE_PATH: Path = create_file_path_field(Path(__file__).parent.parent / 'config.yml')
```### Switch target YAML config file to the one for unit testing?
When setup on unit testing, you can call `Config.load()` with argument.
Case when unittest:
```python
from pathlib import Path
import unittestfrom yourproduct import CONFIG
class ConfigurableTestCase(unittest.TestCase):
def setUp(self):
CONFIG.load(Path('path/to/yaml'))
```Case when pytest:
```python
from pathlib import Path
import pytestfrom yourproduct import CONFIG
@pytest.fixture
def yaml_config():
CONFIG.load(Path('path/to/yaml'))
yielddef test_something(yaml_config):
"""test something"""
```### Use path to YAML config file as same as production when test?
[fixturefilehandler](https://pypi.org/project/fixturefilehandler/)
can replace config.yml with tests/config.yml.dist easily.
Please call all `DeployerFactory.create` with `YamlConfigFilePathBuilder` instance argument
to create ConfigDeployer.
Then, set target directory which config.yml should be placed into `path_target_directory`.Case when unittest:
```python
from pathlib import Path
import unittest
from fixturefilehandler.factories import DeployerFactory
from fixturefilehandler.file_paths import YamlConfigFilePathBuilderfrom yourproduct import CONFIG
ConfigDeployer = DeployerFactory.create(YamlConfigFilePathBuilder(path_target_directory=Path(__file__).parent.parent))
class ConfigurableTestCase(unittest.TestCase):
def setUp(self):
ConfigDeployer.setup()
CONFIG.load()def doCleanups(self):
ConfigDeployer.teardown()
```Case when pytest:
```python
from pathlib import Path
import pytest
from fixturefilehandler.factories import DeployerFactory
from fixturefilehandler.file_paths import YamlConfigFilePathBuilderfrom yourproduct import CONFIG
ConfigDeployer = DeployerFactory.create(YamlConfigFilePathBuilder(path_target_directory=Path(__file__).parent.parent))
@pytest.fixture
def yaml_config():
ConfigDeployer.setup()
CONFIG.load()
yield
ConfigDeployer.teardown()def test_something(yaml_config):
"""test something"""
```