Add Config.env_prefix option (#1990)

* add Config.env_prefix option

* fix variable name in docs

* simplify test case

* rollback markdown formatting

* Update docs/config.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
This commit is contained in:
Alex Oleshkevich 2023-01-23 00:24:35 +03:00 committed by GitHub
parent 01f9975697
commit 7822568378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 0 deletions

View File

@ -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

View File

@ -54,8 +54,10 @@ class Config:
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 @@ class Config:
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)

View File

@ -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")