Browse Source

Load only predefined variables by default (#2)

* Load only predefined variables by default

* Have ENV_LOAD_ALL be True by default

* Update docs

* Add test asserting default behavior of ENV_LOAD_ALL
master
Brett Langdon 8 years ago
committed by GitHub
parent
commit
7484e6c2fa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 10 deletions
  1. +9
    -0
      README.rst
  2. +6
    -0
      flask_env.py
  3. +31
    -10
      test_flask_env.py

+ 9
- 0
README.rst View File

@ -86,6 +86,14 @@ ENV_PREFIX
The prefix will be removed from the environment variable name when setting in the configuration. The prefix will be removed from the environment variable name when setting in the configuration.
(default: :code:`''`, example: :code:`ENV_PREFIX = 'MYAPP_'`) (default: :code:`''`, example: :code:`ENV_PREFIX = 'MYAPP_'`)
ENV_LOAD_ALL
Whether or not to load all environment variables for the configuration object.
When :code:`False` only settings predefined on the configuration object are loaded, all others are ignored.
When :code:`True` all environment variables defined in :code:`os.environ` will get loaded into your configuration object.
(default :code:`True`)
Note: Future versions will have default of :code:`False`.
Setting configuration values Setting configuration values
---------------------------- ----------------------------
@ -99,3 +107,4 @@ You can set the :code:`flask-env` configuration settings directly on your Flask
class Configuration(metaclass=MetaFlaskEnv): class Configuration(metaclass=MetaFlaskEnv):
ENV_PREFIX = 'MYAPP_' ENV_PREFIX = 'MYAPP_'
ENV_LOAD_ALL = False

+ 6
- 0
flask_env.py View File

@ -13,6 +13,7 @@ class MetaFlaskEnv(type):
# Get our internal settings # Get our internal settings
prefix = dict.get('ENV_PREFIX', '') prefix = dict.get('ENV_PREFIX', '')
load_all = dict.get('ENV_LOAD_ALL', True)
# Override default configuration from environment variables # Override default configuration from environment variables
for key, value in os.environ.items(): for key, value in os.environ.items():
@ -23,6 +24,11 @@ class MetaFlaskEnv(type):
# Strip the prefix from the environment variable name # Strip the prefix from the environment variable name
key = key[len(prefix):] key = key[len(prefix):]
# Unless we specify that we want to load all environment variables
# only load variables that we have predefined on our object
if not load_all and not hasattr(cls, key):
continue
# If value is "true" or "false", parse as a boolean # If value is "true" or "false", parse as a boolean
# Otherwise, if it contains a "." then try to parse as a float # Otherwise, if it contains a "." then try to parse as a float
# Otherwise, try to parse as an integer # Otherwise, try to parse as an integer


+ 31
- 10
test_flask_env.py View File

@ -5,16 +5,29 @@ from flask_env import MetaFlaskEnv
class TestFlaskEnv(unittest.TestCase): class TestFlaskEnv(unittest.TestCase):
def _get_test_configuration(self, env_prefix=''):
def _get_test_configuration(self, env_prefix='', env_load_all=False, **kwargs):
"""Helper to define a new configuration class using our MetaFlaskEnv""" """Helper to define a new configuration class using our MetaFlaskEnv"""
return MetaFlaskEnv('TestConfiguration', (object, ), dict( return MetaFlaskEnv('TestConfiguration', (object, ), dict(
ENV_PREFIX=env_prefix, ENV_PREFIX=env_prefix,
DEFAULT_SETTING='default_value',
ENV_LOAD_ALL=env_load_all,
**kwargs
)) ))
def test_default_env_load_all(self):
"""A test to ensure that we load all environment variables by default"""
# Configure an environment variable not defined on the configuration class
os.environ['TEST_SETTING'] = 'true'
# Create our configuration object
TestConfiguration = MetaFlaskEnv('TestConfiguration', (object, ), dict())
# Assert that we loaded all environment variables
self.assertTrue(TestConfiguration.TEST_SETTING)
def test_default_settings(self): def test_default_settings(self):
"""A test to ensure that if no environment variable is set, we get the default value that is set""" """A test to ensure that if no environment variable is set, we get the default value that is set"""
TestConfiguration = self._get_test_configuration()
TestConfiguration = self._get_test_configuration(DEFAULT_SETTING='default_value')
self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'default_value') self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'default_value')
def test_override_from_env(self): def test_override_from_env(self):
@ -22,7 +35,7 @@ class TestFlaskEnv(unittest.TestCase):
# DEV: We have to set the environment variable first, since they get loaded into the class on definition # DEV: We have to set the environment variable first, since they get loaded into the class on definition
os.environ['DEFAULT_SETTING'] = 'set_by_env' os.environ['DEFAULT_SETTING'] = 'set_by_env'
TestConfiguration = self._get_test_configuration()
TestConfiguration = self._get_test_configuration(DEFAULT_SETTING='default_value')
self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'set_by_env') self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'set_by_env')
def test_only_set_on_env(self): def test_only_set_on_env(self):
@ -30,15 +43,20 @@ class TestFlaskEnv(unittest.TestCase):
# DEV: We have to set the environment variable first, since they get loaded into the class on definition # DEV: We have to set the environment variable first, since they get loaded into the class on definition
os.environ['NEW_SETTING'] = 'set_by_env' os.environ['NEW_SETTING'] = 'set_by_env'
TestConfiguration = self._get_test_configuration()
# When configured to load all environment variables
TestConfiguration = self._get_test_configuration(env_load_all=True)
self.assertEqual(TestConfiguration.NEW_SETTING, 'set_by_env') self.assertEqual(TestConfiguration.NEW_SETTING, 'set_by_env')
# When configured to not load all environment variables
TestConfiguration = self._get_test_configuration(env_load_all=False)
self.assertFalse(hasattr(TestConfiguration, 'NEW_SETTING'))
def test_env_prefix(self): def test_env_prefix(self):
"""A test to ensure that the ENV_PREFIX setting functions as needed""" """A test to ensure that the ENV_PREFIX setting functions as needed"""
# DEV: We have to set the environment variable first, since they get loaded into the class on definition # DEV: We have to set the environment variable first, since they get loaded into the class on definition
os.environ['TEST_DEFAULT_SETTING'] = 'set_by_env' os.environ['TEST_DEFAULT_SETTING'] = 'set_by_env'
TestConfiguration = self._get_test_configuration(env_prefix='TEST_')
TestConfiguration = self._get_test_configuration(env_prefix='TEST_', DEFAULT_SETTING='default_value')
self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'set_by_env') self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'set_by_env')
def test_env_prefix_non_matching(self): def test_env_prefix_non_matching(self):
@ -46,7 +64,7 @@ class TestFlaskEnv(unittest.TestCase):
# DEV: We have to set the environment variable first, since they get loaded into the class on definition # DEV: We have to set the environment variable first, since they get loaded into the class on definition
os.environ['DEFAULT_SETTING'] = 'set_by_env' os.environ['DEFAULT_SETTING'] = 'set_by_env'
TestConfiguration = self._get_test_configuration(env_prefix='MYAPP_')
TestConfiguration = self._get_test_configuration(env_prefix='MYAPP_', DEFAULT_SETTING='default_value')
self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'default_value') self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'default_value')
def test_parsing_boolean(self): def test_parsing_boolean(self):
@ -57,7 +75,8 @@ class TestFlaskEnv(unittest.TestCase):
os.environ['IS_FALSE'] = 'FALSE' os.environ['IS_FALSE'] = 'FALSE'
os.environ['IS_WACKY_FALSE'] = 'FaLSe' os.environ['IS_WACKY_FALSE'] = 'FaLSe'
TestConfiguration = self._get_test_configuration()
# DEV: Set `env_load_all=True` to keep from having to make default values for each variable
TestConfiguration = self._get_test_configuration(env_load_all=True)
self.assertEqual(TestConfiguration.IS_TRUE, True) self.assertEqual(TestConfiguration.IS_TRUE, True)
self.assertEqual(TestConfiguration.IS_NOT_TRUE, 'true-ish') self.assertEqual(TestConfiguration.IS_NOT_TRUE, 'true-ish')
self.assertEqual(TestConfiguration.IS_FALSE, False) self.assertEqual(TestConfiguration.IS_FALSE, False)
@ -71,7 +90,8 @@ class TestFlaskEnv(unittest.TestCase):
os.environ['LEADING_DOT'] = '.12' os.environ['LEADING_DOT'] = '.12'
os.environ['IS_NOT_FLOAT'] = 'This is 6.5' os.environ['IS_NOT_FLOAT'] = 'This is 6.5'
TestConfiguration = self._get_test_configuration()
# DEV: Set `env_load_all=True` to keep from having to make default values for each variable
TestConfiguration = self._get_test_configuration(env_load_all=True)
self.assertEqual(TestConfiguration.IS_FLOAT, 12.5) self.assertEqual(TestConfiguration.IS_FLOAT, 12.5)
self.assertEqual(TestConfiguration.TRAILING_DOT, 12.0) self.assertEqual(TestConfiguration.TRAILING_DOT, 12.0)
self.assertEqual(TestConfiguration.LEADING_DOT, 0.12) self.assertEqual(TestConfiguration.LEADING_DOT, 0.12)
@ -84,7 +104,8 @@ class TestFlaskEnv(unittest.TestCase):
os.environ['IS_ZERO'] = '0' os.environ['IS_ZERO'] = '0'
os.environ['IS_NOT_INT'] = '12fa' os.environ['IS_NOT_INT'] = '12fa'
TestConfiguration = self._get_test_configuration()
# DEV: Set `env_load_all=True` to keep from having to make default values for each variable
TestConfiguration = self._get_test_configuration(env_load_all=True)
self.assertEqual(TestConfiguration.IS_INT, 12) self.assertEqual(TestConfiguration.IS_INT, 12)
self.assertEqual(TestConfiguration.IS_ZERO, 0) self.assertEqual(TestConfiguration.IS_ZERO, 0)
self.assertEqual(TestConfiguration.IS_NOT_INT, '12fa') self.assertEqual(TestConfiguration.IS_NOT_INT, '12fa')


Loading…
Cancel
Save