diff --git a/CHANGES.rst b/CHANGES.rst index e75719ee..cde8a704 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -44,6 +44,8 @@ Unreleased to set the domain, which modern browsers interpret as an exact match rather than a subdomain match. Warnings about ``localhost`` and IP addresses are also removed. :issue:`5051` +- ``config.from_prefixed_env`` supports not trimming the prefix using + ``trim_prefix=False``. :issue:`5060` Version 2.2.4 diff --git a/src/flask/config.py b/src/flask/config.py index 5e48be33..be1ec7ef 100644 --- a/src/flask/config.py +++ b/src/flask/config.py @@ -99,15 +99,21 @@ class Config(dict): return self.from_pyfile(rv, silent=silent) def from_prefixed_env( - self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + self, + prefix: str = "FLASK", + *, + loads: t.Callable[[str], t.Any] = json.loads, + trim_prefix: bool = True, ) -> bool: - """Load any environment variables that start with ``FLASK_``, - dropping the prefix from the env key for the config key. Values - are passed through a loading function to attempt to convert them - to more specific types than strings. + """Load any environment variables that start with ``FLASK_``. + Values are passed through a loading function to attempt to + convert them to more specific types than strings. Keys are loaded in :func:`sorted` order. + The default is to drop the prefix from the env key for the + config key. + The default loading function attempts to parse values as any valid JSON type, including dicts and lists. @@ -121,6 +127,11 @@ class Config(dict): the returned value as the config value. If any error is raised it is ignored and the value remains a string. The default is :func:`json.loads`. + :param trim_prefix: A flag indicating if the prefix should be + dropped for the config key. Defaults to ``True`` + + .. versionchanged:: 2.3 + The ``trim_prefix`` parameter was added. .. versionadded:: 2.1 """ @@ -139,8 +150,9 @@ class Config(dict): # Keep the value as a string if loading failed. pass - # Change to key.removeprefix(prefix) on Python >= 3.9. - key = key[len_prefix:] + if trim_prefix: + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] if "__" not in key: # A non-nested key, set directly. diff --git a/tests/test_config.py b/tests/test_config.py index 580ae864..4d01a5af 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -108,6 +108,18 @@ def test_from_prefixed_env_nested(monkeypatch): assert app.config["NEW"] == {"K": "v"} +def test_from_prefixed_env_no_trim(monkeypatch): + monkeypatch.setenv("FLASK_SECRET_KEY", "asdf") + monkeypatch.setenv("APP_DEBUG", "true") + + app = flask.Flask(__name__) + app.config.from_prefixed_env(trim_prefix=True) + app.config.from_prefixed_env("APP", trim_prefix=False) + + assert app.config["SECRET_KEY"] == "asdf" + assert app.config["APP_DEBUG"] is True + + def test_config_from_mapping(): app = flask.Flask(__name__) app.config.from_mapping({"SECRET_KEY": "config", "TEST_KEY": "foo"})