Skip to main content

A module for other modules to allow flexible (yet not error-prone) configuration.

Project description

flexmod

A python module for other modules to allow flexible (yet not error-prone) configuration.

Story

Suppose you wrote a package and you want to allow users to set package-level configs:

import awesomepackage
from awesomepackage.foo import bar

# user can change module param on the fly
awesomepackage.config["logging"]["verbose"] = True

# package behavior is now different from default
bar()

This is simple, but maybe not any parameter can be changed at any time. For example:

awesomepackage.config["metric"]["length"] = "foot"

Having flexible units may be helpful for different locales, but changing metric units in the middle of a program can lead to consistency issues.

flexmod lets you:

  • specify configs that are auto-locked (i.e. no further changes) when used
  • add custom preprocessor functions to entered config values
    • this is useful when reading config from a text file
  • add validation functions to check user-supplied config values

Usage

Define configurations in your module using flexmod classes

# mypackage/__init__.py
from flexmod import ConfigValue, AutolockedConfigValue, Config, ConfigIndex

config = ConfigIndex(
    [
        Config(
	    "interface",
	    [
	        # example of a config that stays the same throughout a program
	    	AutolockedConfigValue(
		    # name of the config paramater
		    "language",
		    # hint
		    "The language of module interface (logs, warnings, etc.)",
		    # default value
		    "en-us",
		    # validate the config value
		    validation=lambda x: x in ["en-us", "fr-fr"],
		),
	        # example of a config that can change dynamically
	    	ConfigValue(
		    "verbosity",
		    "The granularity to which the module reports / complains",
		    1,
		    # specify a preprocessor function if needed
		    preprocessor=int,
		),
	    ],
	),
        Config(
	    "foo",
	    [
	    	AutolockedConfigValue(
		    "bar",
		    "Any other config parameter",
		    "",
		),
	    ],
	),
    ]
)
# mypackage/message.py
import mypackage

def hello_world():
    """
    Example function that uses a module-level config.
    """
    lang = mypackage.config["interface"]["language"]
    if lang == "en-us":
        print("Hello, world!")
    elif lang == "fr-fr":
        print("Bonjour, tout le monde!")
    else:
        pass

Package user: customize your module on the fly

Your user will not need to be aware of flexmod.

import mypackage
from mypackage.message import hello_world

# change module param on the fly
mypackage.config["interface"]["language"] = "fr-fr"

# this gets "Bonjour, tout le monde!"
hello_world()

# after an autolocked config is read, it cannot be changed
mypackage.config["interface"]["language"] = "en-us"
# AssertionError: language is locked from updates.

Users can also supply an configparser-style ini file.

  • Unlike in default configparser, booleans, integers and floats will be autodetected and converted.
# in custom.ini
[interface]
language = fr-fr
verbosity = 2

[foo]
bar = anything
import mypackage
from mypackage.message import hello_world

# change module param on the fly
mypackage.config.load_override("custom.ini")

# this gets "Bonjour, tout le monde!"
hello_world()

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

flexmod-0.1.2.tar.gz (4.8 kB view hashes)

Uploaded Source

Built Distribution

flexmod-0.1.2-py3-none-any.whl (5.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