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.
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.
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 for async functions to be passed to the Flask class
instance, for example as a view function,
@app.route("/")
async def index():
return "Async hello"
this comes with a cost though of poorer performance than using the
sync equivalent.
asgiref is the standard way to run async code within a sync context,
and is used in Django making it a safe and sane choice for this.
This takes a popular API whereby instead of passing the HTTP method as
an argument to route it is instead used as the method name i.e.
@app.route("/", methods=["POST"])
is now writeable as,
@app.post("/")
This is simply syntatic sugar, it doesn't do anything else, but makes
it slightly easier for users.
I've included all the methods that are relevant and aren't auto
generated i.e. not connect, head, options, and trace.
The implementations were moved to Werkzeug, Flask's functions become
wrappers around Werkzeug to pass some Flask-specific values.
cache_timeout is renamed to max_age. SEND_FILE_MAX_AGE_DEFAULT,
app.send_file_max_age_default, and app.get_send_file_max_age defaults
to None. This tells the browser to use conditional requests rather than
a 12 hour cache.
attachment_filename is renamed to download_name, and is always sent if
a name is known.
Deprecate helpers.safe_join in favor of werkzeug.utils.safe_join.
Removed most of the send_file tests, they're tested in Werkzeug.
In the file upload example, renamed the uploaded_file view to
download_file to avoid a common source of confusion.