diff --git a/environs/__init__.py b/environs/__init__.py index ef13d64..ffb025b 100644 --- a/environs/__init__.py +++ b/environs/__init__.py @@ -495,7 +495,7 @@ def _get_from_environ( proxy env key. """ env_key = self._get_key(key, omit_prefix=proxied) - value = os.environ.get(env_key, default) + value = self._get_value(env_key, default) if hasattr(value, "strip"): expand_match = self.expand_vars and _EXPANDED_VAR_PATTERN.match(value) if expand_match: # Full match expand_vars - special case keep default @@ -535,3 +535,20 @@ def _expand_vars(self, parsed_key, value): def _get_key(self, key: _StrType, *, omit_prefix: _BoolType = False) -> _StrType: return self._prefix + key if self._prefix and not omit_prefix else key + + @staticmethod + def _get_value(env_key, default): + return os.environ.get(env_key, default) + + +class FileAwareEnv(Env): + """An environment variable reader that supports reading values from files.""" + + @staticmethod + def _get_value(env_key, default): + file_key = env_key + "_FILE" + if file_location := os.environ.get(file_key, None): + return Path(file_location).read_text() + else: + return os.environ.get(env_key, default) + diff --git a/tests/test_environs.py b/tests/test_environs.py index 70f3034..8eb0cca 100644 --- a/tests/test_environs.py +++ b/tests/test_environs.py @@ -837,3 +837,18 @@ def test_composite_types(self, env, set_env): "foo": "bar", "wget_params": '--header="Referer: https://radiocut.fm/"', } + + +class TestFileAwareEnv: + @pytest.fixture + def env(self): + return environs.FileAwareEnv(expand_vars=True) + + def test_full_expand_vars(self, env, set_env): + set_env( + { + "MAIN": "legacy_value", + "MAIN_FILE": HERE / "subfolder/.another.env", + } + ) + assert env.str("MAIN") == "CUSTOM_STRING=bar\n"