Skip to content

Commit efe8a09

Browse files
committed
Add option for raising an error on missing ENV variable
1 parent f1e1db4 commit efe8a09

3 files changed

Lines changed: 43 additions & 6 deletions

File tree

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,26 @@ test1:
154154
```
155155
will raise a `ValueError` because `data1: !TEST ${ENV_TAG2}` there is no default value for `ENV_TAG2` in this line.
156156

157-
---
157+
---
158+
#### Raise an exception on missing environment variable without default
159+
160+
Often, a proper default value for an environment variable doesn't exist and
161+
an exception should be thrown when the environment variable is not set.
162+
163+
If you want config parsing to fail if the environment variable is missing
164+
and no *default value* is specified, you can set the `raise_if_missing`
165+
flag to `True`.
166+
167+
For example:
158168

169+
```yaml
170+
test1:
171+
data1: !TEST ${ENV_TAG2}
172+
```
173+
will raise a `ValueError` when `ENV_TAG2` is missing because no default is set
174+
explicitly.
159175

176+
---
160177
#### Using a different loader:
161178

162179
The default yaml loader is `yaml.SafeLoader`. If you need to work with serialized Python objects,

src/pyaml_env/parse_config.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def parse_config(
1111
default_value='N/A',
1212
raise_if_na=False,
1313
loader=yaml.SafeLoader,
14-
encoding='utf-8'
14+
encoding='utf-8',
15+
raise_if_missing=False
1516
):
1617
"""
1718
Load yaml configuration from path or from the contents of a file (data)
@@ -39,6 +40,8 @@ def parse_config(
3940
yaml.SafeLoader
4041
:param str encoding: the encoding of the data if a path is specified,
4142
defaults to utf-8
43+
:param bool raise_if_missing: raise a ValueError when an env variable
44+
is not set and no default value is given
4245
:return: the dict configuration
4346
:rtype: dict[str, T]
4447
"""
@@ -86,10 +89,15 @@ def constructor_env_variables(loader, node):
8689
_, curr_default_value = each.split(default_sep, 1)
8790
found = True
8891
break
89-
if not found and raise_if_na:
90-
raise ValueError(
91-
f'Could not find default value for {env_var_name}'
92-
)
92+
if not found:
93+
if raise_if_na:
94+
raise ValueError(f'Could not find default value '
95+
f'for {env_var_name}')
96+
if raise_if_missing and env_var_name not in os.environ:
97+
raise ValueError(f'Could not find env variable '
98+
f'{env_var_name} and no default '
99+
f'is set')
100+
93101
full_value = full_value.replace(
94102
f'${{{env_var_name_with_default}}}',
95103
os.environ.get(env_var_name, curr_default_value)

tests/pyaml_env_tests/test_parse_config.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,18 @@ def test_parse_config_default_sep_blank_value_error(self):
582582
expected_config
583583
)
584584

585+
def test_parse_config_raise_if_missing_raised(self):
586+
test_data = 'data0: !TAG ${ENV_TAG1}'
587+
self.assertRaises(ValueError, parse_config, data=test_data, tag='!TAG',
588+
raise_if_missing=True)
589+
590+
def test_parse_config_raise_if_missing_not_raised(self):
591+
default_value = 'default_value'
592+
test_data = f'data0: !TAG ${{ENV_TAG1:{default_value}}}'
593+
config = parse_config(data=test_data, tag='!TAG',
594+
raise_if_missing=True)
595+
self.assertEqual(config['data0'], default_value)
596+
585597
def test_default_loader(self):
586598
os.environ[self.env_var1] = 'it works!'
587599
os.environ[self.env_var2] = 'this works too!'

0 commit comments

Comments
 (0)