diff --git a/docs/config.md b/docs/config.md index a879374dc3..853dff3d4e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -113,6 +113,23 @@ from starlette.config import environ environ['TESTING'] = 'TRUE' ``` +## Reading prefixed environment variables + +You can namespace the environment variables by setting `env_prefix` argument. + +```python title="myproject/settings.py" +import os +from starlette.config import Config + +os.environ['APP_DEBUG'] = 'yes' +os.environ['ENVIRONMENT'] = 'dev' + +config = Config(env_prefix='APP_') + +DEBUG = config('DEBUG') # lookups APP_DEBUG, returns "yes" +ENVIRONMENT = config('ENVIRONMENT') # lookups APP_ENVIRONMENT, raises KeyError as variable is not defined +``` + ## A full example Structuring large applications can be complex. You need proper separation of diff --git a/starlette/config.py b/starlette/config.py index 8c58b2738d..795232cf64 100644 --- a/starlette/config.py +++ b/starlette/config.py @@ -54,8 +54,10 @@ def __init__( self, env_file: typing.Optional[typing.Union[str, Path]] = None, environ: typing.Mapping[str, str] = environ, + env_prefix: str = "", ) -> None: self.environ = environ + self.env_prefix = env_prefix self.file_values: typing.Dict[str, str] = {} if env_file is not None and os.path.isfile(env_file): self.file_values = self._read_file(env_file) @@ -103,6 +105,7 @@ def get( cast: typing.Optional[typing.Callable] = None, default: typing.Any = undefined, ) -> typing.Any: + key = self.env_prefix + key if key in self.environ: value = self.environ[key] return self._perform_cast(key, value, cast) diff --git a/tests/test_config.py b/tests/test_config.py index d33000389c..70b0a48120 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -127,3 +127,13 @@ def test_environ(): environ = Environ() assert list(iter(environ)) == list(iter(os.environ)) assert len(environ) == len(os.environ) + + +def test_config_with_env_prefix(tmpdir, monkeypatch): + config = Config( + environ={"APP_DEBUG": "value", "ENVIRONMENT": "dev"}, env_prefix="APP_" + ) + assert config.get("DEBUG") == "value" + + with pytest.raises(KeyError): + config.get("ENVIRONMENT")