Skip to main content

Python Configuration System

Project description

Python Configuration System

tests publish Code style: black

Description

Library to define configurations using python files.

Installation

Recommended installation with pip:

pip install pycs

Usage

  1. Define config schema:
# project/config.py
from pycs import CL, CN

class BaseClass:
    pass

cfg = CN()  # Basic config node
cfg.DICT = CN()  # Nested config node
cfg.DICT.FOO = "FOO"  # Config leaf with actual value
cfg.DICT.INT = 1
cfg.NAME = CL(None, str, required=True)  # Specification of config leaf to be defined with type
cfg.CLASSES = CN(BaseClass)  # Config node with type specification of its config leafs
cfg.SUBCLASSES = CN(CL(None, BaseClass, subclass=True))  # Config node with subclass specification of its config leafs
cfg.VAL = CL(1, desc="Interesting description") # Config leaf with description

def transform(cfg: CN) -> None:
    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
cfg.add_transform(transform)
# Validators are run after transforms and freeze, with them you can verify additional restrictions
cfg.add_validator(validate)
# Hooks are run after validators and can perform additional actions outside of config
cfg.add_hook(hook)
# Validators and hooks should not (and mostly cannot) modify the config
  1. Set actual values for each leaf in the config, the import has to be absolute:
# my_cfg.py
from pycs import CN

from project.config import cfg # Import has to be absolute

# Pass schema as an argument to the CN() to init the schema
cfg = CN(cfg)

# Schema changes are not allowed here, only leafs 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 # This import has to be relative and should only import cfg variable

cfg = CN(cfg)
cfg.DICT.FOO = "BAR"

There a few restrictions on imports in configs:

  • When you are importing config schema from project that import has to be absolute
  • When you inherit config values from another file, that import has to be relative
  • Other than config inheritance, all other imports have to be absolute
  1. 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"

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pycs-4.4.0.tar.gz (27.7 kB view hashes)

Uploaded Source

Built Distribution

pycs-4.4.0-py3-none-any.whl (15.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page