Skip to main content

Package for simplified work with configurations (as dataclass), manage their profiles, and export/import possibilities

Project description

Configlayer: an attempt to simplify working with configurations

PyPI PyPI - Python Version GitHub License Coverage Flake8 mypy mypy-imprecise CI and CD

Python Linux Windows MacOS
3.10 pytest pytest pytest
3.11 pytest pytest pytest

Features

Initially positioned as a convenient bridge between dataclass and ConfigParser,
but later was split into optional modules and added extra functionality:

  • Profiles module (cfg.profiles) - a lot of functions for config profiles manipulation:
    • Profiles: get, set, clear, rename and switch
    • Groups: get and del, set at init only ('group' keyword)
  • I/O module (cfg.io) - export/import functions, if needed custom save/load
  • File module (cfg.file) - save/load functions for ini config files (use I/O)
  • Config groups - simultaneous switch/rename of several configs profiles (use profiles)
  • On set handlers (cfg.*_on_set) - calling a user-defined function for changed field(s)
  • Options (cfg.options) - change defaults in several functions (waits rewrite in future)
  • Data validation (implemented in utils module, but maybe pydantic should be used)
  • Batch fields get (cfg.get_*) - data, defaults, types, changed states, params, on_set handlers
  • Batch fields set (cfg.set_*) - data and defaults only
  • Besides ConfigBase, there is also LanguageBase - use fixed 'language' group, and 'str' type

Todo list

  • Add docs..
  • Add optional autosave (time interval, at exit)
  • Add optional get_value_func and pooling_sec to Field (for environment variables, etc.)
  • Add optional history of fields/profiles changes (for undo/redo)
  • Add config versions (import from older configs by dev-provided functions)
  • Add multiple configs in single file (if profiles disabled)
  • Add modules support, for example __init__(modules={'db': DataBaseBridge}) (cfg.db)
  • Add several active profiles support (with different active fields, override by last one)
  • Add logging..
  • Do something with utils module - make a separate library or simplify it
  • Rebuilt Options to set default methods params at init and change it during execution

Installing

Recommended way (without '--user' - elevated privileges needed, if a system interpreter is used)

pip install --user configlayer

Minimal usage example

from configlayer import ConfigBase


class Config(ConfigBase):
    param: str = 'Some str'


data = Config('cfg.ini')  # Load from file if exists, else check save file possibility 
data.param = 'Another str'
data.cfg.file.save()

Other examples

Common part

from ast import literal_eval                # Needed only for custom fields import from str
from configlayer import ConfigBase, Field   # Field is needed only for custom fields I/O


# Configuration fields with types and factory defaults
class Config(ConfigBase):
    """Main"""  # optional verbose config name at first __doc__ line
    auto: bool = False
    tab: int = 0
    param: str = 'factory default'
    items: list = []
    items_custom_io: list = Field([], lambda x: f'{x}custom', lambda x: literal_eval(x[:-6]))

Simple config file

# Init config from file, if it exists
data = Config('config simple.ini')

# Set fields ways
data.param = 'field'
data.cfg.set_fields({'auto': True, 'items': ['some']})

# Set user defaults 
data.cfg.set_defaults({'tab': 1, 'items_custom_io': ['default']})

# Save changes to file (no autosave yet, planned)
data.cfg.file.save()

Profiles config file

# Init config with profiles support (file has additional internal section)
data = Config('config profiles.ini', profiles=True)
profiles = data.cfg.profiles

# Set defaults ways (at this stage - default profile selected, set fields ways change defaults)
data.param = 'default'
data.cfg.set_fields({'auto': True, 'tab': 2})
data.cfg.set_defaults({'items': ['default'], 'items_custom_io': ['default']})

# Add new profiles and switch to it ways
profiles.set('Profile 1', {'auto': False, 'tab': 0})

## 'auto' and 'tab' at factory defaults, 'items' and 'items_custom_io' at user defaults
profiles.switch('Profile 1')

## the same as 'Profile 1', due to copy from currently selected profile
profiles.switch('Profile 2', add=True, add_current=True)

## all fields copied from user defaults
profiles.switch('Profile 3', add=True)

# Rename current profile
profiles.rename('New profile')

# Rename selected profile
profiles.rename('New profile 2', 'Profile 2')

# Save changes to file (no autosave yet, planned)
data.cfg.file.save()

Simple RAM-only config, with I/O operations

# Init config only in RAM with export/import functions access
data1 = Config(io=True)
data1.param = 'field'
exported = data1.cfg.io.export_config()

data2 = Config(io=True)
data2.cfg.io.import_config(exported)
assert data1 == data2

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

configlayer-0.1.2.tar.gz (67.9 kB view hashes)

Uploaded Source

Built Distribution

configlayer-0.1.2-py3-none-any.whl (37.3 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