Skip to main content

Python Configuration System

tests codecov publish Python Version from PEP 621 TOML PyPI - Version Code Style: Ruff

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
    
    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
    
  2. 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'
    
  3. 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 are 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
  4. Load actual config and use it in the code.

    from pycs import CN
    
    cfg = CN.load("my_cfg.py")
    # Access values as attributes
    assert cfg.NAME == "Hello World!"
    assert cfg.DICT.FOO == "BAR"
    

Other features

  • Load config changes/updates from YAML or JSON

    my_changes.yaml

    DICT:
      FOO: BAR
    

    my_changes.json

    {
      "DICT": {
        "INT": 2
      }
    }
    
    from project.config import schema
    
    cfg = schema.load_from_data_file("my_changes.yaml")
    assert cfg.DICT.FOO == "BAR"
    cfg = schema.load_from_data_file("my_changes.json")
    assert cfg.DICT.INT == 2
    
  • Save loaded config to a file for tracking:

    cfg.save("saved.py")
    

    Please note: There are limitations on which configs can be saved. Generally, config schema should be defined at the module-level and then config should be created with one of:

    • CN.load()
    • schema.static_init()
    • schema.load_from_data_file()
    • schema.load_or_static()

    In addition, only basic changes should be applied to config after loading. See CfgSaveable for how to permit saving changes with more complex types.

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 format the code, use the black format: black .
    • To sort the imports, user isort utility: isort .
  • 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.

  • You can also use pre-commit to help verify that all changes are valid. Multiple hooks are used, so use the following commands to install:

    pre-commit install
    pre-commit install --hook-type commit-msg
    

Acknowledgements

This library was inspired by yacs.

Release files for pycs 6.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycs 6.0.0
File Size Uploaded
pycs-6.0.0.tar.gz 31.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pycs 6.0.0
File Interpreter ABI Platform
pycs-6.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.7 kB

Release files / pycs-6.0.0.tar.gz

Download URL pycs-6.0.0.tar.gz
Size 31.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ddd0cdf7a15dfaa94fbc98ab6259d3827f71bba787c1d7fa411e96e710e77f83
BLAKE2b-256 checksum
How to use checksums
fded05c783c6542e68f799a3582c921ad8c7a183042083dbd8dd737c9adfb328
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.25.1

Release files / pycs-6.0.0-py3-none-any.whl

Download URL pycs-6.0.0-py3-none-any.whl
Size 16.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef0e04ae5317f1600b2343d1fc04d89df1269e4aeb49ebf20de27b5ee3bbb536
BLAKE2b-256 checksum
How to use checksums
5103e946a77303396aac58cfb85c3fe7d57c1db3e30f11f4e2d2ffcc8d681a61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.25.1

Release history Release notifications | RSS feed

This release

6.0.0 This release

2 release files

5.3.0

2 release files

5.2.0

2 release files

5.1.0

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.5.0

2 release files

4.4.1

2 release files

4.4.0

2 release files

4.3.0

2 release files

4.2.0

2 release files

4.1.0

2 release files

4.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page