Config.from_prefixed_env: Allow to not trim prefix

Fixes #5060
This commit is contained in:
Felix Stupp 2023-04-14 11:52:37 +02:00
parent 182ce3dd15
commit a34549a33a
No known key found for this signature in database
GPG key ID: 93E1BD26F6B02FB7
3 changed files with 33 additions and 7 deletions

View file

@ -44,6 +44,8 @@ Unreleased
to set the domain, which modern browsers interpret as an exact match rather than 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. a subdomain match. Warnings about ``localhost`` and IP addresses are also removed.
:issue:`5051` :issue:`5051`
- ``config.from_prefixed_env`` supports not trimming the prefix using
``trim_prefix=False``. :issue:`5060`
Version 2.2.4 Version 2.2.4

View file

@ -99,15 +99,21 @@ class Config(dict):
return self.from_pyfile(rv, silent=silent) return self.from_pyfile(rv, silent=silent)
def from_prefixed_env( 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: ) -> bool:
"""Load any environment variables that start with ``FLASK_``, """Load any environment variables that start with ``FLASK_``.
dropping the prefix from the env key for the config key. Values Values are passed through a loading function to attempt to
are passed through a loading function to attempt to convert them convert them to more specific types than strings.
to more specific types than strings.
Keys are loaded in :func:`sorted` order. 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 The default loading function attempts to parse values as any
valid JSON type, including dicts and lists. 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 the returned value as the config value. If any error is
raised it is ignored and the value remains a string. The raised it is ignored and the value remains a string. The
default is :func:`json.loads`. 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 .. versionadded:: 2.1
""" """
@ -139,8 +150,9 @@ class Config(dict):
# Keep the value as a string if loading failed. # Keep the value as a string if loading failed.
pass pass
# Change to key.removeprefix(prefix) on Python >= 3.9. if trim_prefix:
key = key[len_prefix:] # Change to key.removeprefix(prefix) on Python >= 3.9.
key = key[len_prefix:]
if "__" not in key: if "__" not in key:
# A non-nested key, set directly. # A non-nested key, set directly.

View file

@ -108,6 +108,18 @@ def test_from_prefixed_env_nested(monkeypatch):
assert app.config["NEW"] == {"K": "v"} 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(): def test_config_from_mapping():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.config.from_mapping({"SECRET_KEY": "config", "TEST_KEY": "foo"}) app.config.from_mapping({"SECRET_KEY": "config", "TEST_KEY": "foo"})