diff --git a/README.rst b/README.rst index 14f92ed..c2fd35e 100644 --- a/README.rst +++ b/README.rst @@ -86,6 +86,12 @@ ENV_PREFIX The prefix will be removed from the environment variable name when setting in the configuration. (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:`False`) + Setting configuration values ---------------------------- @@ -99,3 +105,4 @@ You can set the :code:`flask-env` configuration settings directly on your Flask class Configuration(metaclass=MetaFlaskEnv): ENV_PREFIX = 'MYAPP_' + ENV_LOAD_ALL = False diff --git a/flask_env.py b/flask_env.py index dd4d554..a17d739 100644 --- a/flask_env.py +++ b/flask_env.py @@ -13,6 +13,7 @@ class MetaFlaskEnv(type): # Get our internal settings prefix = dict.get('ENV_PREFIX', '') + load_all = dict.get('ENV_LOAD_ALL', False) # Override default configuration from environment variables for key, value in os.environ.items(): @@ -23,6 +24,11 @@ class MetaFlaskEnv(type): # Strip the prefix from the environment variable name 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 # Otherwise, if it contains a "." then try to parse as a float # Otherwise, try to parse as an integer diff --git a/test_flask_env.py b/test_flask_env.py index 562da3a..fd37d7f 100644 --- a/test_flask_env.py +++ b/test_flask_env.py @@ -5,16 +5,17 @@ from flask_env import MetaFlaskEnv 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""" return MetaFlaskEnv('TestConfiguration', (object, ), dict( ENV_PREFIX=env_prefix, - DEFAULT_SETTING='default_value', + ENV_LOAD_ALL=env_load_all, + **kwargs )) def test_default_settings(self): """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') def test_override_from_env(self): @@ -22,7 +23,7 @@ class TestFlaskEnv(unittest.TestCase): # 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' - TestConfiguration = self._get_test_configuration() + TestConfiguration = self._get_test_configuration(DEFAULT_SETTING='default_value') self.assertEqual(TestConfiguration.DEFAULT_SETTING, 'set_by_env') def test_only_set_on_env(self): @@ -30,15 +31,20 @@ class TestFlaskEnv(unittest.TestCase): # 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' - 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') + # 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): """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 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') def test_env_prefix_non_matching(self): @@ -46,7 +52,7 @@ class TestFlaskEnv(unittest.TestCase): # 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' - 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') def test_parsing_boolean(self): @@ -57,7 +63,8 @@ class TestFlaskEnv(unittest.TestCase): os.environ['IS_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_NOT_TRUE, 'true-ish') self.assertEqual(TestConfiguration.IS_FALSE, False) @@ -71,7 +78,8 @@ class TestFlaskEnv(unittest.TestCase): os.environ['LEADING_DOT'] = '.12' 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.TRAILING_DOT, 12.0) self.assertEqual(TestConfiguration.LEADING_DOT, 0.12) @@ -84,7 +92,8 @@ class TestFlaskEnv(unittest.TestCase): os.environ['IS_ZERO'] = '0' 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_ZERO, 0) self.assertEqual(TestConfiguration.IS_NOT_INT, '12fa')