Sources

The built-in sources are:

argparse

class multiconfparse.ArgparseSource(config_specs, priority=20)

Obtains config values from an argparse.ArgumentParser.

Do not create ArgparseSource objects directly, add them to a ConfigParser object using ConfigParser.add_source(). For example:

parser = multiconfparse.ConfigParser()
parser.add_config("config_item1")
parser.add_config("config_item2", nargs=2, type=int)
parser.add_config("config_item3", action="store_true")
argparse_source = parser.add_source("argparse")

argparse_parser = argparse.ArgumentParser()
argparse_parser.add_argument("arg1")
argparse_parser.add_argument("--opt1", type=int, action="append")
argparse_source.add_configs_to_argparse_parser(argparse_parser)

args = argparse_parser.parse_args((
    "arg1_value --config-item1 v1 --config-item2 1 2 --opt1 opt1_v1 "
    "--config-item-3 --opt1 opt1_v2"
).split())

argparse_source.notify_parsed_args(args)

config_parser.parse_config()
# -> multiconfparse.Namespace {
#   "config_item1": "v1",
#   "config_item2": [1, 2],
#   "config_item3": True,
# }

The argparse source does not create an argparse.ArgumentParser for you. This is to allow extra command line arguments to be added to an argparse.ArgumentParser that are not config items. Instead ArgparseSource, which implements the argparse source provides two methods to provide communication with the argparse.ArgumentParser:

add_configs_to_argparse_parser(argparse_parser)

Add arguments to an argparse.ArgumentParser for config items.

notify_parsed_args(argparse_namespace)

Notify the argparse source of the argparse.Namespace object returned by argparse.ArgumentParser.parse_args().

If you don’t need to add command line arguments other than for config items, see SimpleArgparseSource which implements the simple_argparse source.

The arguments of ConfigParser.add_source() for the argparse source are:

  • source (required, positional): "argparse"
  • priority (optional, keyword): The priority for the source. The default priority for an argparse source is 20.

Note that:

  • The name of the command line argument for a config item is the config item’s name with underscores (_) converted to hyphens (-) and prefixed with --.

simple_argparse

class multiconfparse.SimpleArgparseSource(config_specs, argument_parser_class=<class 'argparse.ArgumentParser'>, priority=20, **kwargs)

Obtains config values from the command line.

The simple_argparse source is simpler to use than the argparse source but it doesn’t allow adding arguments that are not config items.

Do not create objects of this class directly - create them via ConfigParser.add_source() instead. For example:

parser = multiconfparse.ConfigParser()
parser.add_config("config_item1")
parser.add_config("config_item2", nargs=2, type=int)
parser.add_config("config_item3", action="store_true")
parser.add_source("simple_argparse")
config_parser.parse_config()
# If the command line looks something like:
#    PROG_NAME --config-item1 v1 --config-item2 1 2 --config-item-3
# The result would be:
# multiconfparse.Namespace {
#   "config_item1": "v1",
#   "config_item2": [1, 2],
#   "config_item3": True,
# }

The arguments of ConfigParser.add_source() for the simple_argparse source are:

  • source (required, positional): "simple_argparse"
  • argument_parser_class (optional, keyword): a class derived from argparse.ArgumentParser to use instead of ArgumentParser itself. This can be useful if you want to override argparse.ArgumentParser.exit() or argparse.ArgumentParser.error().
  • priority (optional, keyword): The priority for the source. The default priority for a simple_argparse source is 20.
  • Extra keyword arguments to pass to argparse.ArgumentParser. E.g. prog, allow_help. Don’t use the argument_default option though - the simple_argparse sources sets this internally. See the config_default option for ConfigParser instead.

Note that:

  • The name of the command line argument for a config item is the config item’s name with underscores (_) converted to hyphens (-) and prefixed with --.

environment

class multiconfparse.EnvironmentSource(config_specs, none_values=None, priority=10, env_var_prefix='')

Obtains config values from the environment.

Do not create EnvironmentSource objects directly, add them to a ConfigParser object using ConfigParser.add_source(). For example:

# For demonstration purposes, set some config values in environment
# variables
os.environ["MY_APP_CONFIG_ITEM1"] = "v1"
os.environ["MY_APP_CONFIG_ITEM2"] = "1 2"
os.environ["MY_APP_CONFIG_ITEM3"] = ""

parser = multiconfparse.ConfigParser()
parser.add_config("config_item1")
parser.add_config("config_item2", nargs=2, type=int)
parser.add_config("config_item3", action="store_true")
parser.add_source("environment", env_var_prefix="MY_APP_")
parser.parse_config()
# -> multiconfparse.Namespace {
#   "config_item1": "v1",
#   "config_item2": [1, 2],
#   "config_item3": True,
# }

The arguments of ConfigParser.add_source() for the environment source are:

  • source (required, positional): "environment"

  • none_values (optional, keyword): a list of values that, when seen in environment variables, should be treated as if they were not present (i.e. values for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the dict).

    The default none_values is [""]. using a different value for none_values is useful you want the empty string to be treated as a valid config value.

  • priority (optional, keyword): The priority for the source. The default priority for an environment source is 10.

  • env_var_prefix (optional, keyword): a string prefixed to the environment variable names that the source will look for. The default value is "".

Note that:

  • The name of the environment variable for a config item is the config item’s name, converted to upper case, then prefixed with env_var_prefix.
  • Values in environment variables for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the environment variable) should be values from the none_values list described above.
  • Values in environment variables for config items with nargs >= 2, nargs == "+" or nargs == "*" are split into arguments by shlex.split() (i.e. like arguments given on a command line via a shell). See the shlex documentation for full details.

json

class multiconfparse.JsonSource(config_specs, path=None, fileobj=None, none_values=None, json_none_values=None, priority=0)

