Skip to main content

Globally scoped configuration with argparse integration

Project description

Effortless Config

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.
    """

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.

Where SettingType is Union[int, float, str, bool].

Using the configuration

Then in your code you can use these settings, for example in'example/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.1.tar.gz (5.1 kB view details)

Uploaded Source

Built Distribution

effortless_config-0.1.1-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: effortless-config-0.1.1.tar.gz
  • Upload date:
  • Size: 5.1 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.1.tar.gz
Algorithm Hash digest
SHA256 bcdb6cbda6608c908f305302feeb922391f4cbc33ac3c8a3012f1b2ca45f78b4
MD5 0cf662dbbbc46ce8b0c2540c5f5cf930
BLAKE2b-256 2303a541dbbbda2d9055760217a44f956e547b920014d852713215b4c3887ca6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: effortless_config-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.6 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ffbdb24b3edc0d763c128dcdddecee991c1fe6424760c882172adb895b3b34a7
MD5 8100cffd611360c447b16e5ff7e51044
BLAKE2b-256 0ed09f3e23bb45f7644f90b7f156b81e9ac750853a54cae0ff7d7a16f93b2610

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