Skip to content

KyleJamesWalker/yamlsettings

Repository files navigation

YamlSettings

A Settings Configuration Module.

https://travis-ci.org/KyleJamesWalker/yamlsettings.svg?branch=master

A library to help manage project settings, without having to worry about accidentally checking non-public information, like api keys. Along with environment variable support.

Example setup

Python Code - Base Functions

import yamlsettings


app_settings = yamlsettings.load('defaults.yaml')
app_settings.update(yamlsettings.load('settings.yaml'))
yamlsettings.update_from_env(app_settings)
user = app_settings.myproj.databases.primary_sql.user

defaults.yml - Default Settings for Project (tracked)

---
# Program Defaults, do not edit this file!!!
# All values should be overridden in the following ways:
# 1. In the 'settings.yaml' file.
# 2. With environment variables. Example myproj.databases.primary_sql.user can
#    be overridden with MYPROJ_DATABASES_PRIMARY_SQL_USER.
myproj:
  databases:
    primary_sql:
      user: my_user
      passwd: password_here
      host: db-bouncer-01.postgres.com:5432
      db: postgres
      compress: true
      engine: postgresql
    splunk:
      user: splunk_user_here
      passwd: password here
      host: splunk.com
      port: 8089
    redis:
      redis_host: 127.0.0.1
      redis_port: 6379
  flask_config:
    DEBUG: False
    SECRET_KEY: hard key to guess and keep values secret
  debug_sql: false
  debug_profiler: false
  cache_routes: true
  logging_config:
    version: 1
    disable_existing_loggers: False
    formatters:
      light:
        format: '%(asctime)s [%(levelname).1s] %(name)s: %(message)s'
        datefmt: '%Y-%m-%d %H:%M:%S'
      verbose:
        format: '%(asctime)s %(levelname) 8s(%(name)s): %(message)s'
        datefmt: ''
    handlers:
      console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: light
        stream: ext://sys.stdout
      slack:
        class: api.slackLogHandler.BufferingSlackWebHookHandler
        level: INFO
        formatter: light
        capacity: 100
        organization: KyleJamesWalker
        token: need_this
        channel: '#services'
        username: my-proj-logger
        icon_emoji: ':happy_panda:'
      noid:
        class: logging.NullHandler
    loggers:
      requests:
        level: NOTSET
        handlers: [noid]
        propagate: no
    root:
      level: NOTSET
      handlers:
        - console

settings.yml - Custom Settings (untracked)

---
myproj:
  databases:
    primary_sql:
      user: root
      passwd: god
    splunk:
      user: real_user
      passwd: pa$$word
  flask_config:
    SECRET_KEY: sdfasjksdfASFAS23423f@#$%!$#VR@%UQ%
  logging_config:
    handlers:
      slack:
        token: 123243294832104981209
    root:
      handlers:
        - console
        - slack

Example package resource loading

"""Parameters that can be passed are:
 resource: The resource to load from the package (default: settings.yaml)
 env: When set the yamldict will update with env variables (default: true)
 prefix: Prefix for environment loading (default: None)
 persist: When set the yamldict will only be loaded once. (default: true)
"""
yamlsettings.load('package://example')
yamlsettings.load('package://example?resource=diff.yaml')
yamlsettings.load('package://example?prefix=MY_FUN&persist=false')

Plugins

This project also supports plugins. The base project has two plugins:

  • file: Loads from the file system.
  • package: Loads settings from a package resource.

Example Plugin:

setup.py

from setuptools import setup

setup(
    name='yamlsettings-example',
    version='1.0.0',
    author='Kyle Walker',
    author_email='[email protected]',
    description='Quick Example',
    requirements=['yamlsettings'],
    py_modules=['yamlsettings_example'],
    entry_points={
        'yamlsettings10': [
            'ext = yamlsettings_example:ZxcExtension',
        ],
    },
)

yamlsettings_example.py

from yamlsettings.extensions.base import YamlSettingsExtension


class ZxcExtension(YamlSettingsExtension):
    """Quick Example Plugin

    Standard file opener, but will merge in values passed to kwargs
    """
    protocols = ['zxc']

    @classmethod
    def load_target(cls, scheme, path, fragment, username,
                    password, hostname, port, query,
                    load_method, **kwargs):
        full_path = (hostname or '') + path
        obj = load_method(open(full_path, **query))

        # Load all returns a generator list of configurations
        many = isinstance(obj, types.GeneratorType)
        obj = list(obj) if many else obj

        if many:
            for x in obj:
                x.update(kwargs)
        else:
            obj.update(kwargs)

        return obj

usage

import yamlsettings
yamlsettings.load("zxc://defaults.yaml", foo='bar')

# Note: this is automatically detected when the extension is installed
# alternatively the extension can be manually registered with:
yamlsettings.registry.add(ZxcExtension)