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.
Handlers registered via url_value_preprocessor, before_request,
context_processor, and url_defaults are called in downward order: First
on the app and last on the current blueprint.
Handlers registered via after_request and teardown_request are called
in upward order: First on the current blueprint and last on the app.
Previously the blueprint recorded aspects (before request, after
request etc) would only be added to the app if it was the first
registration of the blueprint instance. However only the record-once
aspects (app-before requests, app-after request) should be added once
on registration of the instance, whereas everything else should be
added on every unique name registration. This ensures that these
trigger under the new name as well as the old.
It is better to encourage users to utilise the app ensure_sync method
(or the newely added async_to_sync method) so that any extensions that
alter these methods take affect throughout the users code.
With the helper method users code fix parts of their code to the
asgiref async_to_sync ignoring any extension changes.
Firstly `run_sync` was a misleading name as it didn't run anything,
instead I think `async_to_sync` is much clearer as it converts a
coroutine function to a function. (Name stolen from asgiref).
Secondly trying to run the ensure_sync during registration made the
code more complex and brittle, e.g. the _flask_async_wrapper
usage. This was done to pay any setup costs during registration rather
than runtime, however this only saved a iscoroutne check. It allows
the weirdness of the Blueprint and Scaffold ensure_sync methods to be
removed.
Switching to runtime ensure_sync usage provides a method for
extensions to also support async, as now documented.
As long as popular libraries (e.g. Celery) require click 7, depending
on Click 8 in Flask makes it hard to test the latest version (and its
other dependencies) in existing applications.
Wrapped functions are not comparable, see
https://bugs.python.org/issue3564, therefore a marker is used to note
when the function has been sync wrapped to allow comparison with the
wrapped function instead.
This ensures that multiple route decorators work without raising
exceptions i.e.,
@app.route("/")
@app.route("/a")
async def index():
...
works.
This allows blueprints to be nested within blueprints via a new
Blueprint.register_blueprint method. This should provide a use case
that has been desired for the past ~10 years.
This works by setting the endpoint name to be the blueprint names,
from parent to child delimeted by "." and then iterating over the
blueprint names in reverse order in the app (from most specific to
most general). This means that the expectation of nesting a blueprint
within a nested blueprint is met.
This allows extensions to override the Flask.ensure_sync method and
have the change apply to blueprints as well. Without this change it is
possible for differing blueprints to have differing ensure_sync
approaches depending on the extension used - which would likely result
in event-loop blocking issues.
This also allows blueprints to have a custom ensure_sync, although
this is a by product rather than an expected use case.