configure – configuration toolkit for YAML

Configure is a thin wrapper around PyYAML which extends already readable and powerful YAML with inheritance, composition and (so called) “object-graph configuration” features.

Basic usage

Configure uses YAML as a configuration format so you can refer to YAML specification for details on how you can compose your configuration. The basics are the following – you your config as a mapping, which allows nesting and also can contain sequences:

# my.conf
database: postgresql://localhost/dbname
timeout: !timedelta 10m
messages:
  - msg: Hello, world!
    author: Andrey Popp
  - msg: Wow!
    author: John Doe
EOF

Inline comments are started with # (sharp). To read configuration:

from configure import Configuration
config = Configuration.from_file('./my.conf').configure()
assert config.database == 'postgresql://localhost/dbname'
assert config['database'] == 'postgresql://localhost/dbname'
assert config.timeout == datetime.timedelta(seconds=600)

As you can see timeout value automatically parsed and converted to class:datetime.timedelta object by annotating configuration value with !timedelta tag. There’s also !re builtin tag which passes value to re.compile() function so you can have compiled regular expression right after reading a config.

Note

You should always call Configuration.configure() method before using Configuration.

Objects of class Configuration implement collections.MutableMapping interface, but as you already saw, you can also access values by attribute.

Composition

You can compose configuration from different sources by using !include tag, the configuration you included will be placed inplace of the element you tagged with !include:

# common.conf
db: postgresql://localhost/dbname

# app.conf
common: !include:common.conf

Note that filename resolves relative to dirname of configuration which contain !include tag, so in example above app.conf and common.conf should be placed in the same directory. After loading app.conf configuration:

config = Configuration.from_file('app.conf').configure()
assert config.common.db == 'postgresql://localhost/dbname'

You can use !include tag at any level of the document.

Inheritance

Configuration can be also composed using inheritance mechanism using !extends tag. It can be useful for providing some sensible defaults for configuration file:

# base.conf, contains default values
db: postgresql://localhost/dbname

# app.conf
--- !extends:base.conf
timeout: !timedelta 10m

Filename resolution performs the same like with !include tag, so base.conf and app.conf should be placed in the same directory again. When you load app.conf:

config = Configuration.from_file('app.conf').configure()
assert config.db == 'postgresql://localhost/dbname'

you will see that config.db was inherited from base.conf. Inheritance mechanism can also be applied at any level not necessary at the entire configuration file.

Object-graph configuration

There is also another useful feature configure library provides – so called object-graph configuration. Suppose you have somewhere in your code function which accepts some configuration values and performs some task to configure your system based on these values:

# myapp.py
def configure_db(uri, echo=False):
  ...

You can ask configure to call this function for you automatically with some values from configuration:

# my.conf
db: !factory:myapp.configure_db
  uri: !ref:dburi
  echo: false

dburi: postgresql://localhost/dbname

You see there are !ref and !factory tags – first one just references some other value from configuration which allows you to stay DRY, while !factory tag call specified function using arguments provided in mapping.

Note

This does work only with positional and keyword arguments and doesn’t work with “magic” *args and **kwargs at the moment.

Note

When using inheritance with !extends it is possible to !ref to refer to values defined not in the current config but in the parent configs as well.

Another useful tag is the !obj tag which just imports some python object for you:

resource_cls: !obj:myapp.resource.Resource

will import myapp.resource.Resource object and assign it resource_cls key.

API reference

configure – configuration machinery on top of YAML

class configure.Configuration(struct=None, pwd=None, parent=None)

Configuration object

You should never instantiate this object but use from_file, from_string or from_dict classmethods instead. Implements collections.MutableMapping protocol.

configure(struct=None, _root=True)

Commit configuration

This method performs all actions pending to this Configuration object. You can also override configuration at this moment by providing mapping object as struct argument.

classmethod from_dict(cfg, pwd=None)

Construct Configuration from dict d.

Parameters:d – mapping object to use for config
classmethod from_file(filename, ctx=None, pwd=None, constructors=None)

Construct Configuration object by reading and parsing file filename.

Parameters:
  • filename – filename to parse config from
  • ctx – mapping object used for value interpolation
  • constructors – mapping of names to constructor for custom objects in YAML. Look at _timedelta_constructor and _re_constructor for examples.
classmethod from_string(string, ctx=None, pwd=None, constructors=None)

Construct Configuration from string.

Parameters:
  • string – string to parse config from
  • ctx – mapping object used for value interpolation
  • constructors – mapping of names to constructor for custom objects in YAML. Look at _timedelta_constructor and _re_constructor for examples.
merge(config)

Produce new configuration by merging config object into this one

exception configure.ConfigurationError

Configuration error

configure.configure_logging(logcfg=None, disable_existing_loggers=True)

Configure logging in a sane way

Parameters:
  • logcfg – may be a. a dict suitable for logging.config.dictConfig(), b. “syslog” string or c. None
  • disable_existing_loggers – if we need to disable existing loggers
configure.import_string(import_name, silent=False)

Imports an object based on a string. This is useful if you want to use import paths as endpoints or something similar. An import path can be specified either in dotted notation (xml.sax.saxutils.escape) or with a colon as object delimiter (xml.sax.saxutils:escape).

If silent is True the return value will be None if the import fails.

For better debugging we recommend the new import_module() function to be used instead.

Parameters:
  • import_name – the dotted name for the object to import.
  • silent – if set to True import errors are ignored and None is returned instead.
Returns:

imported object

Copyright :
  1. 2011 by the Werkzeug Team
exception configure.ImportStringError(import_name, exception)

Provides information about a failed import_string() attempt.

Copyright :
  1. 2011 by the Werkzeug Team
exception = None

Wrapped exception.

import_name = None

String in dotted notation that failed to be imported.