Obtains config values from a JSON file.

Do not create objects of this class directly - create them via ConfigParser.add_source(). For example:

parser = multiconfparse.ConfigParser()
parser.add_config("config_item1")
parser.add_config("config_item2", nargs=2, type=int)
parser.add_config("config_item3", action="store_true")

fileobj = io.StringIO('''
    {
        "config_item1": "v1",
        "config_item2": [1, 2],
        "config_item3": null
    }
''')
parser.add_source("json", fileobj=fileobj)

config_parser.parse_config()
# -> multiconfparse.Namespace {
#   "config_item1": "v1",
#   "config_item2": [1, 2],
#   "config_item3": True,
# }

The arguments of ConfigParser.add_source() for json sources are:

  • source (required, positional): "json".
  • priority (optional, keyword): The priority for the source. The default priority for a json source is 0.
  • path (optional, keyword): path to the JSON file to parse. Exactly one of the path and fileobj options must be given.
  • fileobj (optional keyword): a file object representing a stream of JSON data. Exactly one of the path and fileobj options must be given.
  • none_values (optional, keyword): a list of python values that, when seen as config item values after JSON decoding, should be treated as if they were not present (i.e. values for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the dict). The default none_values is [].
  • json_none_values (optional, keyword): a list of JSON values (as strings) that are decoded into Python values and added to none_values. The default json_none_values is ["null"].

Notes:

  • The data in the JSON file should be a JSON object. Each config item value should be assigned to a field of the object that has the same name as the config item.

  • Fields in the JSON object for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the dict) should either have values from the json_none_values list or should decode to values in the none_values list.

  • Fields in the JSON object for config items with nargs >= 2, nargs == "+" or nargs == "*" should be JSON arrays with an element for each argument of the config item.

    In the special case where nargs == "+" or nargs == "*" and there is a single argument for the config item, the value may be given without the enclosing JSON array, unless the argument is itself an array.

dict

class multiconfparse.DictSource(config_specs, values_dict, none_values=None, priority=0)

Obtains config values from a Python dict object.

Do not create DictSource objects directly, add them to a ConfigParser object using ConfigParser.add_source(). For example:

parser = multiconfparse.ConfigParser()
parser.add_config("config_item1")
parser.add_config("config_item2", nargs=2, type=int)
parser.add_config("config_item3", action="store_true")

values_dict = {
    "config_item1": "v1",
    "config_item2": [1, 2],
    "config_item3": None,
}
parser.add_source("dict", values_dict)
parser.parse_config()
# -> multiconfparse.Namespace {
#   "config_item1": "v1",
#   "config_item2": [1, 2],
#   "config_item3": True,
# }

The arguments of ConfigParser.add_source() for the dict source are:

  • source (required, positional): "dict".

  • values_dict (required, positional): the dict containing the config values.

    Note that:

    • Values in values_dict for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the dict) should be values from the none_values list described below.

    • Values in values_dict for config items with nargs >= 2, nargs == "+" or nargs == "*" should be list objects with an element for each argument of the config item.

      In the special case where nargs == "+" or nargs == "*" and there is a single argument for the config item, the value may be given without the enclosing list, unless the argument is itself a list.

  • none_values (optional, keyword): a list of values that, when seen in values_dict, should be treated as if they were not present (i.e. values for config items with nargs == 0 or nargs == "?" (where the const value should be used rather than the value from the dict).

    The default none_values is [None, multiconfparse.MENTIONED_WITHOUT_VALUE]. using none_values=[multiconfparse.MENTIONED_WITHOUT_VALUE] is useful if you want None to be treated as a valid config value.

  • priority (optional, keyword): The priority for the source. The default priority for a dict source is 0.

Creating your own source classes

To create your own source class, create a subclass of Source:

class multiconfparse.Source(priority=0)

Abstract base for classes that parse config sources.

All config source classes should inherit from Source, have a name class attribute containing the name of the source, and provide an implementation for the parse_config() method.

parse_config()

Read the values of config items for this source.

This is an abstract method that subclasses must implement to return a Namespace object where:

  • The returned Namespace has an attribute for each config item found. The name of the attribute for a config item must be the config item’s name as specified by the name attribute of its Action.

  • The value for each attribute is a list, where each element of the list is a value given for the config item in the source. The elements should be ordered so that values appearing earlier in the source are earlier in the list. In the common case where only a single value for the config item is given in the source, the attribute’s value should be a list with a single element.

    For example, if config_item1 is mentioned in the source once with value "v1" and config_item2 is mentioned in the source twice with values "v2" and then "v3", the returned Namespace object would have an attribute config_item1 with value ["v1"] and an attribute config_item2 with value ["v2", "v3"].

  • If a config item with nargs == 0 or nargs == "?" is mentioned in the source without a value (or possibly with a source-specific value that means None/null for sources where a value must always be given for a config item), the value for that mention of the config item should be given in the list of values as MENTIONED_WITHOUT_VALUE.

  • If a config item with nargs == None, nargs == 1 or nargs == "?" is mentioned in the source with a value, the value for that mention of the config item should be given in the list of values as the value itself.

  • If a config item with nargs >= 2 , nargs == "*" or nargs == "+" is mentioned in the source, the value for that mention of the config item should be given in the list of values as a list of the values/arguments given in that mention.

    For example, if a config item config_item1 with nargs == 2 appears in the source first with values/arguments of "v1a" and "v1b" and then again with values/arguments of "v2a" and "v2b", the config_item1 attribute in the Namespace should have a value of [["v1a", "v1b"], ["v2a", "v2b"]].

  • None of the values returned should yet have been coerced into the types specified by the user in ConfigParser.add_config().