more from_prefixed_env features

* support nested dict access with "__" separator
* don't specify separator in prefix
* catch exceptions for any loads function
This commit is contained in:
David Lord 2022-03-25 11:00:32 -07:00
parent 08a283af5e
commit 4eb5e9455b
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
4 changed files with 136 additions and 62 deletions

View file

@ -521,7 +521,8 @@ configuration values directly from the environment. Flask can be
instructed to load all environment variables starting with a specific
prefix into the config using :meth:`~flask.Config.from_prefixed_env`.
Environment variables can be set in the shell before starting the server:
Environment variables can be set in the shell before starting the
server:
.. tabs::
@ -561,30 +562,43 @@ Environment variables can be set in the shell before starting the server:
> flask run
* Running on http://127.0.0.1:5000/
The variables can then be loaded and accessed via the config with a
key equal to the environment variable name without the prefix i.e.
The variables can then be loaded and accessed via the config with a key
equal to the environment variable name without the prefix i.e.
.. code-block:: python
app.config.from_prefixed_env()
app.config["SECRET_KEY"] # Is "5f352379324c22463451387a0aec5d2f"
The prefix is ``FLASK_`` by default, however it is an configurable via
the ``prefix`` argument of :meth:`~flask.Config.from_prefixed_env`.
The prefix is ``FLASK_`` by default. This is configurable via the
``prefix`` argument of :meth:`~flask.Config.from_prefixed_env`.
Whilst the value of any environment variable is a string, it will be
parsed before being placed into the flask config. By default the
parsing is done by json.loads, however this is configurable via the
``loads`` argument of :meth:`~flask.Config.from_prefixed_env`.
Values will be parsed to attempt to convert them to a more specific type
than strings. By default :func:`json.loads` is used, so any valid JSON
value is possible, including lists and dicts. This is configurable via
the ``loads`` argument of :meth:`~flask.Config.from_prefixed_env`.
Notice that any value besides an empty string will be interpreted as a boolean
``True`` value in Python, which requires care if an environment explicitly sets
values intended to be ``False``.
When adding a boolean value with the default JSON parsing, only "true"
and "false", lowercase, are valid values. Keep in mind that any
non-empty string is considered ``True`` by Python.
Make sure to load the configuration very early on, so that extensions have the
ability to access the configuration when starting up. There are other methods
on the config object as well to load from individual files. For a complete
reference, read the :class:`~flask.Config` class documentation.
It is possible to set keys in nested dictionaries by separating the
keys with double underscore (``__``). Any intermediate keys that don't
exist on the parent dict will be initialized to an empty dict.
.. code-block:: text
$ export FLASK_MYAPI__credentials__username=user123
.. code-block:: python
app.config["MYAPI"]["credentials"]["username"] # Is "user123"
For even more config loading features, including merging, try a
dedicated library such as Dynaconf_, which includes integration with
Flask.
.. _Dynaconf: https://www.dynaconf.com/
Configuration Best Practices
@ -604,6 +618,10 @@ that experience:
limit yourself to request-only accesses to the configuration you can
reconfigure the object later on as needed.
3. Make sure to load the configuration very early on, so that
extensions can access the configuration when calling ``init_app``.
.. _config-dev-prod:
Development / Production