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.3.tar.gz (5.2 kB view details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: effortless-config-0.1.3.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.3.tar.gz
Algorithm Hash digest
SHA256 47235633bfb31b98577fc44871e1fa76df77e502c0addb21157eb75733486abc
MD5 aef37ce63e9913c95922c0870181efd5
BLAKE2b-256 f57f2c3e3004cb6a06d02ba607259f7253dc411944d10f6ef2f5cf48e9811c6e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: effortless_config-0.1.3-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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 08f2b71d5212adbb3d8b60988aa803a2f6eb85d29ffa1f7af57dc868f375292f
MD5 018c4a43403ce0935c7840ac00320929
BLAKE2b-256 65d77e8abd823acdc4d3c0eff2c9b9b4d16bfb6a164c1edf25868fe99bae98a3

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