Skip to main content

Globally scoped configuration with argparse integration

Project description

Effortless Config

PyPI version CircleCI

Globally scoped configuration with argparse integration.

Installation

pip install effortless-config

Rationale

  1. When building machine learning models, I often find myself with a file named config.py that has a bunch of global variables that I reference throughout the codebase.
  2. As the work progresses, I end up with groups of specific configuration settings that correspond to specific experiments.
  3. I want to be able to select configuration group on the command line when I start an experiment.
  4. And I want to be able to override certain settings within that experiment, from the command line.

Usage

Defining configuration

Inside some file in your project, for example example/config.py:

from effortless_config import Config, setting

class config(Config):  # notice lowercase c

    groups = ['experiment1', 'experiment2']

    SOME_INTEGER_SETTING = setting(10, experiment1=20, experiment2=30)
    FLOAT_SETTING = setting(0.5)
    A_BOOLEAN = setting(False, experiment1=True)
    MY_STRING_SETTING = setting('foo', experiment2='bar')
    SOME_OTHER_INTEGER = 100

First we create a class that extends effortless_config.Config. Inside it we add configurable parameters with the effortless_config.setting method. setting has the signature:

def setting(default: SettingType, **kwargs: SettingType):
    """
    Create a new configurable parameter, inside a class that extends Config.

    Args:
        default: Default parameter value.
        **kwargs: Map of group name to group value.

    Returns:
        A new setting.
    """

(...where SettingType is Union[int, float, str, bool].)

In this example, FLOAT_SETTING has no groups defined, so this setting will use the default value for all groups. It can still be overridden on the command line though. But SOME_OTHER_INTEGER will always be fixed, since it's not wrapped in setting.

Using the configuration

Then in your code you can use these settings, for example inexample/main.py:

from .config import config

if __name__ == '__main__':
    config.parse_args()
    print(f'SOME_INTEGER_SETTING is {config.SOME_INTEGER_SETTING}')
    print(f'FLOAT_SETTING is {config.FLOAT_SETTING}')
    print(f'A_BOOLEAN is {config.A_BOOLEAN}')
    print(f'MY_STRING_SETTING is {config.MY_STRING_SETTING}')
    print(f'SOME_OTHER_INTEGER is {config.SOME_OTHER_INTEGER}')

When we invoke main.py without any arguments, we get the default settings:

$ python -m example.main
SOME_INTEGER_SETTING is 10
FLOAT_SETTING is 0.5
A_BOOLEAN is False
MY_STRING_SETTING is foo
SOME_OTHER_INTEGER is 100

When we pass an configuration group using the --configuration parameter, we get different values:

$ python -m example.main --configuration experiment1
SOME_INTEGER_SETTING is 20
FLOAT_SETTING is 0.5
A_BOOLEAN is True
MY_STRING_SETTING is foo
SOME_OTHER_INTEGER is 100

We can also override individual settings:

$ python -m example.main --some-integer-setting 40 --float-setting -5
SOME_INTEGER_SETTING is 40
FLOAT_SETTING is -5.0
A_BOOLEAN is False
MY_STRING_SETTING is foo
SOME_OTHER_INTEGER is 100

As well as combining groups with individual settings:

$ python -m example.main --configuration experiment1 --some-integer-setting 40
SOME_INTEGER_SETTING is 40
FLOAT_SETTING is 0.5
A_BOOLEAN is True
MY_STRING_SETTING is foo
SOME_OTHER_INTEGER is 100

You can see all available settings using the -h flag:

$ python -m example.main -h
usage: main.py [-h] [--configuration {experiment1,experiment2}]
               [--some-integer-setting SOME_INTEGER_SETTING]
               [--float-setting FLOAT_SETTING] [--a-boolean {true,false}]
               [--my-string-setting MY_STRING_SETTING]

optional arguments:
  -h, --help            show this help message and exit
  --configuration {experiment1,experiment2}, -c {experiment1,experiment2}
  --some-integer-setting SOME_INTEGER_SETTING
  --float-setting FLOAT_SETTING
  --a-boolean {true,false}
  --my-string-setting MY_STRING_SETTING

Testing

When writing tests, you can use the config.override context manager to override individual settings:

import pytest
from .config import config

def test_with_context_manager():
    with config.override(FLOAT_SETTING=0.8, A_BOOLEAN=True):
        assert config.FLOAT_SETTING * config.SOME_INTEGER_SETTING == 8
        assert config.A_BOOLEAN is True

The config.override method can also be used without context management in conjunction with config.reset_to_defaults:

def test_with_manual_reset():
    config.override(FLOAT_SETTING=0.8, A_BOOLEAN=True)
    assert config.FLOAT_SETTING * config.SOME_INTEGER_SETTING == 8
    assert config.A_BOOLEAN is True
    config.reset_to_defaults()

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

effortless-config-0.1.7.tar.gz (5.2 kB view details)

Uploaded Source

Built Distribution

effortless_config-0.1.7-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file effortless-config-0.1.7.tar.gz.

File metadata

  • Download URL: effortless-config-0.1.7.tar.gz
  • Upload date:
  • Size: 5.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.8.0 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for effortless-config-0.1.7.tar.gz
Algorithm Hash digest
SHA256 81fe690f37ea6d7d73cef2a37e7da9f0721ad968328a99b91379771ff26efdf4
MD5 cd185c51122754105f9169f872576fa2
BLAKE2b-256 28d88ad4078883558efcf307830390e9ff55029d4b792aed621347efc12c372f

See more details on using hashes here.

File details

Details for the file effortless_config-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: effortless_config-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.8.0 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for effortless_config-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 f9f1a4c943b506e6072ecec84b315ca6336611650cecf10ad32ae90880abe424
MD5 cbd0f7953f1cd8b212e61af4a05cc5f0
BLAKE2b-256 dfacabccd256d8fd788ae5d203745a9a2ee7db5cc8c98c24ea22206936c9a492

See more details on using hashes here.

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