Skip to content

Commit

Permalink
allow splitting environment variable values by whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
wryfi committed Apr 26, 2020
1 parent 0ca9428 commit 288986f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
28 changes: 23 additions & 5 deletions cfitall/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from decimal import Decimal
import logging
import json
import re
import os
Expand All @@ -7,16 +8,21 @@
from cfitall import utils


logger = logging.getLogger(__name__)


class ConfigManager(object):
def __init__(self, name, env_prefix=None, env_path_sep='__', env_value_split=True, env_bool=True, defaults={}):
def __init__(self, name, env_prefix=None, env_path_sep='__', env_value_split=True,
env_value_split_space=False, env_bool=True, defaults={}):
"""
The configuration registry holds configuration data from different sources
and reconciles it for retrieval.
:param str name: name of registry (cannot contain env_separator string)
:param str env_prefix: prefix for environment variables (defaults to uppercase name)
:param str env_path_sep: string for separating config hierarchies in env vars (default '__')
:param bool env_value_split: split env var values into python string (on comma)
:param bool env_value_split: split env var values into python list (on comma)
:param bool env_value_split_space: split env var values into python list (on whitespace)
:param bool env_bool: convert 'true' and 'false' strings in env vars to python bools
:param dict defaults: dictionary of default configuration settings
"""
Expand All @@ -26,6 +32,7 @@ def __init__(self, name, env_prefix=None, env_path_sep='__', env_value_split=Tru
self.values = {'super': {}, 'cli': {}, 'cfgfile': {}, 'defaults': defaults}
self.env_path_sep = env_path_sep
self.env_value_split = env_value_split
self.env_value_split_space = env_value_split_space
self.env_bool = env_bool
if env_prefix:
self.env_prefix = env_prefix.upper()
Expand Down Expand Up @@ -211,9 +218,7 @@ def _read_environment(self):
for key, value in os.environ.items():
if key.startswith(prefix):
key = key.replace(prefix, '', 1).lower()
if isinstance(value, str) and self.env_value_split:
if re.match(r'.*,(.*,)*.*', value):
value = value.split(',')
value = self._split_value(value)
if self.env_bool:
if type(value) == str and value.lower() == 'true':
value = True
Expand All @@ -237,3 +242,16 @@ def _merge_configs(self):
config = utils.merge_dicts(self._read_environment(), config)
config = utils.merge_dicts(self.values['super'], config)
return config

def _split_value(self, value):
"""
For now, env_value_split_space always overrides env_value_split;
this may change in a future release.
"""
if self.env_value_split and not self.env_value_split_space:
if re.match(r'.*,(.*,)*.*', value):
return value.split(',')
elif self.env_value_split_space:
if re.match(r'.*\s+(.*\s+)*.*', value):
return re.split(r'\s+', value)
return value
10 changes: 10 additions & 0 deletions cfitall/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ def test_comma_list(self):
cf.env_value_split = False
self.assertEqual(cf.get('test.list'), 'hello,world,melting')

def test_space_list(self):
cf = ConfigManager('cfitall')
cf.set_default('test.list.withspaces', ['flenderson, toby', 'martin, angela'])
self.assertEqual(cf.get('test.list.withcommas'), ['flenderson, toby', 'martin, angela'])
os.environ['CFITALL__TEST__LIST'] = 'hello world melting antarctica broadway'
cf.env_value_split_space = True
self.assertEqual(cf.get('test.list'), ['hello', 'world', 'melting', 'antarctica', 'broadway'])
cf.env_value_split_space = False
self.assertEqual(cf.get('test.list'), 'hello world melting antarctica broadway')

def test_different_keys_same_value(self):
cf = ConfigManager('cfitall')
cf.set_default('test.string', 'hello, world')
Expand Down

0 comments on commit 288986f

Please sign in to comment.