Skip to main content

Configuration manager for cloud native application, support configuration stored in memory, in files, in databases

Project description

Latest version on Supported Python versions Travis Pipelines build status codecov

Config42

Config42 is a complete configuration reader and manager. It aims to read the configuration from different sources: a memory Dict object, an external file ( YAML, JSON, INI, PYTHON Object ), an SQL database (Postgres, MySQL, Oracle) alternatively, Key-value data store ( Etcd )

It is designed to be extensible. Different handlers could support another data store. All PR are welcome.

Related blog posts

Install

From sources: (Bleeding edge)

pip install git+https://github.com/yurilaaziz/config42

From PyPi: (Stable)

pip install config42

Getting started

Config42 abstract loading configuration complexity. Let config42 manage your configuration for you.

Using environment variables

Most of the containerised applications change behaviour from environment variables to change their behaviour. config42 handle it easily.

Here a working sample examples/docker

from config42 import ConfigManager
env_config = ConfigManager(prefix="MYAPP")
# Access to configuration via the ConfigManager getter
print("username : {}".format(env_config.get('username')))
print("nested key  : {}".format(env_config.get('secret.one')))

Export variables to system environment

export MYAPP_USERNAME=yuri
export MYAPP_SECRET_ONE=password
python app.py

Export variables to process environment

MYAPP_USERNAME=yuri2 python app.py

Once you build you docker image, you may run the application by export variables into the container environment

docker run  -e MYAPP_USERNAME=yuri -e MYAPP_SECRET_ONE=secret testconfig42:latest

Using Etcd Handler

To load configuration from Etcd data store, you need to specify the keyspace where the configuration is located, Etcd host(s) and port(s).

from config42 import ConfigManager
from config42.handlers import Etcd

config = ConfigManager(handler=Etcd, keyspace='/config')
# config = ConfigManager(handler=Etcd, keyspace='/config', port=4001)
# config = ConfigManager(handler=Etcd, keyspace='/config', host='127.0.0.1', port=4001)
# config = ConfigManager(handler=Etcd, keyspace='/config', host=(('127.0.0.1', 4001), ('127.0.0.1', 4002), ('127.0.0.1', 4003)))

Note : Etcd handler use python-etcd client All args after keyspace are passed to Etcd.Client class.

Using Filehandler, Load configuration from file

from pprint import pprint
from config42 import ConfigManager
from config42.handlers import FileHandler

# Yaml files
config = ConfigManager(handler=FileHandler, path='files/config1.yml')
#config = ConfigManager(handler=FileHandler, path='files/config1.yaml')

# Json file 
#config = ConfigManager(handler=FileHandler, path='files/config1.json')

#INI structure support only one level of nesting (Sections = { key: value }) 
#config = ConfigManager(handler=FileHandler, path='files/config.ini')

CONFIG = config.as_dict()

print("Configuration has been loaded")
pprint(CONFIG)

# Access to configuration via the ConfigManager getter
print("application_name : {}".format(config.get('application_name')))
print("nested key : {}".format(config.get('nested.nestedkey.key2')))

# Access to configuration via the as dict utility; it will dump configuration file to data store if updated
print("user : {}".format(config.as_dict()['user']))

# Access to configuration via the classic CONFIG global variable
print("application_name : {}".format(CONFIG['application_name']))
print("nested key : {}".format(CONFIG['nested']['nestedkey']['key2']))

Using argparse, Load configuration from commandline parameters (sys.argv)

from config42 import ConfigManager
from config42.handlers.argparse import Argparse

schema = [
    dict(key="user", description="username"),
    dict(key="verbosity", description="verbosity level", choices=["debug", "info"]),

]
config = ConfigManager(handler=Argparse, schema=schema)

Please take a look to the example using Argparse's handler

Real use case

Below is a real use from Instabot-Py project that uses this library as a configuration manager.

config42 handles 4 sources of configuration data in order of priority:

  • Default configuration from Dict Object
  • Environment variables prefixed by INSTABOT
  • Local file where value located in config.file (INSTABOT_CONFIG_FILE)
  • Etcd data-store

ref : https://github.com/instabot-py/instabot.py

import logging.config
import os

from config42 import ConfigManager

from instabot_py.default_config import DEFAULT_CONFIG

env_config = ConfigManager(prefix="INSTABOT")
logging.basicConfig(level=logging.DEBUG if env_config.get("debug") else logging.INFO)
LOGGER = logging.getLogger(__name__)
config = ConfigManager()
config.set_many(DEFAULT_CONFIG)

config.set_many(env_config.as_dict())
config_file = config.get("config.file")
config_etcd = config.get("config.etcd")

if config_file:
    if config_file.startswith("/"):
        config_path = config_file
    else:
        cwd = os.getcwd()
        config_path = cwd + "/" + config_file
    config.set_many(ConfigManager(path=config_path.replace('//', '/')).as_dict())
    LOGGER.info("Setting configuration from {} : OK".format(config_file))

if config_etcd:
    if not config_etcd.get("keyspace"):
        raise Exception("etcd Keyspace is mandatory")
    try:
        config.set_many(ConfigManager(**config_etcd).as_dict())
        LOGGER.info(
            "Setting external configuration from {} : OK".format(config_file))
    except Exception as exc:
        LOGGER.error(
            "Setting external configuration from ({}) : NOT OK".format(
                ",".join({key + "=" + value for key, value in config_etcd.items() or {}})
            ))

        LOGGER.exception(exc)
        raise exc

logging.config.dictConfig(config.get("logging"))

Requirements

Yaml configuration files

pip install Pyaml

Etcd data store

pip install python-etcd

DEV

The following packages are needed to run tests and coverage

pip install tox pytest-cov pytest flake8

or

pip install -r requirements/ci.txt
pip install -r requirements/tests.txt

Usage examples

TODO

  • readthedoc with sphinx

Releases

0.3.1

  • Add set default variables feature

0.3

  • Add Environment Handler

0.2

  • Add Etcd Handler
  • Add Ini Yaml, Json Handlers

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

config42-0.4.4-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file config42-0.4.4-py3-none-any.whl.

File metadata

  • Download URL: config42-0.4.4-py3-none-any.whl
  • Upload date:
  • Size: 29.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.7

File hashes

Hashes for config42-0.4.4-py3-none-any.whl
Algorithm Hash digest
SHA256 36ba63fdafc56e4e07e0dfa66b6945ae3294e9b5d3c43e30c46befba45c20398
MD5 58de2a1771a59df66896a20750697361
BLAKE2b-256 b2fa111f9702014938f0e20d1d5eb9ad7bf330b787ec0267460188c04da9212c

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