Python Configuration System
Project description
Python Configuration System
Description
Library to define configurations using python files.
Installation
Recommended installation with pip:
pip install pycs
Usage
- Define config schema:
# project/config.py
from pycs import CL, CN
class BaseClass:
pass
schema = CN() # Basic config node
schema.DICT = CN() # Nested config node
schema.DICT.FOO = "FOO" # Config leaf with actual value
schema.DICT.INT = 1
schema.NAME = CL(None, str, required=True) # Specification of config leaf to be defined with type
schema.CLASSES = CN(BaseClass) # Config node with type specification of its config leaves
schema.SUBCLASSES = CN(CL(None, BaseClass, subclass=True)) # Config node with subclass specification of its config leaves
schema.VAL = CL(1, desc="Interesting description") # Config leaf with description
def transform(cfg: CN) -> None:
cfg.NAME = cfg.NAME or "__static__"
cfg.DICT.FOO = "BAR"
def validate(cfg: CN) -> None:
assert len(cfg.NAME) > 0
def hook(cfg: CN) -> None:
print("Loaded")
# Add transform, validation & hooks function
# Transforms are run after config is loaded and can change values in config
# Can also be run at runtime using .transform()
# If you plan to transform multiple times we strongly recommend to make them idempotent
schema.add_transform(transform)
# Validators are run after transforms and freeze, with them you can verify additional restrictions
schema.add_validator(validate)
# Hooks are run after validators and can perform additional actions outside of config
schema.add_hook(hook)
# Validators and hooks should not (and mostly cannot) modify the config
- If you want to use configuration with default values or make changes in the program you can use
.static_init()
:
from project.config import schema
cfg = schema.static_init() # 'Loaded'
print(cfg.DICT.FOO) # 'BAR'
- If you want to store changes more permanently, please create a config file:
# my_cfg.py
from pycs import CN
from project.config import schema
# Use init_cfg() to separate changes from base variable and freeze schema
cfg = schema.init_cfg()
# Schema changes are not allowed here, only leaves can be altered.
cfg.NAME = "Hello World!"
cfg.DICT.INT = 2
You can also create another file to inherit from first and add more changes:
# my_cfg2.py
from ntc import CN
from .my_cfg import cfg
# Separate changes from parent, important when inheriting in multiple files
cfg = cfg.clone()
cfg.DICT.FOO = "BAR"
There a few restrictions on imports in configs:
- If you are inheriting changes from another config, please import variable as
cfg
- No other import should be named
cfg
- Load actual config and use it in the code.
# main.py
from pycs import CN
cfg = CN.load("my_cfg.py")
# Access values as attributes
assert cfg.NAME == "Hello World!"
assert cfg.DICT.FOO == "BAR"
- You can also load from YAML or JSON:
# my_changes.yaml
DICT:
FOO: BAR
# my_changes.json
{
"DICT": {
"INT": 2
}
}
# main.py
from project.config import schema
cfg = schema.load_updates_from_file("my_changes.yaml")
assert cfg.DICT.FOO == "BAR"
cfg = schema.load_updates_from_file("my_changes.json")
assert cfg.DICT.INT == 2
Development
- Install dev dependencies:
pip install -e ".[dev]"
- For linting and basic fixes ruff is used:
ruff check . --fix
- This repository follows strict formatting style which will be checked by the CI.
To properly format the code, use the black format:
black .
- To test code, use pytest:
pytest .
- This repository follows semantic-release, which means all commit messages have to follow a style. You can use tools like commitizen to write your commits.
Acknowledgements
This library was inspired by yacs.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pycs-5.1.0.tar.gz
(29.8 kB
view hashes)
Built Distribution
pycs-5.1.0-py3-none-any.whl
(15.8 kB
view hashes)