The getconf project provides simple configuration helpers for Python programs.
It provides a simple API to read from various configuration files and environment variables:
import getconf
config = getconf.ConfigGetter('myproj', ['/etc/myproj.conf'])
db_host = config.getstr('db.host', 'localhost')
db_port = config.getint('db.port', 5432)Beyond this API, getconf aims at unifying configuration setup across development and production systems, respecting the standard procedures in each system:
- Allow userspace configuration on development systems
- Allow multiple different configurations for continuous integration systems
- Use standard configuration space in
/etcon traditional production servers - Handle environment-based configuration for cloud-based platforms
getconf is distributed under the two-clause BSD license, a copy of
which is in the source.
getconf v1.12 onwards supports Python 3.7, 3.8, 3.9 and 3.10.
v1.11.x are the last versions to support Python 3.5 & 3.6.
v1.9.x are the last versions to support Python 2.7 and 3.4.
v1.8.x are the last versions to support Python 3.3.
v1.5.x are the last versions to support Python 2.6.
- Package on PyPI: http://pypi.python.org/pypi/getconf/
- Doc on ReadTheDocs: http://readthedocs.org/docs/getconf/
- Source on GitHub: http://github.com/Polyconseil/getconf/
Install the package from PyPI, using pip:
pip install getconfOr from GitHub:
git clone git://github.com/Polyconseil/getconfgetconf has no external dependency beyond Python.
Note
Please refer to the full doc for :doc:`reference <reference>` and :doc:`advanced usage <advanced>`.
All configuration values are accessed through the getconf.ConfigGetter object:
import getconf
config = getconf.ConfigGetter('myproj', ['/etc/myproj/settings.ini', './local_settings.ini'])The above line declares:
- Use the
myprojnamespace (explained later; this is mostly used for environment-based configuration, as a prefix for environment variables) - Look, in turn, at
/etc/myproj/settings.ini(for production) and./local_settings.ini(for development); the latter overriding the former.
Once the getconf.ConfigGetter has been configured, it can be used to retrieve settings:
debug = config.getbool('debug', False)
db_host = config.getstr('db.host', 'localhost')
db_port = config.getint('db.port', 5432)
allowed_hosts = config.getlist('django.allowed_hosts', ['*'])All settings have a type (default is text), and accept a default value. They use namespaces (think 'sections') for easier reading.
With the above setup, getconf will try to provide db.host by inspecting
the following options in order (it stops at the first defined value):
- From the environment variable
MYPROJ_DB_HOST, if defined - From the
hostkey in the[db]section of./local_settings.ini - From the
hostkey in the[db]section of/etc/myproj/settings.ini - From the default provided value,
'localhost'
- Env-based configuration files
- An extra configuration file/directory/glob can be provided through
MYPROJ_CONFIG; it takes precedence over other files - Default options
An extra dictionary can be provided as
ConfigGetter(defaults=some_dict); it is used after configuration files and environment variables.It should be a dict mapping a section name to a dict of
key => value:>>> config = ConfigGetter('myproj', defaults={'db': {'host': 'localhost'}}) >>> config.getstr('db.host') 'localhost'
- Typed getters
getconfcan convert options into a few standard types:config.getbool('db.enabled', False) config.getint('db.port', 5432) config.getlist('db.tables') # Expects a comma-separated list config.getfloat('db.auto_vacuum_scale_factor', 0.2) config.gettimedelta('account_activation.validity', '2d') config.getpath('django.static_root', pathlib.Path(BASE_DIR / 'static'))
getconfcan also convert options to user-defined standard-type-based types:class Environment(str, enum.Enum): DEV = 'dev' PROD = 'prod' config.getenum('environment', Environment.PROD)
getconf relies on a few key concepts:
- namespace
Each
ConfigGetterworks within a specific namespace (its first argument).Its goal is to avoid mistakes while reading the environment: with
ConfigGetter(namespace='myproj'), only environment variables beginning withMYPROJ_will be read.It is, however, possible to disable namespacing by using
ConfigGetter(namespace=getconf.NO_NAMESPACE).- Sections
The configuration options for a project often grow quite a lot; to restrict complexity,
getconfsplits values into sections, similar to Python'sconfigparsermodule.Section are handled differently depending on the actual configuration source:
section.keyis mapped toMYPROJ_SECTION_KEYfor environment variablessection.keyis mapped to[section] key =in configuration filessection.keyis mapped todefaults['section']['key']in the defaults dict.
- Default section
Some settings are actually "globals" for a projet. This is handled by unset section names:
keyis mapped toMYPROJ_KEYfor environment variableskeyis mapped to[DEFAULT] key =in configuration fileskeyis mapped todefaults['DEFAULT']['key']in the defaults dict.