Usage¶
Basic Concepts¶
Config Engine works defining configuration options in a consistent manner by
registering Option
objects to a
Configuration
object. The Option
objects can represent a particular option type and may have their own options
for defining constraints on the option values. For example a
NumberOption
has the ability to define a range
using minimum and maximum values.
A Configuration
does not need to have
all options registered before attempting to read configuration. This allows
individual modules and libraries that share the use of Config Engine to be
able to register their own option sets independently as long as they do not
have name conflicts.
Registering and Reading Options¶
While it is possible to have multiple instances of the py:class:~conf_engine.configuration.Configuration object, it’s typically not needed. Most use cases can take advantage of the module level object. In the below example the module level object is used to register a string option for both a username and password.
from conf_engine import config
from conf_engine import options
# Create option list.
options = [
options.StringOption('username'),
options.StringOption('password'),
options.BooleanOption('debug', default=False)
]
# Register options.
config.register_options(options)
# Read option values.
username = config.username
password = config.password
In the above example a debug mode option is also registered with a default value of False. Default values will be returned if a value for the option cannot be found in any of the configuration sources.
Option Groups¶
Groups can be used to organize options with a similar purpose. For example an application may need to access two different APIs. By utilizing groups the credentials for each API can be defined separately using similar naming semantics.
from conf_engine import config
from conf_engine import options
# Create option list.
api1_options = [
options.StringOption('api_url'),
options.StringOption('token')
]
api2_options = [
options.StringOption('api_url'),
options.StringOption('token'),
options.NumberOption('version')
]
# Register options.
config.register_options(api1_options, group='api1')
config.register_options(api2_options, group='api2')
# Read option values.
api1_username = config.api1.username
api2_version = config.api2.version
Creating and Consuming Configuration¶
Configuration data can be consumed by Config Engine from either operating
system environment variables or from ini style files. When consuming from
environment variables options names are capitalized and prepended with their
group name followed by an _
character. For ini style configuration
all options must be defined in sections. The section name corresponds with
the option group and the [DEFAULT]
section is used for any options
defined with no group.
By default Config Engine will look int the current working directory for
any files with the .ini
extension and load them as configuration.
However it is possible to define the location of configuration data by using
the --config-file
and --config-directory
CLI options when starting
your application.
Configuration Data Caching¶
By default Config Engine will store the value of a configuration option
once it has been read from the configuration source. However, this
caching behavior can be disabled by passing cache=False when creating
a Configuration
object, or a
ConfigGroup
.
Cached data can also be invalidated by calling the flush_cache()
method on either the Configuration
object, or the ConfigGroup
as
well.
from conf_engine import Configuration
from conf_engine import options
# Create option list.
cache_options = [
options.StringOption('username'),
options.StringOption('password'),
]
no_cache_options = [
options.BooleanOption('debug', default=False)
]
# Create two configuration groups, one that caches, and one that does not.
# Then register the options.
caching_config = Configuration(cache=True)
no_cache_config = Configuration(cache=False)
caching_config.register_options(cache_options)
no_cache_config.register_options(no_cache_options)
# This will only read from source once, and then use that
# value in subsequent lookups
print(caching_config.username)
# This will only read from configuration source, and never
# from the cache.
print(no_cache_options.debug)
Namespaces¶
The environment parser supports an optional namespace which will prepend each option with the namespace and an underscore to help ensure that the given option doesn’t have a name collision with other unrelated environment variables. Namespaces require the use of a declared configuration object rather than using the one provided in the ConfEngine module. Declaring options and accessing option values through the configuration object remains unchanged.
"""
Export your var before running the script.
.. code-block:
~# export TESTNS_MYGROUP_MY_VAR=namespaces
"""
from conf_engine import Configuration, options
# Create config object.
config = Configuration(namespace='testns')
# Register options.
config.register_option(options.StringOption('my_var'))
assert config.my_var == 'namespaces'