New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow loading of environment variables into the config #4479
Conversation
src/flask/config.py
Outdated
@@ -97,6 +97,31 @@ def from_envvar(self, variable_name: str, silent: bool = False) -> bool: | |||
) | |||
return self.from_pyfile(rv, silent=silent) | |||
|
|||
def from_prefixed_env(self, prefix: str = "FLASK_") -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that the prefix should include the _
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure here, although I agree dynaconf seems to have set the president of the _
being implied. I'd rather keep it explicit, but I'm happy either way.
I think only accepting strings is too big a limitation, given that it is possible to use types in all other config loading methods. Attempting to convert at least int, float, and bool would cover a lot of cases. It would be nice to also accept list and dict, and maybe use Maybe this should take a |
I agree with the conversion, I've followed dynaconf's convention (although simplified) and used json.loads (dynaconf uses toml). I've also made it configurable via a |
src/flask/config.py
Outdated
@@ -97,6 +105,44 @@ def from_envvar(self, variable_name: str, silent: bool = False) -> bool: | |||
) | |||
return self.from_pyfile(rv, silent=silent) | |||
|
|||
def from_prefixed_env( | |||
self, | |||
prefix: str = "FLASK_", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure what other separator except _
could be used, so I think this shouldn't include the separator. I tried export a.b=c
and export a-b=c
in ZSH and neither worked.
src/flask/config.py
Outdated
for raw_key, value in os.environ.items(): | ||
if raw_key.startswith(prefix): | ||
key = raw_key[len(prefix) :] # Use removeprefix with Python 3.9 | ||
mapping[key] = loads(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the try/except Excetion
should be here so that users don't have to write wrappers for any library they decide to use.
I'm working on finalizing this, including the review I posted above, no need to push anything new. |
I've added support for nested dict access using the If an intermediate key doesn't exist, it will be initialized to an empty dict. This matches how top-level keys work (any config is added, it doesn't already have to be in the config dict), and allows specifying configuration for extensions without requiring calling I did not add support for merging dicts or other nested access like lists or objects, or other advanced features. If even more control of config is needed, users should reach for Dynaconf or another dedicated config library. |
Do we really need/want this level of magic? |
I use it constantly at work, it is really handy for being able to configure deployments in Docker and other platform services. Nested access is nice for grouping config together rather than making it a flat namespace with long individual keys. Flask-SQLAlchemy, for example, has a dict as a config value for engine options. |
This new method will pick out any environment variables with a certain prefix and place them into the config named without the prefix. This makes it easy to use environment variables to configure the app as is now more popular than when Flask started. The prefix should ensure that the environment isn't polluted and the config isn't polluted by environment variables. I've followed the dynaconf convention of trying to parse the environment variable and then falling back to the raw value if parsing fails.
* support nested dict access with "__" separator * don't specify separator in prefix * catch exceptions for any loads function
This new method will pick out any environment variables with a certain
prefix and place them into the config named without the prefix. This
makes it easy to use environment variables to configure the app as is
now more popular than when Flask started.
The prefix should ensure that the environment isn't polluted and the
config isn't polluted by environment variables.
Checklist:
CHANGES.rst
summarizing the change and linking to the issue... versionchanged::
entries in any relevant code docs.pre-commit
hooks and fix any issues.pytest
andtox
, no tests failed.