+
+
+'''
+
+@app.before_request
+def before_request():
+ """请求前钩子 - 记录请求信息"""
+ g.request_start = 'Request started'
+
+@app.route('/')
+def index():
+ """首页路由"""
+ return render_template_string(HOME_TEMPLATE, messages=messages)
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+ """登录路由"""
+ if request.method == 'POST':
+ username = request.form['username']
+ password = request.form['password']
+ if username in users and users[username] == password:
+ session['username'] = username
+ flash('登录成功!')
+ return redirect(url_for('index'))
+ flash('用户名或密码错误!')
+ return render_template_string(LOGIN_TEMPLATE)
+
+@app.route('/register', methods=['GET', 'POST'])
+def register():
+ """注册路由"""
+ if request.method == 'POST':
+ username = request.form['username']
+ password = request.form['password']
+ if username in users:
+ flash('用户名已存在!')
+ else:
+ users[username] = password
+ flash('注册成功,请登录!')
+ return redirect(url_for('login'))
+ return render_template_string(REGISTER_TEMPLATE)
+
+@app.route('/logout')
+def logout():
+ """退出登录"""
+ session.pop('username', None)
+ flash('已退出登录')
+ return redirect(url_for('index'))
+
+@app.route('/message', methods=['POST'])
+def add_message():
+ """添加留言"""
+ content = request.form.get('content', '')
+ username = session.get('username', '匿名用户')
+ if content:
+ messages.append({'user': username, 'content': content})
+ return redirect(url_for('index'))
+
+@app.route('/api/info')
+def api_info():
+ """API 接口 - 返回 JSON 数据"""
+ return jsonify({
+ 'app_name': 'Flask Demo',
+ 'version': '1.0',
+ 'total_users': len(users),
+ 'total_messages': len(messages)
+ })
+
+if __name__ == '__main__':
+ print("Flask 示例应用")
+ print("运行命令: flask run 或 python demo_app.py")
+ print("访问地址: http://127.0.0.1:5000")
+ app.run(debug=True)
diff --git a/src/flask-main/.devcontainer/devcontainer.json b/src/flask-main/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..4519826
--- /dev/null
+++ b/src/flask-main/.devcontainer/devcontainer.json
@@ -0,0 +1,17 @@
+{
+ "name": "pallets/flask",
+ "image": "mcr.microsoft.com/devcontainers/python:3",
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "python.defaultInterpreterPath": "${workspaceFolder}/.venv",
+ "python.terminal.activateEnvInCurrentTerminal": true,
+ "python.terminal.launchArgs": [
+ "-X",
+ "dev"
+ ]
+ }
+ }
+ },
+ "onCreateCommand": ".devcontainer/on-create-command.sh"
+}
diff --git a/src/flask-main/.devcontainer/on-create-command.sh b/src/flask-main/.devcontainer/on-create-command.sh
new file mode 100644
index 0000000..eaebea6
--- /dev/null
+++ b/src/flask-main/.devcontainer/on-create-command.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -e
+python3 -m venv --upgrade-deps .venv
+. .venv/bin/activate
+pip install -r requirements/dev.txt
+pip install -e .
+pre-commit install --install-hooks
diff --git a/src/flask-main/.editorconfig b/src/flask-main/.editorconfig
new file mode 100644
index 0000000..2ff985a
--- /dev/null
+++ b/src/flask-main/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+end_of_line = lf
+charset = utf-8
+max_line_length = 88
+
+[*.{css,html,js,json,jsx,scss,ts,tsx,yaml,yml}]
+indent_size = 2
diff --git a/src/flask-main/.gitignore b/src/flask-main/.gitignore
new file mode 100644
index 0000000..8441e5a
--- /dev/null
+++ b/src/flask-main/.gitignore
@@ -0,0 +1,8 @@
+.idea/
+.vscode/
+__pycache__/
+dist/
+.coverage*
+htmlcov/
+.tox/
+docs/_build/
diff --git a/src/flask-main/.pre-commit-config.yaml b/src/flask-main/.pre-commit-config.yaml
new file mode 100644
index 0000000..eeeee43
--- /dev/null
+++ b/src/flask-main/.pre-commit-config.yaml
@@ -0,0 +1,18 @@
+repos:
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: 488940d9de1b658fac229e34c521d75a6ea476f2 # frozen: v0.14.5
+ hooks:
+ - id: ruff
+ - id: ruff-format
+ - repo: https://github.com/astral-sh/uv-pre-commit
+ rev: b6675a113e27a9b18f3d60c05794d62ca80c7ab5 # frozen: 0.9.9
+ hooks:
+ - id: uv-lock
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
+ hooks:
+ - id: check-merge-conflict
+ - id: debug-statements
+ - id: fix-byte-order-marker
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
diff --git a/src/flask-main/.readthedocs.yaml b/src/flask-main/.readthedocs.yaml
new file mode 100644
index 0000000..acbd83f
--- /dev/null
+++ b/src/flask-main/.readthedocs.yaml
@@ -0,0 +1,10 @@
+version: 2
+build:
+ os: ubuntu-24.04
+ tools:
+ python: '3.13'
+ commands:
+ - asdf plugin add uv
+ - asdf install uv latest
+ - asdf global uv latest
+ - uv run --group docs sphinx-build -W -b dirhtml docs $READTHEDOCS_OUTPUT/html
diff --git a/src/flask-main/CHANGES.rst b/src/flask-main/CHANGES.rst
new file mode 100644
index 0000000..efd076e
--- /dev/null
+++ b/src/flask-main/CHANGES.rst
@@ -0,0 +1,1644 @@
+Version 3.2.0
+-------------
+
+Unreleased
+
+- Drop support for Python 3.9. :pr:`5730`
+- Remove previously deprecated code: ``__version__``. :pr:`5648`
+- ``RequestContext`` has merged with ``AppContext``. ``RequestContext`` is now
+ a deprecated alias. If an app context is already pushed, it is not reused
+ when dispatching a request. This greatly simplifies the internal code for tracking
+ the active context. :issue:`5639`
+- Many ``Flask`` methods involved in request dispatch now take the current
+ ``AppContext`` as the first parameter, instead of using the proxy objects.
+ If subclasses were overriding these methods, the old signature is detected,
+ shows a deprecation warning, and will continue to work during the
+ deprecation period. :issue:`5815`
+- ``template_filter``, ``template_test``, and ``template_global`` decorators
+ can be used without parentheses. :issue:`5729`
+
+
+Version 3.1.2
+-------------
+
+Released 2025-08-19
+
+- ``stream_with_context`` does not fail inside async views. :issue:`5774`
+- When using ``follow_redirects`` in the test client, the final state
+ of ``session`` is correct. :issue:`5786`
+- Relax type hint for passing bytes IO to ``send_file``. :issue:`5776`
+
+
+Version 3.1.1
+-------------
+
+Released 2025-05-13
+
+- Fix signing key selection order when key rotation is enabled via
+ ``SECRET_KEY_FALLBACKS``. :ghsa:`4grg-w6v8-c28g`
+- Fix type hint for ``cli_runner.invoke``. :issue:`5645`
+- ``flask --help`` loads the app and plugins first to make sure all commands
+ are shown. :issue:`5673`
+- Mark sans-io base class as being able to handle views that return
+ ``AsyncIterable``. This is not accurate for Flask, but makes typing easier
+ for Quart. :pr:`5659`
+
+
+Version 3.1.0
+-------------
+
+Released 2024-11-13
+
+- Drop support for Python 3.8. :pr:`5623`
+- Update minimum dependency versions to latest feature releases.
+ Werkzeug >= 3.1, ItsDangerous >= 2.2, Blinker >= 1.9. :pr:`5624,5633`
+- Provide a configuration option to control automatic option
+ responses. :pr:`5496`
+- ``Flask.open_resource``/``open_instance_resource`` and
+ ``Blueprint.open_resource`` take an ``encoding`` parameter to use when
+ opening in text mode. It defaults to ``utf-8``. :issue:`5504`
+- ``Request.max_content_length`` can be customized per-request instead of only
+ through the ``MAX_CONTENT_LENGTH`` config. Added
+ ``MAX_FORM_MEMORY_SIZE`` and ``MAX_FORM_PARTS`` config. Added documentation
+ about resource limits to the security page. :issue:`5625`
+- Add support for the ``Partitioned`` cookie attribute (CHIPS), with the
+ ``SESSION_COOKIE_PARTITIONED`` config. :issue:`5472`
+- ``-e path`` takes precedence over default ``.env`` and ``.flaskenv`` files.
+ ``load_dotenv`` loads default files in addition to a path unless
+ ``load_defaults=False`` is passed. :issue:`5628`
+- Support key rotation with the ``SECRET_KEY_FALLBACKS`` config, a list of old
+ secret keys that can still be used for unsigning. Extensions will need to
+ add support. :issue:`5621`
+- Fix how setting ``host_matching=True`` or ``subdomain_matching=False``
+ interacts with ``SERVER_NAME``. Setting ``SERVER_NAME`` no longer restricts
+ requests to only that domain. :issue:`5553`
+- ``Request.trusted_hosts`` is checked during routing, and can be set through
+ the ``TRUSTED_HOSTS`` config. :issue:`5636`
+
+
+Version 3.0.3
+-------------
+
+Released 2024-04-07
+
+- The default ``hashlib.sha1`` may not be available in FIPS builds. Don't
+ access it at import time so the developer has time to change the default.
+ :issue:`5448`
+- Don't initialize the ``cli`` attribute in the sansio scaffold, but rather in
+ the ``Flask`` concrete class. :pr:`5270`
+
+
+Version 3.0.2
+-------------
+
+Released 2024-02-03
+
+- Correct type for ``jinja_loader`` property. :issue:`5388`
+- Fix error with ``--extra-files`` and ``--exclude-patterns`` CLI options.
+ :issue:`5391`
+
+
+Version 3.0.1
+-------------
+
+Released 2024-01-18
+
+- Correct type for ``path`` argument to ``send_file``. :issue:`5336`
+- Fix a typo in an error message for the ``flask run --key`` option. :pr:`5344`
+- Session data is untagged without relying on the built-in ``json.loads``
+ ``object_hook``. This allows other JSON providers that don't implement that.
+ :issue:`5381`
+- Address more type findings when using mypy strict mode. :pr:`5383`
+
+
+Version 3.0.0
+-------------
+
+Released 2023-09-30
+
+- Remove previously deprecated code. :pr:`5223`
+- Deprecate the ``__version__`` attribute. Use feature detection, or
+ ``importlib.metadata.version("flask")``, instead. :issue:`5230`
+- Restructure the code such that the Flask (app) and Blueprint
+ classes have Sans-IO bases. :pr:`5127`
+- Allow self as an argument to url_for. :pr:`5264`
+- Require Werkzeug >= 3.0.0.
+
+
+Version 2.3.3
+-------------
+
+Released 2023-08-21
+
+- Python 3.12 compatibility.
+- Require Werkzeug >= 2.3.7.
+- Use ``flit_core`` instead of ``setuptools`` as build backend.
+- Refactor how an app's root and instance paths are determined. :issue:`5160`
+
+
+Version 2.3.2
+-------------
+
+Released 2023-05-01
+
+- Set ``Vary: Cookie`` header when the session is accessed, modified, or refreshed.
+- Update Werkzeug requirement to >=2.3.3 to apply recent bug fixes.
+ :ghsa:`m2qf-hxjv-5gpq`
+
+
+Version 2.3.1
+-------------
+
+Released 2023-04-25
+
+- Restore deprecated ``from flask import Markup``. :issue:`5084`
+
+
+Version 2.3.0
+-------------
+
+Released 2023-04-25
+
+- Drop support for Python 3.7. :pr:`5072`
+- Update minimum requirements to the latest versions: Werkzeug>=2.3.0, Jinja2>3.1.2,
+ itsdangerous>=2.1.2, click>=8.1.3.
+- Remove previously deprecated code. :pr:`4995`
+
+ - The ``push`` and ``pop`` methods of the deprecated ``_app_ctx_stack`` and
+ ``_request_ctx_stack`` objects are removed. ``top`` still exists to give
+ extensions more time to update, but it will be removed.
+ - The ``FLASK_ENV`` environment variable, ``ENV`` config key, and ``app.env``
+ property are removed.
+ - The ``session_cookie_name``, ``send_file_max_age_default``, ``use_x_sendfile``,
+ ``propagate_exceptions``, and ``templates_auto_reload`` properties on ``app``
+ are removed.
+ - The ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_MIMETYPE``, and
+ ``JSONIFY_PRETTYPRINT_REGULAR`` config keys are removed.
+ - The ``app.before_first_request`` and ``bp.before_app_first_request`` decorators
+ are removed.
+ - ``json_encoder`` and ``json_decoder`` attributes on app and blueprint, and the
+ corresponding ``json.JSONEncoder`` and ``JSONDecoder`` classes, are removed.
+ - The ``json.htmlsafe_dumps`` and ``htmlsafe_dump`` functions are removed.
+ - Calling setup methods on blueprints after registration is an error instead of a
+ warning. :pr:`4997`
+
+- Importing ``escape`` and ``Markup`` from ``flask`` is deprecated. Import them
+ directly from ``markupsafe`` instead. :pr:`4996`
+- The ``app.got_first_request`` property is deprecated. :pr:`4997`
+- The ``locked_cached_property`` decorator is deprecated. Use a lock inside the
+ decorated function if locking is needed. :issue:`4993`
+- Signals are always available. ``blinker>=1.6.2`` is a required dependency. The
+ ``signals_available`` attribute is deprecated. :issue:`5056`
+- Signals support ``async`` subscriber functions. :pr:`5049`
+- Remove uses of locks that could cause requests to block each other very briefly.
+ :issue:`4993`
+- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
+ :pr:`4947`
+- Ensure subdomains are applied with nested blueprints. :issue:`4834`
+- ``config.from_file`` can use ``text=False`` to indicate that the parser wants a
+ binary file instead. :issue:`4989`
+- If a blueprint is created with an empty name it raises a ``ValueError``.
+ :issue:`5010`
+- ``SESSION_COOKIE_DOMAIN`` does not fall back to ``SERVER_NAME``. The default is not
+ 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.
+ :issue:`5051`
+- The ``routes`` command shows each rule's ``subdomain`` or ``host`` when domain
+ matching is in use. :issue:`5004`
+- Use postponed evaluation of annotations. :pr:`5071`
+
+
+Version 2.2.5
+-------------
+
+Released 2023-05-02
+
+- Update for compatibility with Werkzeug 2.3.3.
+- Set ``Vary: Cookie`` header when the session is accessed, modified, or refreshed.
+
+
+Version 2.2.4
+-------------
+
+Released 2023-04-25
+
+- Update for compatibility with Werkzeug 2.3.
+
+
+Version 2.2.3
+-------------
+
+Released 2023-02-15
+
+- Autoescape is enabled by default for ``.svg`` template files. :issue:`4831`
+- Fix the type of ``template_folder`` to accept ``pathlib.Path``. :issue:`4892`
+- Add ``--debug`` option to the ``flask run`` command. :issue:`4777`
+
+
+Version 2.2.2
+-------------
+
+Released 2022-08-08
+
+- Update Werkzeug dependency to >= 2.2.2. This includes fixes related
+ to the new faster router, header parsing, and the development
+ server. :pr:`4754`
+- Fix the default value for ``app.env`` to be ``"production"``. This
+ attribute remains deprecated. :issue:`4740`
+
+
+Version 2.2.1
+-------------
+
+Released 2022-08-03
+
+- Setting or accessing ``json_encoder`` or ``json_decoder`` raises a
+ deprecation warning. :issue:`4732`
+
+
+Version 2.2.0
+-------------
+
+Released 2022-08-01
+
+- Remove previously deprecated code. :pr:`4667`
+
+ - Old names for some ``send_file`` parameters have been removed.
+ ``download_name`` replaces ``attachment_filename``, ``max_age``
+ replaces ``cache_timeout``, and ``etag`` replaces ``add_etags``.
+ Additionally, ``path`` replaces ``filename`` in
+ ``send_from_directory``.
+ - The ``RequestContext.g`` property returning ``AppContext.g`` is
+ removed.
+
+- Update Werkzeug dependency to >= 2.2.
+- The app and request contexts are managed using Python context vars
+ directly rather than Werkzeug's ``LocalStack``. This should result
+ in better performance and memory use. :pr:`4682`
+
+ - Extension maintainers, be aware that ``_app_ctx_stack.top``
+ and ``_request_ctx_stack.top`` are deprecated. Store data on
+ ``g`` instead using a unique prefix, like
+ ``g._extension_name_attr``.
+
+- The ``FLASK_ENV`` environment variable and ``app.env`` attribute are
+ deprecated, removing the distinction between development and debug
+ mode. Debug mode should be controlled directly using the ``--debug``
+ option or ``app.run(debug=True)``. :issue:`4714`
+- Some attributes that proxied config keys on ``app`` are deprecated:
+ ``session_cookie_name``, ``send_file_max_age_default``,
+ ``use_x_sendfile``, ``propagate_exceptions``, and
+ ``templates_auto_reload``. Use the relevant config keys instead.
+ :issue:`4716`
+- Add new customization points to the ``Flask`` app object for many
+ previously global behaviors.
+
+ - ``flask.url_for`` will call ``app.url_for``. :issue:`4568`
+ - ``flask.abort`` will call ``app.aborter``.
+ ``Flask.aborter_class`` and ``Flask.make_aborter`` can be used
+ to customize this aborter. :issue:`4567`
+ - ``flask.redirect`` will call ``app.redirect``. :issue:`4569`
+ - ``flask.json`` is an instance of ``JSONProvider``. A different
+ provider can be set to use a different JSON library.
+ ``flask.jsonify`` will call ``app.json.response``, other
+ functions in ``flask.json`` will call corresponding functions in
+ ``app.json``. :pr:`4692`
+
+- JSON configuration is moved to attributes on the default
+ ``app.json`` provider. ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``,
+ ``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` are
+ deprecated. :pr:`4692`
+- Setting custom ``json_encoder`` and ``json_decoder`` classes on the
+ app or a blueprint, and the corresponding ``json.JSONEncoder`` and
+ ``JSONDecoder`` classes, are deprecated. JSON behavior can now be
+ overridden using the ``app.json`` provider interface. :pr:`4692`
+- ``json.htmlsafe_dumps`` and ``json.htmlsafe_dump`` are deprecated,
+ the function is built-in to Jinja now. :pr:`4692`
+- Refactor ``register_error_handler`` to consolidate error checking.
+ Rewrite some error messages to be more consistent. :issue:`4559`
+- Use Blueprint decorators and functions intended for setup after
+ registering the blueprint will show a warning. In the next version,
+ this will become an error just like the application setup methods.
+ :issue:`4571`
+- ``before_first_request`` is deprecated. Run setup code when creating
+ the application instead. :issue:`4605`
+- Added the ``View.init_every_request`` class attribute. If a view
+ subclass sets this to ``False``, the view will not create a new
+ instance on every request. :issue:`2520`.
+- A ``flask.cli.FlaskGroup`` Click group can be nested as a
+ sub-command in a custom CLI. :issue:`3263`
+- Add ``--app`` and ``--debug`` options to the ``flask`` CLI, instead
+ of requiring that they are set through environment variables.
+ :issue:`2836`
+- Add ``--env-file`` option to the ``flask`` CLI. This allows
+ specifying a dotenv file to load in addition to ``.env`` and
+ ``.flaskenv``. :issue:`3108`
+- It is no longer required to decorate custom CLI commands on
+ ``app.cli`` or ``blueprint.cli`` with ``@with_appcontext``, an app
+ context will already be active at that point. :issue:`2410`
+- ``SessionInterface.get_expiration_time`` uses a timezone-aware
+ value. :pr:`4645`
+- View functions can return generators directly instead of wrapping
+ them in a ``Response``. :pr:`4629`
+- Add ``stream_template`` and ``stream_template_string`` functions to
+ render a template as a stream of pieces. :pr:`4629`
+- A new implementation of context preservation during debugging and
+ testing. :pr:`4666`
+
+ - ``request``, ``g``, and other context-locals point to the
+ correct data when running code in the interactive debugger
+ console. :issue:`2836`
+ - Teardown functions are always run at the end of the request,
+ even if the context is preserved. They are also run after the
+ preserved context is popped.
+ - ``stream_with_context`` preserves context separately from a
+ ``with client`` block. It will be cleaned up when
+ ``response.get_data()`` or ``response.close()`` is called.
+
+- Allow returning a list from a view function, to convert it to a
+ JSON response like a dict is. :issue:`4672`
+- When type checking, allow ``TypedDict`` to be returned from view
+ functions. :pr:`4695`
+- Remove the ``--eager-loading/--lazy-loading`` options from the
+ ``flask run`` command. The app is always eager loaded the first
+ time, then lazily loaded in the reloader. The reloader always prints
+ errors immediately but continues serving. Remove the internal
+ ``DispatchingApp`` middleware used by the previous implementation.
+ :issue:`4715`
+
+
+Version 2.1.3
+-------------
+
+Released 2022-07-13
+
+- Inline some optional imports that are only used for certain CLI
+ commands. :pr:`4606`
+- Relax type annotation for ``after_request`` functions. :issue:`4600`
+- ``instance_path`` for namespace packages uses the path closest to
+ the imported submodule. :issue:`4610`
+- Clearer error message when ``render_template`` and
+ ``render_template_string`` are used outside an application context.
+ :pr:`4693`
+
+
+Version 2.1.2
+-------------
+
+Released 2022-04-28
+
+- Fix type annotation for ``json.loads``, it accepts str or bytes.
+ :issue:`4519`
+- The ``--cert`` and ``--key`` options on ``flask run`` can be given
+ in either order. :issue:`4459`
+
+
+Version 2.1.1
+-------------
+
+Released on 2022-03-30
+
+- Set the minimum required version of importlib_metadata to 3.6.0,
+ which is required on Python < 3.10. :issue:`4502`
+
+
+Version 2.1.0
+-------------
+
+Released 2022-03-28
+
+- Drop support for Python 3.6. :pr:`4335`
+- Update Click dependency to >= 8.0. :pr:`4008`
+- Remove previously deprecated code. :pr:`4337`
+
+ - The CLI does not pass ``script_info`` to app factory functions.
+ - ``config.from_json`` is replaced by
+ ``config.from_file(name, load=json.load)``.
+ - ``json`` functions no longer take an ``encoding`` parameter.
+ - ``safe_join`` is removed, use ``werkzeug.utils.safe_join``
+ instead.
+ - ``total_seconds`` is removed, use ``timedelta.total_seconds``
+ instead.
+ - The same blueprint cannot be registered with the same name. Use
+ ``name=`` when registering to specify a unique name.
+ - The test client's ``as_tuple`` parameter is removed. Use
+ ``response.request.environ`` instead. :pr:`4417`
+
+- Some parameters in ``send_file`` and ``send_from_directory`` were
+ renamed in 2.0. The deprecation period for the old names is extended
+ to 2.2. Be sure to test with deprecation warnings visible.
+
+ - ``attachment_filename`` is renamed to ``download_name``.
+ - ``cache_timeout`` is renamed to ``max_age``.
+ - ``add_etags`` is renamed to ``etag``.
+ - ``filename`` is renamed to ``path``.
+
+- The ``RequestContext.g`` property is deprecated. Use ``g`` directly
+ or ``AppContext.g`` instead. :issue:`3898`
+- ``copy_current_request_context`` can decorate async functions.
+ :pr:`4303`
+- The CLI uses ``importlib.metadata`` instead of ``pkg_resources`` to
+ load command entry points. :issue:`4419`
+- Overriding ``FlaskClient.open`` will not cause an error on redirect.
+ :issue:`3396`
+- Add an ``--exclude-patterns`` option to the ``flask run`` CLI
+ command to specify patterns that will be ignored by the reloader.
+ :issue:`4188`
+- When using lazy loading (the default with the debugger), the Click
+ context from the ``flask run`` command remains available in the
+ loader thread. :issue:`4460`
+- Deleting the session cookie uses the ``httponly`` flag.
+ :issue:`4485`
+- Relax typing for ``errorhandler`` to allow the user to use more
+ precise types and decorate the same function multiple times.
+ :issue:`4095, 4295, 4297`
+- Fix typing for ``__exit__`` methods for better compatibility with
+ ``ExitStack``. :issue:`4474`
+- From Werkzeug, for redirect responses the ``Location`` header URL
+ will remain relative, and exclude the scheme and domain, by default.
+ :pr:`4496`
+- Add ``Config.from_prefixed_env()`` to load config values from
+ environment variables that start with ``FLASK_`` or another prefix.
+ This parses values as JSON by default, and allows setting keys in
+ nested dicts. :pr:`4479`
+
+
+Version 2.0.3
+-------------
+
+Released 2022-02-14
+
+- The test client's ``as_tuple`` parameter is deprecated and will be
+ removed in Werkzeug 2.1. It is now also deprecated in Flask, to be
+ removed in Flask 2.1, while remaining compatible with both in
+ 2.0.x. Use ``response.request.environ`` instead. :pr:`4341`
+- Fix type annotation for ``errorhandler`` decorator. :issue:`4295`
+- Revert a change to the CLI that caused it to hide ``ImportError``
+ tracebacks when importing the application. :issue:`4307`
+- ``app.json_encoder`` and ``json_decoder`` are only passed to
+ ``dumps`` and ``loads`` if they have custom behavior. This improves
+ performance, mainly on PyPy. :issue:`4349`
+- Clearer error message when ``after_this_request`` is used outside a
+ request context. :issue:`4333`
+
+
+Version 2.0.2
+-------------
+
+Released 2021-10-04
+
+- Fix type annotation for ``teardown_*`` methods. :issue:`4093`
+- Fix type annotation for ``before_request`` and ``before_app_request``
+ decorators. :issue:`4104`
+- Fixed the issue where typing requires template global
+ decorators to accept functions with no arguments. :issue:`4098`
+- Support View and MethodView instances with async handlers. :issue:`4112`
+- Enhance typing of ``app.errorhandler`` decorator. :issue:`4095`
+- Fix registering a blueprint twice with differing names. :issue:`4124`
+- Fix the type of ``static_folder`` to accept ``pathlib.Path``.
+ :issue:`4150`
+- ``jsonify`` handles ``decimal.Decimal`` by encoding to ``str``.
+ :issue:`4157`
+- Correctly handle raising deferred errors in CLI lazy loading.
+ :issue:`4096`
+- The CLI loader handles ``**kwargs`` in a ``create_app`` function.
+ :issue:`4170`
+- Fix the order of ``before_request`` and other callbacks that trigger
+ before the view returns. They are called from the app down to the
+ closest nested blueprint. :issue:`4229`
+
+
+Version 2.0.1
+-------------
+
+Released 2021-05-21
+
+- Re-add the ``filename`` parameter in ``send_from_directory``. The
+ ``filename`` parameter has been renamed to ``path``, the old name
+ is deprecated. :pr:`4019`
+- Mark top-level names as exported so type checking understands
+ imports in user projects. :issue:`4024`
+- Fix type annotation for ``g`` and inform mypy that it is a namespace
+ object that has arbitrary attributes. :issue:`4020`
+- Fix some types that weren't available in Python 3.6.0. :issue:`4040`
+- Improve typing for ``send_file``, ``send_from_directory``, and
+ ``get_send_file_max_age``. :issue:`4044`, :pr:`4026`
+- Show an error when a blueprint name contains a dot. The ``.`` has
+ special meaning, it is used to separate (nested) blueprint names and
+ the endpoint name. :issue:`4041`
+- Combine URL prefixes when nesting blueprints that were created with
+ a ``url_prefix`` value. :issue:`4037`
+- Revert a change to the order that URL matching was done. The
+ URL is again matched after the session is loaded, so the session is
+ available in custom URL converters. :issue:`4053`
+- Re-add deprecated ``Config.from_json``, which was accidentally
+ removed early. :issue:`4078`
+- Improve typing for some functions using ``Callable`` in their type
+ signatures, focusing on decorator factories. :issue:`4060`
+- Nested blueprints are registered with their dotted name. This allows
+ different blueprints with the same name to be nested at different
+ locations. :issue:`4069`
+- ``register_blueprint`` takes a ``name`` option to change the
+ (pre-dotted) name the blueprint is registered with. This allows the
+ same blueprint to be registered multiple times with unique names for
+ ``url_for``. Registering the same blueprint with the same name
+ multiple times is deprecated. :issue:`1091`
+- Improve typing for ``stream_with_context``. :issue:`4052`
+
+
+Version 2.0.0
+-------------
+
+Released 2021-05-11
+
+- Drop support for Python 2 and 3.5.
+- Bump minimum versions of other Pallets projects: Werkzeug >= 2,
+ Jinja2 >= 3, MarkupSafe >= 2, ItsDangerous >= 2, Click >= 8. Be sure
+ to check the change logs for each project. For better compatibility
+ with other applications (e.g. Celery) that still require Click 7,
+ there is no hard dependency on Click 8 yet, but using Click 7 will
+ trigger a DeprecationWarning and Flask 2.1 will depend on Click 8.
+- JSON support no longer uses simplejson. To use another JSON module,
+ override ``app.json_encoder`` and ``json_decoder``. :issue:`3555`
+- The ``encoding`` option to JSON functions is deprecated. :pr:`3562`
+- Passing ``script_info`` to app factory functions is deprecated. This
+ was not portable outside the ``flask`` command. Use
+ ``click.get_current_context().obj`` if it's needed. :issue:`3552`
+- The CLI shows better error messages when the app failed to load
+ when looking up commands. :issue:`2741`
+- Add ``SessionInterface.get_cookie_name`` to allow setting the
+ session cookie name dynamically. :pr:`3369`
+- Add ``Config.from_file`` to load config using arbitrary file
+ loaders, such as ``toml.load`` or ``json.load``.
+ ``Config.from_json`` is deprecated in favor of this. :pr:`3398`
+- The ``flask run`` command will only defer errors on reload. Errors
+ present during the initial call will cause the server to exit with
+ the traceback immediately. :issue:`3431`
+- ``send_file`` raises a ``ValueError`` when passed an ``io`` object
+ in text mode. Previously, it would respond with 200 OK and an empty
+ file. :issue:`3358`
+- When using ad-hoc certificates, check for the cryptography library
+ instead of PyOpenSSL. :pr:`3492`
+- When specifying a factory function with ``FLASK_APP``, keyword
+ argument can be passed. :issue:`3553`
+- When loading a ``.env`` or ``.flaskenv`` file, the current working
+ directory is no longer changed to the location of the file.
+ :pr:`3560`
+- When returning a ``(response, headers)`` tuple from a view, the
+ headers replace rather than extend existing headers on the response.
+ For example, this allows setting the ``Content-Type`` for
+ ``jsonify()``. Use ``response.headers.extend()`` if extending is
+ desired. :issue:`3628`
+- The ``Scaffold`` class provides a common API for the ``Flask`` and
+ ``Blueprint`` classes. ``Blueprint`` information is stored in
+ attributes just like ``Flask``, rather than opaque lambda functions.
+ This is intended to improve consistency and maintainability.
+ :issue:`3215`
+- Include ``samesite`` and ``secure`` options when removing the
+ session cookie. :pr:`3726`
+- Support passing a ``pathlib.Path`` to ``static_folder``. :pr:`3579`
+- ``send_file`` and ``send_from_directory`` are wrappers around the
+ implementations in ``werkzeug.utils``. :pr:`3828`
+- Some ``send_file`` parameters have been renamed, the old names are
+ deprecated. ``attachment_filename`` is renamed to ``download_name``.
+ ``cache_timeout`` is renamed to ``max_age``. ``add_etags`` is
+ renamed to ``etag``. :pr:`3828, 3883`
+- ``send_file`` passes ``download_name`` even if
+ ``as_attachment=False`` by using ``Content-Disposition: inline``.
+ :pr:`3828`
+- ``send_file`` sets ``conditional=True`` and ``max_age=None`` by
+ default. ``Cache-Control`` is set to ``no-cache`` if ``max_age`` is
+ not set, otherwise ``public``. This tells browsers to validate
+ conditional requests instead of using a timed cache. :pr:`3828`
+- ``helpers.safe_join`` is deprecated. Use
+ ``werkzeug.utils.safe_join`` instead. :pr:`3828`
+- The request context does route matching before opening the session.
+ This could allow a session interface to change behavior based on
+ ``request.endpoint``. :issue:`3776`
+- Use Jinja's implementation of the ``|tojson`` filter. :issue:`3881`
+- Add route decorators for common HTTP methods. For example,
+ ``@app.post("/login")`` is a shortcut for
+ ``@app.route("/login", methods=["POST"])``. :pr:`3907`
+- Support async views, error handlers, before and after request, and
+ teardown functions. :pr:`3412`
+- Support nesting blueprints. :issue:`593, 1548`, :pr:`3923`
+- Set the default encoding to "UTF-8" when loading ``.env`` and
+ ``.flaskenv`` files to allow to use non-ASCII characters. :issue:`3931`
+- ``flask shell`` sets up tab and history completion like the default
+ ``python`` shell if ``readline`` is installed. :issue:`3941`
+- ``helpers.total_seconds()`` is deprecated. Use
+ ``timedelta.total_seconds()`` instead. :pr:`3962`
+- Add type hinting. :pr:`3973`.
+
+
+Version 1.1.4
+-------------
+
+Released 2021-05-13
+
+- Update ``static_folder`` to use ``_compat.fspath`` instead of
+ ``os.fspath`` to continue supporting Python < 3.6 :issue:`4050`
+
+
+Version 1.1.3
+-------------
+
+Released 2021-05-13
+
+- Set maximum versions of Werkzeug, Jinja, Click, and ItsDangerous.
+ :issue:`4043`
+- Re-add support for passing a ``pathlib.Path`` for ``static_folder``.
+ :pr:`3579`
+
+
+Version 1.1.2
+-------------
+
+Released 2020-04-03
+
+- Work around an issue when running the ``flask`` command with an
+ external debugger on Windows. :issue:`3297`
+- The static route will not catch all URLs if the ``Flask``
+ ``static_folder`` argument ends with a slash. :issue:`3452`
+
+
+Version 1.1.1
+-------------
+
+Released 2019-07-08
+
+- The ``flask.json_available`` flag was added back for compatibility
+ with some extensions. It will raise a deprecation warning when used,
+ and will be removed in version 2.0.0. :issue:`3288`
+
+
+Version 1.1.0
+-------------
+
+Released 2019-07-04
+
+- Bump minimum Werkzeug version to >= 0.15.
+- Drop support for Python 3.4.
+- Error handlers for ``InternalServerError`` or ``500`` will always be
+ passed an instance of ``InternalServerError``. If they are invoked
+ due to an unhandled exception, that original exception is now
+ available as ``e.original_exception`` rather than being passed
+ directly to the handler. The same is true if the handler is for the
+ base ``HTTPException``. This makes error handler behavior more
+ consistent. :pr:`3266`
+
+ - ``Flask.finalize_request`` is called for all unhandled
+ exceptions even if there is no ``500`` error handler.
+
+- ``Flask.logger`` takes the same name as ``Flask.name`` (the value
+ passed as ``Flask(import_name)``. This reverts 1.0's behavior of
+ always logging to ``"flask.app"``, in order to support multiple apps
+ in the same process. A warning will be shown if old configuration is
+ detected that needs to be moved. :issue:`2866`
+- ``RequestContext.copy`` includes the current session object in the
+ request context copy. This prevents ``session`` pointing to an
+ out-of-date object. :issue:`2935`
+- Using built-in RequestContext, unprintable Unicode characters in
+ Host header will result in a HTTP 400 response and not HTTP 500 as
+ previously. :pr:`2994`
+- ``send_file`` supports ``PathLike`` objects as described in
+ :pep:`519`, to support ``pathlib`` in Python 3. :pr:`3059`
+- ``send_file`` supports ``BytesIO`` partial content.
+ :issue:`2957`
+- ``open_resource`` accepts the "rt" file mode. This still does the
+ same thing as "r". :issue:`3163`
+- The ``MethodView.methods`` attribute set in a base class is used by
+ subclasses. :issue:`3138`
+- ``Flask.jinja_options`` is a ``dict`` instead of an
+ ``ImmutableDict`` to allow easier configuration. Changes must still
+ be made before creating the environment. :pr:`3190`
+- Flask's ``JSONMixin`` for the request and response wrappers was
+ moved into Werkzeug. Use Werkzeug's version with Flask-specific
+ support. This bumps the Werkzeug dependency to >= 0.15.
+ :issue:`3125`
+- The ``flask`` command entry point is simplified to take advantage
+ of Werkzeug 0.15's better reloader support. This bumps the Werkzeug
+ dependency to >= 0.15. :issue:`3022`
+- Support ``static_url_path`` that ends with a forward slash.
+ :issue:`3134`
+- Support empty ``static_folder`` without requiring setting an empty
+ ``static_url_path`` as well. :pr:`3124`
+- ``jsonify`` supports ``dataclass`` objects. :pr:`3195`
+- Allow customizing the ``Flask.url_map_class`` used for routing.
+ :pr:`3069`
+- The development server port can be set to 0, which tells the OS to
+ pick an available port. :issue:`2926`
+- The return value from ``cli.load_dotenv`` is more consistent with
+ the documentation. It will return ``False`` if python-dotenv is not
+ installed, or if the given path isn't a file. :issue:`2937`
+- Signaling support has a stub for the ``connect_via`` method when
+ the Blinker library is not installed. :pr:`3208`
+- Add an ``--extra-files`` option to the ``flask run`` CLI command to
+ specify extra files that will trigger the reloader on change.
+ :issue:`2897`
+- Allow returning a dictionary from a view function. Similar to how
+ returning a string will produce a ``text/html`` response, returning
+ a dict will call ``jsonify`` to produce a ``application/json``
+ response. :pr:`3111`
+- Blueprints have a ``cli`` Click group like ``app.cli``. CLI commands
+ registered with a blueprint will be available as a group under the
+ ``flask`` command. :issue:`1357`.
+- When using the test client as a context manager (``with client:``),
+ all preserved request contexts are popped when the block exits,
+ ensuring nested contexts are cleaned up correctly. :pr:`3157`
+- Show a better error message when the view return type is not
+ supported. :issue:`3214`
+- ``flask.testing.make_test_environ_builder()`` has been deprecated in
+ favour of a new class ``flask.testing.EnvironBuilder``. :pr:`3232`
+- The ``flask run`` command no longer fails if Python is not built
+ with SSL support. Using the ``--cert`` option will show an
+ appropriate error message. :issue:`3211`
+- URL matching now occurs after the request context is pushed, rather
+ than when it's created. This allows custom URL converters to access
+ the app and request contexts, such as to query a database for an id.
+ :issue:`3088`
+
+
+Version 1.0.4
+-------------
+
+Released 2019-07-04
+
+- The key information for ``BadRequestKeyError`` is no longer cleared
+ outside debug mode, so error handlers can still access it. This
+ requires upgrading to Werkzeug 0.15.5. :issue:`3249`
+- ``send_file`` url quotes the ":" and "/" characters for more
+ compatible UTF-8 filename support in some browsers. :issue:`3074`
+- Fixes for :pep:`451` import loaders and pytest 5.x. :issue:`3275`
+- Show message about dotenv on stderr instead of stdout. :issue:`3285`
+
+
+Version 1.0.3
+-------------
+
+Released 2019-05-17
+
+- ``send_file`` encodes filenames as ASCII instead of Latin-1
+ (ISO-8859-1). This fixes compatibility with Gunicorn, which is
+ stricter about header encodings than :pep:`3333`. :issue:`2766`
+- Allow custom CLIs using ``FlaskGroup`` to set the debug flag without
+ it always being overwritten based on environment variables.
+ :pr:`2765`
+- ``flask --version`` outputs Werkzeug's version and simplifies the
+ Python version. :pr:`2825`
+- ``send_file`` handles an ``attachment_filename`` that is a native
+ Python 2 string (bytes) with UTF-8 coded bytes. :issue:`2933`
+- A catch-all error handler registered for ``HTTPException`` will not
+ handle ``RoutingException``, which is used internally during
+ routing. This fixes the unexpected behavior that had been introduced
+ in 1.0. :pr:`2986`
+- Passing the ``json`` argument to ``app.test_client`` does not
+ push/pop an extra app context. :issue:`2900`
+
+
+Version 1.0.2
+-------------
+
+Released 2018-05-02
+
+- Fix more backwards compatibility issues with merging slashes between
+ a blueprint prefix and route. :pr:`2748`
+- Fix error with ``flask routes`` command when there are no routes.
+ :issue:`2751`
+
+
+Version 1.0.1
+-------------
+
+Released 2018-04-29
+
+- Fix registering partials (with no ``__name__``) as view functions.
+ :pr:`2730`
+- Don't treat lists returned from view functions the same as tuples.
+ Only tuples are interpreted as response data. :issue:`2736`
+- Extra slashes between a blueprint's ``url_prefix`` and a route URL
+ are merged. This fixes some backwards compatibility issues with the
+ change in 1.0. :issue:`2731`, :issue:`2742`
+- Only trap ``BadRequestKeyError`` errors in debug mode, not all
+ ``BadRequest`` errors. This allows ``abort(400)`` to continue
+ working as expected. :issue:`2735`
+- The ``FLASK_SKIP_DOTENV`` environment variable can be set to ``1``
+ to skip automatically loading dotenv files. :issue:`2722`
+
+
+Version 1.0
+-----------
+
+Released 2018-04-26
+
+- Python 2.6 and 3.3 are no longer supported.
+- Bump minimum dependency versions to the latest stable versions:
+ Werkzeug >= 0.14, Jinja >= 2.10, itsdangerous >= 0.24, Click >= 5.1.
+ :issue:`2586`
+- Skip ``app.run`` when a Flask application is run from the command
+ line. This avoids some behavior that was confusing to debug.
+- Change the default for ``JSONIFY_PRETTYPRINT_REGULAR`` to
+ ``False``. ``~json.jsonify`` returns a compact format by default,
+ and an indented format in debug mode. :pr:`2193`
+- ``Flask.__init__`` accepts the ``host_matching`` argument and sets
+ it on ``Flask.url_map``. :issue:`1559`
+- ``Flask.__init__`` accepts the ``static_host`` argument and passes
+ it as the ``host`` argument when defining the static route.
+ :issue:`1559`
+- ``send_file`` supports Unicode in ``attachment_filename``.
+ :pr:`2223`
+- Pass ``_scheme`` argument from ``url_for`` to
+ ``Flask.handle_url_build_error``. :pr:`2017`
+- ``Flask.add_url_rule`` accepts the ``provide_automatic_options``
+ argument to disable adding the ``OPTIONS`` method. :pr:`1489`
+- ``MethodView`` subclasses inherit method handlers from base classes.
+ :pr:`1936`
+- Errors caused while opening the session at the beginning of the
+ request are handled by the app's error handlers. :pr:`2254`
+- Blueprints gained ``Blueprint.json_encoder`` and
+ ``Blueprint.json_decoder`` attributes to override the app's
+ encoder and decoder. :pr:`1898`
+- ``Flask.make_response`` raises ``TypeError`` instead of
+ ``ValueError`` for bad response types. The error messages have been
+ improved to describe why the type is invalid. :pr:`2256`
+- Add ``routes`` CLI command to output routes registered on the
+ application. :pr:`2259`
+- Show warning when session cookie domain is a bare hostname or an IP
+ address, as these may not behave properly in some browsers, such as
+ Chrome. :pr:`2282`
+- Allow IP address as exact session cookie domain. :pr:`2282`
+- ``SESSION_COOKIE_DOMAIN`` is set if it is detected through
+ ``SERVER_NAME``. :pr:`2282`
+- Auto-detect zero-argument app factory called ``create_app`` or
+ ``make_app`` from ``FLASK_APP``. :pr:`2297`
+- Factory functions are not required to take a ``script_info``
+ parameter to work with the ``flask`` command. If they take a single
+ parameter or a parameter named ``script_info``, the ``ScriptInfo``
+ object will be passed. :pr:`2319`
+- ``FLASK_APP`` can be set to an app factory, with arguments if
+ needed, for example ``FLASK_APP=myproject.app:create_app('dev')``.
+ :pr:`2326`
+- ``FLASK_APP`` can point to local packages that are not installed in
+ editable mode, although ``pip install -e`` is still preferred.
+ :pr:`2414`
+- The ``View`` class attribute
+ ``View.provide_automatic_options`` is set in ``View.as_view``, to be
+ detected by ``Flask.add_url_rule``. :pr:`2316`
+- Error handling will try handlers registered for ``blueprint, code``,
+ ``app, code``, ``blueprint, exception``, ``app, exception``.
+ :pr:`2314`
+- ``Cookie`` is added to the response's ``Vary`` header if the session
+ is accessed at all during the request (and not deleted). :pr:`2288`
+- ``Flask.test_request_context`` accepts ``subdomain`` and
+ ``url_scheme`` arguments for use when building the base URL.
+ :pr:`1621`
+- Set ``APPLICATION_ROOT`` to ``'/'`` by default. This was already the
+ implicit default when it was set to ``None``.
+- ``TRAP_BAD_REQUEST_ERRORS`` is enabled by default in debug mode.
+ ``BadRequestKeyError`` has a message with the bad key in debug mode
+ instead of the generic bad request message. :pr:`2348`
+- Allow registering new tags with ``TaggedJSONSerializer`` to support
+ storing other types in the session cookie. :pr:`2352`
+- Only open the session if the request has not been pushed onto the
+ context stack yet. This allows ``stream_with_context`` generators to
+ access the same session that the containing view uses. :pr:`2354`
+- Add ``json`` keyword argument for the test client request methods.
+ This will dump the given object as JSON and set the appropriate
+ content type. :pr:`2358`
+- Extract JSON handling to a mixin applied to both the ``Request`` and
+ ``Response`` classes. This adds the ``Response.is_json`` and
+ ``Response.get_json`` methods to the response to make testing JSON
+ response much easier. :pr:`2358`
+- Removed error handler caching because it caused unexpected results
+ for some exception inheritance hierarchies. Register handlers
+ explicitly for each exception if you want to avoid traversing the
+ MRO. :pr:`2362`
+- Fix incorrect JSON encoding of aware, non-UTC datetimes. :pr:`2374`
+- Template auto reloading will honor debug mode even if
+ ``Flask.jinja_env`` was already accessed. :pr:`2373`
+- The following old deprecated code was removed. :issue:`2385`
+
+ - ``flask.ext`` - import extensions directly by their name instead
+ of through the ``flask.ext`` namespace. For example,
+ ``import flask.ext.sqlalchemy`` becomes
+ ``import flask_sqlalchemy``.
+ - ``Flask.init_jinja_globals`` - extend
+ ``Flask.create_jinja_environment`` instead.
+ - ``Flask.error_handlers`` - tracked by
+ ``Flask.error_handler_spec``, use ``Flask.errorhandler``
+ to register handlers.
+ - ``Flask.request_globals_class`` - use
+ ``Flask.app_ctx_globals_class`` instead.
+ - ``Flask.static_path`` - use ``Flask.static_url_path`` instead.
+ - ``Request.module`` - use ``Request.blueprint`` instead.
+
+- The ``Request.json`` property is no longer deprecated. :issue:`1421`
+- Support passing a ``EnvironBuilder`` or ``dict`` to
+ ``test_client.open``. :pr:`2412`
+- The ``flask`` command and ``Flask.run`` will load environment
+ variables from ``.env`` and ``.flaskenv`` files if python-dotenv is
+ installed. :pr:`2416`
+- When passing a full URL to the test client, the scheme in the URL is
+ used instead of ``PREFERRED_URL_SCHEME``. :pr:`2430`
+- ``Flask.logger`` has been simplified. ``LOGGER_NAME`` and
+ ``LOGGER_HANDLER_POLICY`` config was removed. The logger is always
+ named ``flask.app``. The level is only set on first access, it
+ doesn't check ``Flask.debug`` each time. Only one format is used,
+ not different ones depending on ``Flask.debug``. No handlers are
+ removed, and a handler is only added if no handlers are already
+ configured. :pr:`2436`
+- Blueprint view function names may not contain dots. :pr:`2450`
+- Fix a ``ValueError`` caused by invalid ``Range`` requests in some
+ cases. :issue:`2526`
+- The development server uses threads by default. :pr:`2529`
+- Loading config files with ``silent=True`` will ignore ``ENOTDIR``
+ errors. :pr:`2581`
+- Pass ``--cert`` and ``--key`` options to ``flask run`` to run the
+ development server over HTTPS. :pr:`2606`
+- Added ``SESSION_COOKIE_SAMESITE`` to control the ``SameSite``
+ attribute on the session cookie. :pr:`2607`
+- Added ``Flask.test_cli_runner`` to create a Click runner that can
+ invoke Flask CLI commands for testing. :pr:`2636`
+- Subdomain matching is disabled by default and setting
+ ``SERVER_NAME`` does not implicitly enable it. It can be enabled by
+ passing ``subdomain_matching=True`` to the ``Flask`` constructor.
+ :pr:`2635`
+- A single trailing slash is stripped from the blueprint
+ ``url_prefix`` when it is registered with the app. :pr:`2629`
+- ``Request.get_json`` doesn't cache the result if parsing fails when
+ ``silent`` is true. :issue:`2651`
+- ``Request.get_json`` no longer accepts arbitrary encodings. Incoming
+ JSON should be encoded using UTF-8 per :rfc:`8259`, but Flask will
+ autodetect UTF-8, -16, or -32. :pr:`2691`
+- Added ``MAX_COOKIE_SIZE`` and ``Response.max_cookie_size`` to
+ control when Werkzeug warns about large cookies that browsers may
+ ignore. :pr:`2693`
+- Updated documentation theme to make docs look better in small
+ windows. :pr:`2709`
+- Rewrote the tutorial docs and example project to take a more
+ structured approach to help new users avoid common pitfalls.
+ :pr:`2676`
+
+
+Version 0.12.5
+--------------
+
+Released 2020-02-10
+
+- Pin Werkzeug to < 1.0.0. :issue:`3497`
+
+
+Version 0.12.4
+--------------
+
+Released 2018-04-29
+
+- Repackage 0.12.3 to fix package layout issue. :issue:`2728`
+
+
+Version 0.12.3
+--------------
+
+Released 2018-04-26
+
+- ``Request.get_json`` no longer accepts arbitrary encodings.
+ Incoming JSON should be encoded using UTF-8 per :rfc:`8259`, but
+ Flask will autodetect UTF-8, -16, or -32. :issue:`2692`
+- Fix a Python warning about imports when using ``python -m flask``.
+ :issue:`2666`
+- Fix a ``ValueError`` caused by invalid ``Range`` requests in some
+ cases.
+
+
+Version 0.12.2
+--------------
+
+Released 2017-05-16
+
+- Fix a bug in ``safe_join`` on Windows.
+
+
+Version 0.12.1
+--------------
+
+Released 2017-03-31
+
+- Prevent ``flask run`` from showing a ``NoAppException`` when an
+ ``ImportError`` occurs within the imported application module.
+- Fix encoding behavior of ``app.config.from_pyfile`` for Python 3.
+ :issue:`2118`
+- Use the ``SERVER_NAME`` config if it is present as default values
+ for ``app.run``. :issue:`2109`, :pr:`2152`
+- Call ``ctx.auto_pop`` with the exception object instead of ``None``,
+ in the event that a ``BaseException`` such as ``KeyboardInterrupt``
+ is raised in a request handler.
+
+
+Version 0.12
+------------
+
+Released 2016-12-21, codename Punsch
+
+- The cli command now responds to ``--version``.
+- Mimetype guessing and ETag generation for file-like objects in
+ ``send_file`` has been removed. :issue:`104`, :pr`1849`
+- Mimetype guessing in ``send_file`` now fails loudly and doesn't fall
+ back to ``application/octet-stream``. :pr:`1988`
+- Make ``flask.safe_join`` able to join multiple paths like
+ ``os.path.join`` :pr:`1730`
+- Revert a behavior change that made the dev server crash instead of
+ returning an Internal Server Error. :pr:`2006`
+- Correctly invoke response handlers for both regular request
+ dispatching as well as error handlers.
+- Disable logger propagation by default for the app logger.
+- Add support for range requests in ``send_file``.
+- ``app.test_client`` includes preset default environment, which can
+ now be directly set, instead of per ``client.get``.
+- Fix crash when running under PyPy3. :pr:`1814`
+
+
+Version 0.11.1
+--------------
+
+Released 2016-06-07
+
+- Fixed a bug that prevented ``FLASK_APP=foobar/__init__.py`` from
+ working. :pr:`1872`
+
+
+Version 0.11
+------------
+
+Released 2016-05-29, codename Absinthe
+
+- Added support to serializing top-level arrays to ``jsonify``. This
+ introduces a security risk in ancient browsers.
+- Added before_render_template signal.
+- Added ``**kwargs`` to ``Flask.test_client`` to support passing
+ additional keyword arguments to the constructor of
+ ``Flask.test_client_class``.
+- Added ``SESSION_REFRESH_EACH_REQUEST`` config key that controls the
+ set-cookie behavior. If set to ``True`` a permanent session will be
+ refreshed each request and get their lifetime extended, if set to
+ ``False`` it will only be modified if the session actually modifies.
+ Non permanent sessions are not affected by this and will always
+ expire if the browser window closes.
+- Made Flask support custom JSON mimetypes for incoming data.
+- Added support for returning tuples in the form ``(response,
+ headers)`` from a view function.
+- Added ``Config.from_json``.
+- Added ``Flask.config_class``.
+- Added ``Config.get_namespace``.
+- Templates are no longer automatically reloaded outside of debug
+ mode. This can be configured with the new ``TEMPLATES_AUTO_RELOAD``
+ config key.
+- Added a workaround for a limitation in Python 3.3's namespace
+ loader.
+- Added support for explicit root paths when using Python 3.3's
+ namespace packages.
+- Added ``flask`` and the ``flask.cli`` module to start the
+ local debug server through the click CLI system. This is recommended
+ over the old ``flask.run()`` method as it works faster and more
+ reliable due to a different design and also replaces
+ ``Flask-Script``.
+- Error handlers that match specific classes are now checked first,
+ thereby allowing catching exceptions that are subclasses of HTTP
+ exceptions (in ``werkzeug.exceptions``). This makes it possible for
+ an extension author to create exceptions that will by default result
+ in the HTTP error of their choosing, but may be caught with a custom
+ error handler if desired.
+- Added ``Config.from_mapping``.
+- Flask will now log by default even if debug is disabled. The log
+ format is now hardcoded but the default log handling can be disabled
+ through the ``LOGGER_HANDLER_POLICY`` configuration key.
+- Removed deprecated module functionality.
+- Added the ``EXPLAIN_TEMPLATE_LOADING`` config flag which when
+ enabled will instruct Flask to explain how it locates templates.
+ This should help users debug when the wrong templates are loaded.
+- Enforce blueprint handling in the order they were registered for
+ template loading.
+- Ported test suite to py.test.
+- Deprecated ``request.json`` in favour of ``request.get_json()``.
+- Add "pretty" and "compressed" separators definitions in jsonify()
+ method. Reduces JSON response size when
+ ``JSONIFY_PRETTYPRINT_REGULAR=False`` by removing unnecessary white
+ space included by default after separators.
+- JSON responses are now terminated with a newline character, because
+ it is a convention that UNIX text files end with a newline and some
+ clients don't deal well when this newline is missing. :pr:`1262`
+- The automatically provided ``OPTIONS`` method is now correctly
+ disabled if the user registered an overriding rule with the
+ lowercase-version ``options``. :issue:`1288`
+- ``flask.json.jsonify`` now supports the ``datetime.date`` type.
+ :pr:`1326`
+- Don't leak exception info of already caught exceptions to context
+ teardown handlers. :pr:`1393`
+- Allow custom Jinja environment subclasses. :pr:`1422`
+- Updated extension dev guidelines.
+- ``flask.g`` now has ``pop()`` and ``setdefault`` methods.
+- Turn on autoescape for ``flask.templating.render_template_string``
+ by default. :pr:`1515`
+- ``flask.ext`` is now deprecated. :pr:`1484`
+- ``send_from_directory`` now raises BadRequest if the filename is
+ invalid on the server OS. :pr:`1763`
+- Added the ``JSONIFY_MIMETYPE`` configuration variable. :pr:`1728`
+- Exceptions during teardown handling will no longer leave bad
+ application contexts lingering around.
+- Fixed broken ``test_appcontext_signals()`` test case.
+- Raise an ``AttributeError`` in ``helpers.find_package`` with a
+ useful message explaining why it is raised when a :pep:`302` import
+ hook is used without an ``is_package()`` method.
+- Fixed an issue causing exceptions raised before entering a request
+ or app context to be passed to teardown handlers.
+- Fixed an issue with query parameters getting removed from requests
+ in the test client when absolute URLs were requested.
+- Made ``@before_first_request`` into a decorator as intended.
+- Fixed an etags bug when sending a file streams with a name.
+- Fixed ``send_from_directory`` not expanding to the application root
+ path correctly.
+- Changed logic of before first request handlers to flip the flag
+ after invoking. This will allow some uses that are potentially
+ dangerous but should probably be permitted.
+- Fixed Python 3 bug when a handler from
+ ``app.url_build_error_handlers`` reraises the ``BuildError``.
+
+
+Version 0.10.1
+--------------
+
+Released 2013-06-14
+
+- Fixed an issue where ``|tojson`` was not quoting single quotes which
+ made the filter not work properly in HTML attributes. Now it's
+ possible to use that filter in single quoted attributes. This should
+ make using that filter with angular.js easier.
+- Added support for byte strings back to the session system. This
+ broke compatibility with the common case of people putting binary
+ data for token verification into the session.
+- Fixed an issue where registering the same method twice for the same
+ endpoint would trigger an exception incorrectly.
+
+
+Version 0.10
+------------
+
+Released 2013-06-13, codename Limoncello
+
+- Changed default cookie serialization format from pickle to JSON to
+ limit the impact an attacker can do if the secret key leaks.
+- Added ``template_test`` methods in addition to the already existing
+ ``template_filter`` method family.
+- Added ``template_global`` methods in addition to the already
+ existing ``template_filter`` method family.
+- Set the content-length header for x-sendfile.
+- ``tojson`` filter now does not escape script blocks in HTML5
+ parsers.
+- ``tojson`` used in templates is now safe by default. This was
+ allowed due to the different escaping behavior.
+- Flask will now raise an error if you attempt to register a new
+ function on an already used endpoint.
+- Added wrapper module around simplejson and added default
+ serialization of datetime objects. This allows much easier
+ customization of how JSON is handled by Flask or any Flask
+ extension.
+- Removed deprecated internal ``flask.session`` module alias. Use
+ ``flask.sessions`` instead to get the session module. This is not to
+ be confused with ``flask.session`` the session proxy.
+- Templates can now be rendered without request context. The behavior
+ is slightly different as the ``request``, ``session`` and ``g``
+ objects will not be available and blueprint's context processors are
+ not called.
+- The config object is now available to the template as a real global
+ and not through a context processor which makes it available even in
+ imported templates by default.
+- Added an option to generate non-ascii encoded JSON which should
+ result in less bytes being transmitted over the network. It's
+ disabled by default to not cause confusion with existing libraries
+ that might expect ``flask.json.dumps`` to return bytes by default.
+- ``flask.g`` is now stored on the app context instead of the request
+ context.
+- ``flask.g`` now gained a ``get()`` method for not erroring out on
+ non existing items.
+- ``flask.g`` now can be used with the ``in`` operator to see what's
+ defined and it now is iterable and will yield all attributes stored.
+- ``flask.Flask.request_globals_class`` got renamed to
+ ``flask.Flask.app_ctx_globals_class`` which is a better name to what
+ it does since 0.10.
+- ``request``, ``session`` and ``g`` are now also added as proxies to
+ the template context which makes them available in imported
+ templates. One has to be very careful with those though because
+ usage outside of macros might cause caching.
+- Flask will no longer invoke the wrong error handlers if a proxy
+ exception is passed through.
+- Added a workaround for chrome's cookies in localhost not working as
+ intended with domain names.
+- Changed logic for picking defaults for cookie values from sessions
+ to work better with Google Chrome.
+- Added ``message_flashed`` signal that simplifies flashing testing.
+- Added support for copying of request contexts for better working
+ with greenlets.
+- Removed custom JSON HTTP exception subclasses. If you were relying
+ on them you can reintroduce them again yourself trivially. Using
+ them however is strongly discouraged as the interface was flawed.
+- Python requirements changed: requiring Python 2.6 or 2.7 now to
+ prepare for Python 3.3 port.
+- Changed how the teardown system is informed about exceptions. This
+ is now more reliable in case something handles an exception halfway
+ through the error handling process.
+- Request context preservation in debug mode now keeps the exception
+ information around which means that teardown handlers are able to
+ distinguish error from success cases.
+- Added the ``JSONIFY_PRETTYPRINT_REGULAR`` configuration variable.
+- Flask now orders JSON keys by default to not trash HTTP caches due
+ to different hash seeds between different workers.
+- Added ``appcontext_pushed`` and ``appcontext_popped`` signals.
+- The builtin run method now takes the ``SERVER_NAME`` into account
+ when picking the default port to run on.
+- Added ``flask.request.get_json()`` as a replacement for the old
+ ``flask.request.json`` property.
+
+
+Version 0.9
+-----------
+
+Released 2012-07-01, codename Campari
+
+- The ``Request.on_json_loading_failed`` now returns a JSON formatted
+ response by default.
+- The ``url_for`` function now can generate anchors to the generated
+ links.
+- The ``url_for`` function now can also explicitly generate URL rules
+ specific to a given HTTP method.
+- Logger now only returns the debug log setting if it was not set
+ explicitly.
+- Unregister a circular dependency between the WSGI environment and
+ the request object when shutting down the request. This means that
+ environ ``werkzeug.request`` will be ``None`` after the response was
+ returned to the WSGI server but has the advantage that the garbage
+ collector is not needed on CPython to tear down the request unless
+ the user created circular dependencies themselves.
+- Session is now stored after callbacks so that if the session payload
+ is stored in the session you can still modify it in an after request
+ callback.
+- The ``Flask`` class will avoid importing the provided import name if
+ it can (the required first parameter), to benefit tools which build
+ Flask instances programmatically. The Flask class will fall back to
+ using import on systems with custom module hooks, e.g. Google App
+ Engine, or when the import name is inside a zip archive (usually an
+ egg) prior to Python 2.7.
+- Blueprints now have a decorator to add custom template filters
+ application wide, ``Blueprint.app_template_filter``.
+- The Flask and Blueprint classes now have a non-decorator method for
+ adding custom template filters application wide,
+ ``Flask.add_template_filter`` and
+ ``Blueprint.add_app_template_filter``.
+- The ``get_flashed_messages`` function now allows rendering flashed
+ message categories in separate blocks, through a ``category_filter``
+ argument.
+- The ``Flask.run`` method now accepts ``None`` for ``host`` and
+ ``port`` arguments, using default values when ``None``. This allows
+ for calling run using configuration values, e.g.
+ ``app.run(app.config.get('MYHOST'), app.config.get('MYPORT'))``,
+ with proper behavior whether or not a config file is provided.
+- The ``render_template`` method now accepts a either an iterable of
+ template names or a single template name. Previously, it only
+ accepted a single template name. On an iterable, the first template
+ found is rendered.
+- Added ``Flask.app_context`` which works very similar to the request
+ context but only provides access to the current application. This
+ also adds support for URL generation without an active request
+ context.
+- View functions can now return a tuple with the first instance being
+ an instance of ``Response``. This allows for returning
+ ``jsonify(error="error msg"), 400`` from a view function.
+- ``Flask`` and ``Blueprint`` now provide a ``get_send_file_max_age``
+ hook for subclasses to override behavior of serving static files
+ from Flask when using ``Flask.send_static_file`` (used for the
+ default static file handler) and ``helpers.send_file``. This hook is
+ provided a filename, which for example allows changing cache
+ controls by file extension. The default max-age for ``send_file``
+ and static files can be configured through a new
+ ``SEND_FILE_MAX_AGE_DEFAULT`` configuration variable, which is used
+ in the default ``get_send_file_max_age`` implementation.
+- Fixed an assumption in sessions implementation which could break
+ message flashing on sessions implementations which use external
+ storage.
+- Changed the behavior of tuple return values from functions. They are
+ no longer arguments to the response object, they now have a defined
+ meaning.
+- Added ``Flask.request_globals_class`` to allow a specific class to
+ be used on creation of the ``g`` instance of each request.
+- Added ``required_methods`` attribute to view functions to force-add
+ methods on registration.
+- Added ``flask.after_this_request``.
+- Added ``flask.stream_with_context`` and the ability to push contexts
+ multiple times without producing unexpected behavior.
+
+
+Version 0.8.1
+-------------
+
+Released 2012-07-01
+
+- Fixed an issue with the undocumented ``flask.session`` module to not
+ work properly on Python 2.5. It should not be used but did cause
+ some problems for package managers.
+
+
+Version 0.8
+-----------
+
+Released 2011-09-29, codename Rakija
+
+- Refactored session support into a session interface so that the
+ implementation of the sessions can be changed without having to
+ override the Flask class.
+- Empty session cookies are now deleted properly automatically.
+- View functions can now opt out of getting the automatic OPTIONS
+ implementation.
+- HTTP exceptions and Bad Request errors can now be trapped so that
+ they show up normally in the traceback.
+- Flask in debug mode is now detecting some common problems and tries
+ to warn you about them.
+- Flask in debug mode will now complain with an assertion error if a
+ view was attached after the first request was handled. This gives
+ earlier feedback when users forget to import view code ahead of
+ time.
+- Added the ability to register callbacks that are only triggered once
+ at the beginning of the first request with
+ ``Flask.before_first_request``.
+- Malformed JSON data will now trigger a bad request HTTP exception
+ instead of a value error which usually would result in a 500
+ internal server error if not handled. This is a backwards
+ incompatible change.
+- Applications now not only have a root path where the resources and
+ modules are located but also an instance path which is the
+ designated place to drop files that are modified at runtime (uploads
+ etc.). Also this is conceptually only instance depending and outside
+ version control so it's the perfect place to put configuration files
+ etc.
+- Added the ``APPLICATION_ROOT`` configuration variable.
+- Implemented ``TestClient.session_transaction`` to easily modify
+ sessions from the test environment.
+- Refactored test client internally. The ``APPLICATION_ROOT``
+ configuration variable as well as ``SERVER_NAME`` are now properly
+ used by the test client as defaults.
+- Added ``View.decorators`` to support simpler decorating of pluggable
+ (class-based) views.
+- Fixed an issue where the test client if used with the "with"
+ statement did not trigger the execution of the teardown handlers.
+- Added finer control over the session cookie parameters.
+- HEAD requests to a method view now automatically dispatch to the
+ ``get`` method if no handler was implemented.
+- Implemented the virtual ``flask.ext`` package to import extensions
+ from.
+- The context preservation on exceptions is now an integral component
+ of Flask itself and no longer of the test client. This cleaned up
+ some internal logic and lowers the odds of runaway request contexts
+ in unittests.
+- Fixed the Jinja environment's ``list_templates`` method not
+ returning the correct names when blueprints or modules were
+ involved.
+
+
+Version 0.7.2
+-------------
+
+Released 2011-07-06
+
+- Fixed an issue with URL processors not properly working on
+ blueprints.
+
+
+Version 0.7.1
+-------------
+
+Released 2011-06-29
+
+- Added missing future import that broke 2.5 compatibility.
+- Fixed an infinite redirect issue with blueprints.
+
+
+Version 0.7
+-----------
+
+Released 2011-06-28, codename Grappa
+
+- Added ``Flask.make_default_options_response`` which can be used by
+ subclasses to alter the default behavior for ``OPTIONS`` responses.
+- Unbound locals now raise a proper ``RuntimeError`` instead of an
+ ``AttributeError``.
+- Mimetype guessing and etag support based on file objects is now
+ deprecated for ``send_file`` because it was unreliable. Pass
+ filenames instead or attach your own etags and provide a proper
+ mimetype by hand.
+- Static file handling for modules now requires the name of the static
+ folder to be supplied explicitly. The previous autodetection was not
+ reliable and caused issues on Google's App Engine. Until 1.0 the old
+ behavior will continue to work but issue dependency warnings.
+- Fixed a problem for Flask to run on jython.
+- Added a ``PROPAGATE_EXCEPTIONS`` configuration variable that can be
+ used to flip the setting of exception propagation which previously
+ was linked to ``DEBUG`` alone and is now linked to either ``DEBUG``
+ or ``TESTING``.
+- Flask no longer internally depends on rules being added through the
+ ``add_url_rule`` function and can now also accept regular werkzeug
+ rules added to the url map.
+- Added an ``endpoint`` method to the flask application object which
+ allows one to register a callback to an arbitrary endpoint with a
+ decorator.
+- Use Last-Modified for static file sending instead of Date which was
+ incorrectly introduced in 0.6.
+- Added ``create_jinja_loader`` to override the loader creation
+ process.
+- Implemented a silent flag for ``config.from_pyfile``.
+- Added ``teardown_request`` decorator, for functions that should run
+ at the end of a request regardless of whether an exception occurred.
+ Also the behavior for ``after_request`` was changed. It's now no
+ longer executed when an exception is raised.
+- Implemented ``has_request_context``.
+- Deprecated ``init_jinja_globals``. Override the
+ ``Flask.create_jinja_environment`` method instead to achieve the
+ same functionality.
+- Added ``safe_join``.
+- The automatic JSON request data unpacking now looks at the charset
+ mimetype parameter.
+- Don't modify the session on ``get_flashed_messages`` if there are no
+ messages in the session.
+- ``before_request`` handlers are now able to abort requests with
+ errors.
+- It is not possible to define user exception handlers. That way you
+ can provide custom error messages from a central hub for certain
+ errors that might occur during request processing (for instance
+ database connection errors, timeouts from remote resources etc.).
+- Blueprints can provide blueprint specific error handlers.
+- Implemented generic class-based views.
+
+
+Version 0.6.1
+-------------
+
+Released 2010-12-31
+
+- Fixed an issue where the default ``OPTIONS`` response was not
+ exposing all valid methods in the ``Allow`` header.
+- Jinja template loading syntax now allows "./" in front of a
+ template load path. Previously this caused issues with module
+ setups.
+- Fixed an issue where the subdomain setting for modules was ignored
+ for the static folder.
+- Fixed a security problem that allowed clients to download arbitrary
+ files if the host server was a windows based operating system and
+ the client uses backslashes to escape the directory the files where
+ exposed from.
+
+
+Version 0.6
+-----------
+
+Released 2010-07-27, codename Whisky
+
+- After request functions are now called in reverse order of
+ registration.
+- OPTIONS is now automatically implemented by Flask unless the
+ application explicitly adds 'OPTIONS' as method to the URL rule. In
+ this case no automatic OPTIONS handling kicks in.
+- Static rules are now even in place if there is no static folder for
+ the module. This was implemented to aid GAE which will remove the
+ static folder if it's part of a mapping in the .yml file.
+- ``Flask.config`` is now available in the templates as ``config``.
+- Context processors will no longer override values passed directly to
+ the render function.
+- Added the ability to limit the incoming request data with the new
+ ``MAX_CONTENT_LENGTH`` configuration value.
+- The endpoint for the ``Module.add_url_rule`` method is now optional
+ to be consistent with the function of the same name on the
+ application object.
+- Added a ``make_response`` function that simplifies creating response
+ object instances in views.
+- Added signalling support based on blinker. This feature is currently
+ optional and supposed to be used by extensions and applications. If
+ you want to use it, make sure to have ``blinker`` installed.
+- Refactored the way URL adapters are created. This process is now
+ fully customizable with the ``Flask.create_url_adapter`` method.
+- Modules can now register for a subdomain instead of just an URL
+ prefix. This makes it possible to bind a whole module to a
+ configurable subdomain.
+
+
+Version 0.5.2
+-------------
+
+Released 2010-07-15
+
+- Fixed another issue with loading templates from directories when
+ modules were used.
+
+
+Version 0.5.1
+-------------
+
+Released 2010-07-06
+
+- Fixes an issue with template loading from directories when modules
+ where used.
+
+
+Version 0.5
+-----------
+
+Released 2010-07-06, codename Calvados
+
+- Fixed a bug with subdomains that was caused by the inability to
+ specify the server name. The server name can now be set with the
+ ``SERVER_NAME`` config key. This key is now also used to set the
+ session cookie cross-subdomain wide.
+- Autoescaping is no longer active for all templates. Instead it is
+ only active for ``.html``, ``.htm``, ``.xml`` and ``.xhtml``. Inside
+ templates this behavior can be changed with the ``autoescape`` tag.
+- Refactored Flask internally. It now consists of more than a single
+ file.
+- ``send_file`` now emits etags and has the ability to do conditional
+ responses builtin.
+- (temporarily) dropped support for zipped applications. This was a
+ rarely used feature and led to some confusing behavior.
+- Added support for per-package template and static-file directories.
+- Removed support for ``create_jinja_loader`` which is no longer used
+ in 0.5 due to the improved module support.
+- Added a helper function to expose files from any directory.
+
+
+Version 0.4
+-----------
+
+Released 2010-06-18, codename Rakia
+
+- Added the ability to register application wide error handlers from
+ modules.
+- ``Flask.after_request`` handlers are now also invoked if the request
+ dies with an exception and an error handling page kicks in.
+- Test client has not the ability to preserve the request context for
+ a little longer. This can also be used to trigger custom requests
+ that do not pop the request stack for testing.
+- Because the Python standard library caches loggers, the name of the
+ logger is configurable now to better support unittests.
+- Added ``TESTING`` switch that can activate unittesting helpers.
+- The logger switches to ``DEBUG`` mode now if debug is enabled.
+
+
+Version 0.3.1
+-------------
+
+Released 2010-05-28
+
+- Fixed a error reporting bug with ``Config.from_envvar``.
+- Removed some unused code.
+- Release does no longer include development leftover files (.git
+ folder for themes, built documentation in zip and pdf file and some
+ .pyc files)
+
+
+Version 0.3
+-----------
+
+Released 2010-05-28, codename Schnaps
+
+- Added support for categories for flashed messages.
+- The application now configures a ``logging.Handler`` and will log
+ request handling exceptions to that logger when not in debug mode.
+ This makes it possible to receive mails on server errors for
+ example.
+- Added support for context binding that does not require the use of
+ the with statement for playing in the console.
+- The request context is now available within the with statement
+ making it possible to further push the request context or pop it.
+- Added support for configurations.
+
+
+Version 0.2
+-----------
+
+Released 2010-05-12, codename J?germeister
+
+- Various bugfixes
+- Integrated JSON support
+- Added ``get_template_attribute`` helper function.
+- ``Flask.add_url_rule`` can now also register a view function.
+- Refactored internal request dispatching.
+- Server listens on 127.0.0.1 by default now to fix issues with
+ chrome.
+- Added external URL support.
+- Added support for ``send_file``.
+- Module support and internal request handling refactoring to better
+ support pluggable applications.
+- Sessions can be set to be permanent now on a per-session basis.
+- Better error reporting on missing secret keys.
+- Added support for Google Appengine.
+
+
+Version 0.1
+-----------
+
+Released 2010-04-16
+
+- First public preview release.
diff --git a/src/flask-main/LICENSE.txt b/src/flask-main/LICENSE.txt
new file mode 100644
index 0000000..9d227a0
--- /dev/null
+++ b/src/flask-main/LICENSE.txt
@@ -0,0 +1,28 @@
+Copyright 2010 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/flask-main/README.md b/src/flask-main/README.md
new file mode 100644
index 0000000..64f56ca
--- /dev/null
+++ b/src/flask-main/README.md
@@ -0,0 +1,53 @@
+
+
+# Flask
+
+Flask is a lightweight [WSGI] web application framework. It is designed
+to make getting started quick and easy, with the ability to scale up to
+complex applications. It began as a simple wrapper around [Werkzeug]
+and [Jinja], and has become one of the most popular Python web
+application frameworks.
+
+Flask offers suggestions, but doesn't enforce any dependencies or
+project layout. It is up to the developer to choose the tools and
+libraries they want to use. There are many extensions provided by the
+community that make adding new functionality easy.
+
+[WSGI]: https://wsgi.readthedocs.io/
+[Werkzeug]: https://werkzeug.palletsprojects.com/
+[Jinja]: https://jinja.palletsprojects.com/
+
+## A Simple Example
+
+```python
+# save this as app.py
+from flask import Flask
+
+app = Flask(__name__)
+
+@app.route("/")
+def hello():
+ return "Hello, World!"
+```
+
+```
+$ flask run
+ * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+```
+
+## Donate
+
+The Pallets organization develops and supports Flask and the libraries
+it uses. In order to grow the community of contributors and users, and
+allow the maintainers to devote more time to the projects, [please
+donate today].
+
+[please donate today]: https://palletsprojects.com/donate
+
+## Contributing
+
+See our [detailed contributing documentation][contrib] for many ways to
+contribute, including reporting issues, requesting features, asking or answering
+questions, and making PRs.
+
+[contrib]: https://palletsprojects.com/contributing/
diff --git a/src/flask-main/docs/Makefile b/src/flask-main/docs/Makefile
new file mode 100644
index 0000000..d4bb2cb
--- /dev/null
+++ b/src/flask-main/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/src/flask-main/docs/_static/debugger.png b/src/flask-main/docs/_static/debugger.png
new file mode 100644
index 0000000..7d4181f
Binary files /dev/null and b/src/flask-main/docs/_static/debugger.png differ
diff --git a/src/flask-main/docs/_static/flask-icon.svg b/src/flask-main/docs/_static/flask-icon.svg
new file mode 100644
index 0000000..c802da9
--- /dev/null
+++ b/src/flask-main/docs/_static/flask-icon.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/src/flask-main/docs/_static/flask-logo.svg b/src/flask-main/docs/_static/flask-logo.svg
new file mode 100644
index 0000000..c216b61
--- /dev/null
+++ b/src/flask-main/docs/_static/flask-logo.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/flask-main/docs/_static/flask-name.svg b/src/flask-main/docs/_static/flask-name.svg
new file mode 100644
index 0000000..b46782d
--- /dev/null
+++ b/src/flask-main/docs/_static/flask-name.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/src/flask-main/docs/_static/pycharm-run-config.png b/src/flask-main/docs/_static/pycharm-run-config.png
new file mode 100644
index 0000000..ad02554
Binary files /dev/null and b/src/flask-main/docs/_static/pycharm-run-config.png differ
diff --git a/src/flask-main/docs/api.rst b/src/flask-main/docs/api.rst
new file mode 100644
index 0000000..d3c517f
--- /dev/null
+++ b/src/flask-main/docs/api.rst
@@ -0,0 +1,708 @@
+API
+===
+
+.. module:: flask
+
+This part of the documentation covers all the interfaces of Flask. For
+parts where Flask depends on external libraries, we document the most
+important right here and provide links to the canonical documentation.
+
+
+Application Object
+------------------
+
+.. autoclass:: Flask
+ :members:
+ :inherited-members:
+
+
+Blueprint Objects
+-----------------
+
+.. autoclass:: Blueprint
+ :members:
+ :inherited-members:
+
+Incoming Request Data
+---------------------
+
+.. autoclass:: Request
+ :members:
+ :inherited-members:
+ :exclude-members: json_module
+
+.. data:: request
+
+ A proxy to the request data for the current request, an instance of
+ :class:`.Request`.
+
+ This is only available when a :doc:`request context ` is
+ active.
+
+ This is a proxy. See :ref:`context-visibility` for more information.
+
+
+Response Objects
+----------------
+
+.. autoclass:: flask.Response
+ :members:
+ :inherited-members:
+ :exclude-members: json_module
+
+Sessions
+--------
+
+If you have set :attr:`Flask.secret_key` (or configured it from
+:data:`SECRET_KEY`) you can use sessions in Flask applications. A session makes
+it possible to remember information from one request to another. The way Flask
+does this is by using a signed cookie. The user can look at the session
+contents, but can't modify it unless they know the secret key, so make sure to
+set that to something complex and unguessable.
+
+To access the current session you can use the :data:`.session` proxy.
+
+.. data:: session
+
+ A proxy to the session data for the current request, an instance of
+ :class:`.SessionMixin`.
+
+ This is only available when a :doc:`request context ` is
+ active.
+
+ This is a proxy. See :ref:`context-visibility` for more information.
+
+ The session object works like a dict but tracks assignment and access to its
+ keys. It cannot track modifications to mutable values, you need to set
+ :attr:`~.SessionMixin.modified` manually when modifying a list, dict, etc.
+
+ .. code-block:: python
+
+ # appending to a list is not detected
+ session["numbers"].append(42)
+ # so mark it as modified yourself
+ session.modified = True
+
+ The session is persisted across requests using a cookie. By default the
+ users's browser will clear the cookie when it is closed. Set
+ :attr:`~.SessionMixin.permanent` to ``True`` to persist the cookie for
+ :data:`PERMANENT_SESSION_LIFETIME`.
+
+
+Session Interface
+-----------------
+
+.. versionadded:: 0.8
+
+The session interface provides a simple way to replace the session
+implementation that Flask is using.
+
+.. currentmodule:: flask.sessions
+
+.. autoclass:: SessionInterface
+ :members:
+
+.. autoclass:: SecureCookieSessionInterface
+ :members:
+
+.. autoclass:: SecureCookieSession
+ :members:
+
+.. autoclass:: NullSession
+ :members:
+
+.. autoclass:: SessionMixin
+ :members:
+
+.. admonition:: Notice
+
+ The :data:`PERMANENT_SESSION_LIFETIME` config can be an integer or ``timedelta``.
+ The :attr:`~flask.Flask.permanent_session_lifetime` attribute is always a
+ ``timedelta``.
+
+
+Test Client
+-----------
+
+.. currentmodule:: flask.testing
+
+.. autoclass:: FlaskClient
+ :members:
+
+
+Test CLI Runner
+---------------
+
+.. currentmodule:: flask.testing
+
+.. autoclass:: FlaskCliRunner
+ :members:
+
+
+Application Globals
+-------------------
+
+.. currentmodule:: flask
+
+To share data that is valid for one request only from one function to
+another, a global variable is not good enough because it would break in
+threaded environments. Flask provides you with a special object that
+ensures it is only valid for the active request and that will return
+different values for each request. In a nutshell: it does the right
+thing, like it does for :data:`.request` and :data:`.session`.
+
+.. data:: g
+
+ A proxy to a namespace object used to store data during a single request or
+ app context. An instance of :attr:`.Flask.app_ctx_globals_class`, which
+ defaults to :class:`._AppCtxGlobals`.
+
+ This is a good place to store resources during a request. For example, a
+ :meth:`~.Flask.before_request` function could load a user object from a
+ session id, then set ``g.user`` to be used in the view function.
+
+ This is only available when an :doc:`app context ` is active.
+
+ This is a proxy. See :ref:`context-visibility` for more information.
+
+ .. versionchanged:: 0.10
+ Bound to the application context instead of the request context.
+
+.. autoclass:: flask.ctx._AppCtxGlobals
+ :members:
+
+
+Useful Functions and Classes
+----------------------------
+
+.. data:: current_app
+
+ A proxy to the :class:`.Flask` application handling the current request or
+ other activity.
+
+ This is useful to access the application without needing to import it, or if
+ it can't be imported, such as when using the application factory pattern or
+ in blueprints and extensions.
+
+ This is only available when an :doc:`app context ` is active.
+
+ This is a proxy. See :ref:`context-visibility` for more information.
+
+.. autofunction:: has_request_context
+
+.. autofunction:: copy_current_request_context
+
+.. autofunction:: has_app_context
+
+.. autofunction:: url_for
+
+.. autofunction:: abort
+
+.. autofunction:: redirect
+
+.. autofunction:: make_response
+
+.. autofunction:: after_this_request
+
+.. autofunction:: send_file
+
+.. autofunction:: send_from_directory
+
+
+Message Flashing
+----------------
+
+.. autofunction:: flash
+
+.. autofunction:: get_flashed_messages
+
+
+JSON Support
+------------
+
+.. module:: flask.json
+
+Flask uses Python's built-in :mod:`json` module for handling JSON by
+default. The JSON implementation can be changed by assigning a different
+provider to :attr:`flask.Flask.json_provider_class` or
+:attr:`flask.Flask.json`. The functions provided by ``flask.json`` will
+use methods on ``app.json`` if an app context is active.
+
+Jinja's ``|tojson`` filter is configured to use the app's JSON provider.
+The filter marks the output with ``|safe``. Use it to render data inside
+HTML ``
+
+.. autofunction:: jsonify
+
+.. autofunction:: dumps
+
+.. autofunction:: dump
+
+.. autofunction:: loads
+
+.. autofunction:: load
+
+.. autoclass:: flask.json.provider.JSONProvider
+ :members:
+ :member-order: bysource
+
+.. autoclass:: flask.json.provider.DefaultJSONProvider
+ :members:
+ :member-order: bysource
+
+.. automodule:: flask.json.tag
+
+
+Template Rendering
+------------------
+
+.. currentmodule:: flask
+
+.. autofunction:: render_template
+
+.. autofunction:: render_template_string
+
+.. autofunction:: stream_template
+
+.. autofunction:: stream_template_string
+
+.. autofunction:: get_template_attribute
+
+Configuration
+-------------
+
+.. autoclass:: Config
+ :members:
+
+
+Stream Helpers
+--------------
+
+.. autofunction:: stream_with_context
+
+Useful Internals
+----------------
+
+.. autoclass:: flask.ctx.AppContext
+ :members:
+
+.. data:: flask.globals.app_ctx
+
+ A proxy to the active :class:`.AppContext`.
+
+ This is an internal object that is essential to how Flask handles requests.
+ Accessing this should not be needed in most cases. Most likely you want
+ :data:`.current_app`, :data:`.g`, :data:`.request`, and :data:`.session` instead.
+
+ This is only available when a :doc:`request context ` is
+ active.
+
+ This is a proxy. See :ref:`context-visibility` for more information.
+
+.. class:: flask.ctx.RequestContext
+
+ .. deprecated:: 3.2
+ Merged with :class:`AppContext`. This alias will be removed in Flask 4.0.
+
+.. data:: flask.globals.request_ctx
+
+ .. deprecated:: 3.2
+ Merged with :data:`.app_ctx`. This alias will be removed in Flask 4.0.
+
+.. autoclass:: flask.blueprints.BlueprintSetupState
+ :members:
+
+.. _core-signals-list:
+
+Signals
+-------
+
+Signals are provided by the `Blinker`_ library. See :doc:`signals` for an introduction.
+
+.. _blinker: https://blinker.readthedocs.io/
+
+.. data:: template_rendered
+
+ This signal is sent when a template was successfully rendered. The
+ signal is invoked with the instance of the template as `template`
+ and the context as dictionary (named `context`).
+
+ Example subscriber::
+
+ def log_template_renders(sender, template, context, **extra):
+ sender.logger.debug('Rendering template "%s" with context %s',
+ template.name or 'string template',
+ context)
+
+ from flask import template_rendered
+ template_rendered.connect(log_template_renders, app)
+
+.. data:: flask.before_render_template
+ :noindex:
+
+ This signal is sent before template rendering process. The
+ signal is invoked with the instance of the template as `template`
+ and the context as dictionary (named `context`).
+
+ Example subscriber::
+
+ def log_template_renders(sender, template, context, **extra):
+ sender.logger.debug('Rendering template "%s" with context %s',
+ template.name or 'string template',
+ context)
+
+ from flask import before_render_template
+ before_render_template.connect(log_template_renders, app)
+
+.. data:: request_started
+
+ This signal is sent when the request context is set up, before
+ any request processing happens. Because the request context is already
+ bound, the subscriber can access the request with the standard global
+ proxies such as :class:`~flask.request`.
+
+ Example subscriber::
+
+ def log_request(sender, **extra):
+ sender.logger.debug('Request context is set up')
+
+ from flask import request_started
+ request_started.connect(log_request, app)
+
+.. data:: request_finished
+
+ This signal is sent right before the response is sent to the client.
+ It is passed the response to be sent named `response`.
+
+ Example subscriber::
+
+ def log_response(sender, response, **extra):
+ sender.logger.debug('Request context is about to close down. '
+ 'Response: %s', response)
+
+ from flask import request_finished
+ request_finished.connect(log_response, app)
+
+.. data:: got_request_exception
+
+ This signal is sent when an unhandled exception happens during
+ request processing, including when debugging. The exception is
+ passed to the subscriber as ``exception``.
+
+ This signal is not sent for
+ :exc:`~werkzeug.exceptions.HTTPException`, or other exceptions that
+ have error handlers registered, unless the exception was raised from
+ an error handler.
+
+ This example shows how to do some extra logging if a theoretical
+ ``SecurityException`` was raised:
+
+ .. code-block:: python
+
+ from flask import got_request_exception
+
+ def log_security_exception(sender, exception, **extra):
+ if not isinstance(exception, SecurityException):
+ return
+
+ security_logger.exception(
+ f"SecurityException at {request.url!r}",
+ exc_info=exception,
+ )
+
+ got_request_exception.connect(log_security_exception, app)
+
+.. data:: request_tearing_down
+
+ This signal is sent when the request is tearing down. This is always
+ called, even if an exception is caused. Currently functions listening
+ to this signal are called after the regular teardown handlers, but this
+ is not something you can rely on.
+
+ Example subscriber::
+
+ def close_db_connection(sender, **extra):
+ session.close()
+
+ from flask import request_tearing_down
+ request_tearing_down.connect(close_db_connection, app)
+
+ As of Flask 0.9, this will also be passed an `exc` keyword argument
+ that has a reference to the exception that caused the teardown if
+ there was one.
+
+.. data:: appcontext_tearing_down
+
+ This signal is sent when the app context is tearing down. This is always
+ called, even if an exception is caused. Currently functions listening
+ to this signal are called after the regular teardown handlers, but this
+ is not something you can rely on.
+
+ Example subscriber::
+
+ def close_db_connection(sender, **extra):
+ session.close()
+
+ from flask import appcontext_tearing_down
+ appcontext_tearing_down.connect(close_db_connection, app)
+
+ This will also be passed an `exc` keyword argument that has a reference
+ to the exception that caused the teardown if there was one.
+
+.. data:: appcontext_pushed
+
+ This signal is sent when an application context is pushed. The sender
+ is the application. This is usually useful for unittests in order to
+ temporarily hook in information. For instance it can be used to
+ set a resource early onto the `g` object.
+
+ Example usage::
+
+ from contextlib import contextmanager
+ from flask import appcontext_pushed
+
+ @contextmanager
+ def user_set(app, user):
+ def handler(sender, **kwargs):
+ g.user = user
+ with appcontext_pushed.connected_to(handler, app):
+ yield
+
+ And in the testcode::
+
+ def test_user_me(self):
+ with user_set(app, 'john'):
+ c = app.test_client()
+ resp = c.get('/users/me')
+ assert resp.data == 'username=john'
+
+ .. versionadded:: 0.10
+
+.. data:: appcontext_popped
+
+ This signal is sent when an application context is popped. The sender
+ is the application. This usually falls in line with the
+ :data:`appcontext_tearing_down` signal.
+
+ .. versionadded:: 0.10
+
+.. data:: message_flashed
+
+ This signal is sent when the application is flashing a message. The
+ messages is sent as `message` keyword argument and the category as
+ `category`.
+
+ Example subscriber::
+
+ recorded = []
+ def record(sender, message, category, **extra):
+ recorded.append((message, category))
+
+ from flask import message_flashed
+ message_flashed.connect(record, app)
+
+ .. versionadded:: 0.10
+
+
+Class-Based Views
+-----------------
+
+.. versionadded:: 0.7
+
+.. currentmodule:: None
+
+.. autoclass:: flask.views.View
+ :members:
+
+.. autoclass:: flask.views.MethodView
+ :members:
+
+.. _url-route-registrations:
+
+URL Route Registrations
+-----------------------
+
+Generally there are three ways to define rules for the routing system:
+
+1. You can use the :meth:`flask.Flask.route` decorator.
+2. You can use the :meth:`flask.Flask.add_url_rule` function.
+3. You can directly access the underlying Werkzeug routing system
+ which is exposed as :attr:`flask.Flask.url_map`.
+
+Variable parts in the route can be specified with angular brackets
+(``/user/``). By default a variable part in the URL accepts any
+string without a slash however a different converter can be specified as
+well by using ````.
+
+Variable parts are passed to the view function as keyword arguments.
+
+The following converters are available:
+
+=========== ===============================================
+`string` accepts any text without a slash (the default)
+`int` accepts integers
+`float` like `int` but for floating point values
+`path` like the default but also accepts slashes
+`any` matches one of the items provided
+`uuid` accepts UUID strings
+=========== ===============================================
+
+Custom converters can be defined using :attr:`flask.Flask.url_map`.
+
+Here are some examples::
+
+ @app.route('/')
+ def index():
+ pass
+
+ @app.route('/')
+ def show_user(username):
+ pass
+
+ @app.route('/post/')
+ def show_post(post_id):
+ pass
+
+An important detail to keep in mind is how Flask deals with trailing
+slashes. The idea is to keep each URL unique so the following rules
+apply:
+
+1. If a rule ends with a slash and is requested without a slash by the
+ user, the user is automatically redirected to the same page with a
+ trailing slash attached.
+2. If a rule does not end with a trailing slash and the user requests the
+ page with a trailing slash, a 404 not found is raised.
+
+This is consistent with how web servers deal with static files. This
+also makes it possible to use relative link targets safely.
+
+You can also define multiple rules for the same function. They have to be
+unique however. Defaults can also be specified. Here for example is a
+definition for a URL that accepts an optional page::
+
+ @app.route('/users/', defaults={'page': 1})
+ @app.route('/users/page/')
+ def show_users(page):
+ pass
+
+This specifies that ``/users/`` will be the URL for page one and
+``/users/page/N`` will be the URL for page ``N``.
+
+If a URL contains a default value, it will be redirected to its simpler
+form with a 301 redirect. In the above example, ``/users/page/1`` will
+be redirected to ``/users/``. If your route handles ``GET`` and ``POST``
+requests, make sure the default route only handles ``GET``, as redirects
+can't preserve form data. ::
+
+ @app.route('/region/', defaults={'id': 1})
+ @app.route('/region/', methods=['GET', 'POST'])
+ def region(id):
+ pass
+
+Here are the parameters that :meth:`~flask.Flask.route` and
+:meth:`~flask.Flask.add_url_rule` accept. The only difference is that
+with the route parameter the view function is defined with the decorator
+instead of the `view_func` parameter.
+
+=============== ==========================================================
+`rule` the URL rule as string
+`endpoint` the endpoint for the registered URL rule. Flask itself
+ assumes that the name of the view function is the name
+ of the endpoint if not explicitly stated.
+`view_func` the function to call when serving a request to the
+ provided endpoint. If this is not provided one can
+ specify the function later by storing it in the
+ :attr:`~flask.Flask.view_functions` dictionary with the
+ endpoint as key.
+`defaults` A dictionary with defaults for this rule. See the
+ example above for how defaults work.
+`subdomain` specifies the rule for the subdomain in case subdomain
+ matching is in use. If not specified the default
+ subdomain is assumed.
+`**options` the options to be forwarded to the underlying
+ :class:`~werkzeug.routing.Rule` object. A change to
+ Werkzeug is handling of method options. methods is a list
+ of methods this rule should be limited to (``GET``, ``POST``
+ etc.). By default a rule just listens for ``GET`` (and
+ implicitly ``HEAD``). Starting with Flask 0.6, ``OPTIONS`` is
+ implicitly added and handled by the standard request
+ handling. They have to be specified as keyword arguments.
+=============== ==========================================================
+
+
+View Function Options
+---------------------
+
+For internal usage the view functions can have some attributes attached to
+customize behavior the view function would normally not have control over.
+The following attributes can be provided optionally to either override
+some defaults to :meth:`~flask.Flask.add_url_rule` or general behavior:
+
+- `__name__`: The name of a function is by default used as endpoint. If
+ endpoint is provided explicitly this value is used. Additionally this
+ will be prefixed with the name of the blueprint by default which
+ cannot be customized from the function itself.
+
+- `methods`: If methods are not provided when the URL rule is added,
+ Flask will look on the view function object itself if a `methods`
+ attribute exists. If it does, it will pull the information for the
+ methods from there.
+
+- `provide_automatic_options`: if this attribute is set Flask will
+ either force enable or disable the automatic implementation of the
+ HTTP ``OPTIONS`` response. This can be useful when working with
+ decorators that want to customize the ``OPTIONS`` response on a per-view
+ basis.
+
+- `required_methods`: if this attribute is set, Flask will always add
+ these methods when registering a URL rule even if the methods were
+ explicitly overridden in the ``route()`` call.
+
+Full example::
+
+ def index():
+ if request.method == 'OPTIONS':
+ # custom options handling here
+ ...
+ return 'Hello World!'
+ index.provide_automatic_options = False
+ index.methods = ['GET', 'OPTIONS']
+
+ app.add_url_rule('/', index)
+
+.. versionadded:: 0.8
+ The `provide_automatic_options` functionality was added.
+
+Command Line Interface
+----------------------
+
+.. currentmodule:: flask.cli
+
+.. autoclass:: FlaskGroup
+ :members:
+
+.. autoclass:: AppGroup
+ :members:
+
+.. autoclass:: ScriptInfo
+ :members:
+
+.. autofunction:: load_dotenv
+
+.. autofunction:: with_appcontext
+
+.. autofunction:: pass_script_info
+
+ Marks a function so that an instance of :class:`ScriptInfo` is passed
+ as first argument to the click callback.
+
+.. autodata:: run_command
+
+.. autodata:: shell_command
diff --git a/src/flask-main/docs/appcontext.rst b/src/flask-main/docs/appcontext.rst
new file mode 100644
index 0000000..81b73b4
--- /dev/null
+++ b/src/flask-main/docs/appcontext.rst
@@ -0,0 +1,186 @@
+The App and Request Context
+===========================
+
+The context keeps track of data and objects during a request, CLI command, or
+other activity. Rather than passing this data around to every function, the
+:data:`.current_app`, :data:`.g`, :data:`.request`, and :data:`.session` proxies
+are accessed instead.
+
+When handling a request, the context is referred to as the "request context"
+because it contains request data in addition to application data. Otherwise,
+such as during a CLI command, it is referred to as the "app context". During an
+app context, :data:`.current_app` and :data:`.g` are available, while during a
+request context :data:`.request` and :data:`.session` are also available.
+
+
+Purpose of the Context
+----------------------
+
+The context and proxies help solve two development issues: circular imports, and
+passing around global data during a request.
+
+The :class:`.Flask` application object has attributes, such as
+:attr:`~.Flask.config`, that are useful to access within views and other
+functions. However, importing the ``app`` instance within the modules in your
+project is prone to circular import issues. When using the
+:doc:`app factory pattern ` or writing reusable
+:doc:`blueprints ` or :doc:`extensions ` there won't
+be an ``app`` instance to import at all.
+
+When the application handles a request, it creates a :class:`.Request` object.
+Because a *worker* handles only one request at a time, the request data can be
+considered global to that worker during that request. Passing it as an argument
+through every function during the request becomes verbose and redundant.
+
+Flask solves these issues with the *active context* pattern. Rather than
+importing an ``app`` directly, or having to pass it and the request through to
+every single function, you import and access the proxies, which point to the
+currently active application and request data. This is sometimes referred to
+as "context local" data.
+
+
+Context During Setup
+--------------------
+
+If you try to access :data:`.current_app`, :data:`.g`, or anything that uses it,
+outside an app context, you'll get this error message:
+
+.. code-block:: pytb
+
+ RuntimeError: Working outside of application context.
+
+ Attempted to use functionality that expected a current application to be
+ set. To solve this, set up an app context using 'with app.app_context()'.
+ See the documentation on app context for more information.
+
+If you see that error while configuring your application, such as when
+initializing an extension, you can push a context manually since you have direct
+access to the ``app``. Use :meth:`.Flask.app_context` in a ``with`` block.
+
+.. code-block:: python
+
+ def create_app():
+ app = Flask(__name__)
+
+ with app.app_context():
+ init_db()
+
+ return app
+
+If you see that error somewhere else in your code not related to setting up the
+application, it most likely indicates that you should move that code into a view
+function or CLI command.
+
+
+Context During Testing
+----------------------
+
+See :doc:`/testing` for detailed information about managing the context during
+tests.
+
+If you try to access :data:`.request`, :data:`.session`, or anything that uses
+it, outside a request context, you'll get this error message:
+
+.. code-block:: pytb
+
+ RuntimeError: Working outside of request context.
+
+ Attempted to use functionality that expected an active HTTP request. See the
+ documentation on request context for more information.
+
+This will probably only happen during tests. If you see that error somewhere
+else in your code not related to testing, it most likely indicates that you
+should move that code into a view function.
+
+The primary way to solve this is to use :meth:`.Flask.test_client` to simulate
+a full request.
+
+If you only want to unit test one function, rather than a full request, use
+:meth:`.Flask.test_request_context` in a ``with`` block.
+
+.. code-block:: python
+
+ def generate_report(year):
+ format = request.args.get("format")
+ ...
+
+ with app.test_request_context(
+ "/make_report/2017", query_string={"format": "short"}
+ ):
+ generate_report()
+
+
+.. _context-visibility:
+
+Visibility of the Context
+-------------------------
+
+The context will have the same lifetime as an activity, such as a request, CLI
+command, or ``with`` block. Various callbacks and signals registered with the
+app will be run during the context.
+
+When a Flask application handles a request, it pushes a requet context
+to set the active application and request data. When it handles a CLI command,
+it pushes an app context to set the active application. When the activity ends,
+it pops that context. Proxy objects like :data:`.request`, :data:`.session`,
+:data:`.g`, and :data:`.current_app`, are accessible while the context is pushed
+and active, and are not accessible after the context is popped.
+
+The context is unique to each thread (or other worker type). The proxies cannot
+be passed to another worker, which has a different context space and will not
+know about the active context in the parent's space.
+
+Besides being scoped to each worker, the proxy object has a separate type and
+identity than the proxied real object. In some cases you'll need access to the
+real object, rather than the proxy. Use the
+:meth:`~.LocalProxy._get_current_object` method in those cases.
+
+.. code-block:: python
+
+ app = current_app._get_current_object()
+ my_signal.send(app)
+
+
+Lifecycle of the Context
+------------------------
+
+Flask dispatches a request in multiple stages which can affect the request,
+response, and how errors are handled. See :doc:`/lifecycle` for a list of all
+the steps, callbacks, and signals during each request. The following are the
+steps directly related to the context.
+
+- The app context is pushed, the proxies are available.
+- The :data:`.appcontext_pushed` signal is sent.
+- The request is dispatched.
+- Any :meth:`.Flask.teardown_request` decorated functions are called.
+- The :data:`.request_tearing_down` signal is sent.
+- Any :meth:`.Flask.teardown_appcontext` decorated functions are called.
+- The :data:`.appcontext_tearing_down` signal is sent.
+- The app context is popped, the proxies are no longer available.
+- The :data:`.appcontext_popped` signal is sent.
+
+The teardown callbacks are called by the context when it is popped. They are
+called even if there is an unhandled exception during dispatch. They may be
+called multiple times in some test scenarios. This means there is no guarantee
+that any other parts of the request dispatch have run. Be sure to write these
+functions in a way that does not depend on other callbacks and will not fail.
+
+
+How the Context Works
+---------------------
+
+Context locals are implemented using Python's :mod:`contextvars` and Werkzeug's
+:class:`~werkzeug.local.LocalProxy`. Python's contextvars are a low level
+structure to manage data local to a thread or coroutine. ``LocalProxy`` wraps
+the contextvar so that access to any attributes and methods is forwarded to the
+object stored in the contextvar.
+
+The context is tracked like a stack, with the active context at the top of the
+stack. Flask manages pushing and popping contexts during requests, CLI commands,
+testing, ``with`` blocks, etc. The proxies access attributes on the active
+context.
+
+Because it is a stack, other contexts may be pushed to change the proxies during
+an already active context. This is not a common pattern, but can be used in
+advanced use cases. For example, a Flask application can be used as WSGI
+middleware, calling another wrapped Flask app from a view.
diff --git a/src/flask-main/docs/async-await.rst b/src/flask-main/docs/async-await.rst
new file mode 100644
index 0000000..16b6194
--- /dev/null
+++ b/src/flask-main/docs/async-await.rst
@@ -0,0 +1,125 @@
+.. _async_await:
+
+Using ``async`` and ``await``
+=============================
+
+.. versionadded:: 2.0
+
+Routes, error handlers, before request, after request, and teardown
+functions can all be coroutine functions if Flask is installed with the
+``async`` extra (``pip install flask[async]``). This allows views to be
+defined with ``async def`` and use ``await``.
+
+.. code-block:: python
+
+ @app.route("/get-data")
+ async def get_data():
+ data = await async_db_query(...)
+ return jsonify(data)
+
+Pluggable class-based views also support handlers that are implemented as
+coroutines. This applies to the :meth:`~flask.views.View.dispatch_request`
+method in views that inherit from the :class:`flask.views.View` class, as
+well as all the HTTP method handlers in views that inherit from the
+:class:`flask.views.MethodView` class.
+
+.. admonition:: Using ``async`` with greenlet
+
+ When using gevent or eventlet to serve an application or patch the
+ runtime, greenlet>=1.0 is required. When using PyPy, PyPy>=7.3.7 is
+ required.
+
+
+Performance
+-----------
+
+Async functions require an event loop to run. Flask, as a WSGI
+application, uses one worker to handle one request/response cycle.
+When a request comes in to an async view, Flask will start an event loop
+in a thread, run the view function there, then return the result.
+
+Each request still ties up one worker, even for async views. The upside
+is that you can run async code within a view, for example to make
+multiple concurrent database queries, HTTP requests to an external API,
+etc. However, the number of requests your application can handle at one
+time will remain the same.
+
+**Async is not inherently faster than sync code.** Async is beneficial
+when performing concurrent IO-bound tasks, but will probably not improve
+CPU-bound tasks. Traditional Flask views will still be appropriate for
+most use cases, but Flask's async support enables writing and using
+code that wasn't possible natively before.
+
+
+Background tasks
+----------------
+
+Async functions will run in an event loop until they complete, at
+which stage the event loop will stop. This means any additional
+spawned tasks that haven't completed when the async function completes
+will be cancelled. Therefore you cannot spawn background tasks, for
+example via ``asyncio.create_task``.
+
+If you wish to use background tasks it is best to use a task queue to
+trigger background work, rather than spawn tasks in a view
+function. With that in mind you can spawn asyncio tasks by serving
+Flask with an ASGI server and utilising the asgiref WsgiToAsgi adapter
+as described in :doc:`deploying/asgi`. This works as the adapter creates
+an event loop that runs continually.
+
+
+When to use Quart instead
+-------------------------
+
+Flask's async support is less performant than async-first frameworks due
+to the way it is implemented. If you have a mainly async codebase it
+would make sense to consider `Quart`_. Quart is a reimplementation of
+Flask based on the `ASGI`_ standard instead of WSGI. This allows it to
+handle many concurrent requests, long running requests, and websockets
+without requiring multiple worker processes or threads.
+
+It has also already been possible to run Flask with Gevent or Eventlet
+to get many of the benefits of async request handling. These libraries
+patch low-level Python functions to accomplish this, whereas ``async``/
+``await`` and ASGI use standard, modern Python capabilities. Deciding
+whether you should use Flask, Quart, or something else is ultimately up
+to understanding the specific needs of your project.
+
+.. _Quart: https://github.com/pallets/quart
+.. _ASGI: https://asgi.readthedocs.io/en/latest/
+
+
+Extensions
+----------
+
+Flask extensions predating Flask's async support do not expect async views.
+If they provide decorators to add functionality to views, those will probably
+not work with async views because they will not await the function or be
+awaitable. Other functions they provide will not be awaitable either and
+will probably be blocking if called within an async view.
+
+Extension authors can support async functions by utilising the
+:meth:`flask.Flask.ensure_sync` method. For example, if the extension
+provides a view function decorator add ``ensure_sync`` before calling
+the decorated function,
+
+.. code-block:: python
+
+ def extension(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ ... # Extension logic
+ return current_app.ensure_sync(func)(*args, **kwargs)
+
+ return wrapper
+
+Check the changelog of the extension you want to use to see if they've
+implemented async support, or make a feature request or PR to them.
+
+
+Other event loops
+-----------------
+
+At the moment Flask only supports :mod:`asyncio`. It's possible to
+override :meth:`flask.Flask.ensure_sync` to change how async functions
+are wrapped to use a different library.
diff --git a/src/flask-main/docs/blueprints.rst b/src/flask-main/docs/blueprints.rst
new file mode 100644
index 0000000..d5cf3d8
--- /dev/null
+++ b/src/flask-main/docs/blueprints.rst
@@ -0,0 +1,315 @@
+Modular Applications with Blueprints
+====================================
+
+.. currentmodule:: flask
+
+.. versionadded:: 0.7
+
+Flask uses a concept of *blueprints* for making application components and
+supporting common patterns within an application or across applications.
+Blueprints can greatly simplify how large applications work and provide a
+central means for Flask extensions to register operations on applications.
+A :class:`Blueprint` object works similarly to a :class:`Flask`
+application object, but it is not actually an application. Rather it is a
+*blueprint* of how to construct or extend an application.
+
+Why Blueprints?
+---------------
+
+Blueprints in Flask are intended for these cases:
+
+* Factor an application into a set of blueprints. This is ideal for
+ larger applications; a project could instantiate an application object,
+ initialize several extensions, and register a collection of blueprints.
+* Register a blueprint on an application at a URL prefix and/or subdomain.
+ Parameters in the URL prefix/subdomain become common view arguments
+ (with defaults) across all view functions in the blueprint.
+* Register a blueprint multiple times on an application with different URL
+ rules.
+* Provide template filters, static files, templates, and other utilities
+ through blueprints. A blueprint does not have to implement applications
+ or view functions.
+* Register a blueprint on an application for any of these cases when
+ initializing a Flask extension.
+
+A blueprint in Flask is not a pluggable app because it is not actually an
+application -- it's a set of operations which can be registered on an
+application, even multiple times. Why not have multiple application
+objects? You can do that (see :doc:`/patterns/appdispatch`), but your
+applications will have separate configs and will be managed at the WSGI
+layer.
+
+Blueprints instead provide separation at the Flask level, share
+application config, and can change an application object as necessary with
+being registered. The downside is that you cannot unregister a blueprint
+once an application was created without having to destroy the whole
+application object.
+
+The Concept of Blueprints
+-------------------------
+
+The basic concept of blueprints is that they record operations to execute
+when registered on an application. Flask associates view functions with
+blueprints when dispatching requests and generating URLs from one endpoint
+to another.
+
+My First Blueprint
+------------------
+
+This is what a very basic blueprint looks like. In this case we want to
+implement a blueprint that does simple rendering of static templates::
+
+ from flask import Blueprint, render_template, abort
+ from jinja2 import TemplateNotFound
+
+ simple_page = Blueprint('simple_page', __name__,
+ template_folder='templates')
+
+ @simple_page.route('/', defaults={'page': 'index'})
+ @simple_page.route('/')
+ def show(page):
+ try:
+ return render_template(f'pages/{page}.html')
+ except TemplateNotFound:
+ abort(404)
+
+When you bind a function with the help of the ``@simple_page.route``
+decorator, the blueprint will record the intention of registering the
+function ``show`` on the application when it's later registered.
+Additionally it will prefix the endpoint of the function with the
+name of the blueprint which was given to the :class:`Blueprint`
+constructor (in this case also ``simple_page``). The blueprint's name
+does not modify the URL, only the endpoint.
+
+Registering Blueprints
+----------------------
+
+So how do you register that blueprint? Like this::
+
+ from flask import Flask
+ from yourapplication.simple_page import simple_page
+
+ app = Flask(__name__)
+ app.register_blueprint(simple_page)
+
+If you check the rules registered on the application, you will find
+these::
+
+ >>> app.url_map
+ Map([' (HEAD, OPTIONS, GET) -> static>,
+ ' (HEAD, OPTIONS, GET) -> simple_page.show>,
+ simple_page.show>])
+
+The first one is obviously from the application itself for the static
+files. The other two are for the `show` function of the ``simple_page``
+blueprint. As you can see, they are also prefixed with the name of the
+blueprint and separated by a dot (``.``).
+
+Blueprints however can also be mounted at different locations::
+
+ app.register_blueprint(simple_page, url_prefix='/pages')
+
+And sure enough, these are the generated rules::
+
+ >>> app.url_map
+ Map([' (HEAD, OPTIONS, GET) -> static>,
+ ' (HEAD, OPTIONS, GET) -> simple_page.show>,
+ simple_page.show>])
+
+On top of that you can register blueprints multiple times though not every
+blueprint might respond properly to that. In fact it depends on how the
+blueprint is implemented if it can be mounted more than once.
+
+Nesting Blueprints
+------------------
+
+It is possible to register a blueprint on another blueprint.
+
+.. code-block:: python
+
+ parent = Blueprint('parent', __name__, url_prefix='/parent')
+ child = Blueprint('child', __name__, url_prefix='/child')
+ parent.register_blueprint(child)
+ app.register_blueprint(parent)
+
+The child blueprint will gain the parent's name as a prefix to its
+name, and child URLs will be prefixed with the parent's URL prefix.
+
+.. code-block:: python
+
+ url_for('parent.child.create')
+ /parent/child/create
+
+In addition a child blueprint's will gain their parent's subdomain,
+with their subdomain as prefix if present i.e.
+
+.. code-block:: python
+
+ parent = Blueprint('parent', __name__, subdomain='parent')
+ child = Blueprint('child', __name__, subdomain='child')
+ parent.register_blueprint(child)
+ app.register_blueprint(parent)
+
+ url_for('parent.child.create', _external=True)
+ "child.parent.domain.tld"
+
+Blueprint-specific before request functions, etc. registered with the
+parent will trigger for the child. If a child does not have an error
+handler that can handle a given exception, the parent's will be tried.
+
+
+Blueprint Resources
+-------------------
+
+Blueprints can provide resources as well. Sometimes you might want to
+introduce a blueprint only for the resources it provides.
+
+Blueprint Resource Folder
+`````````````````````````
+
+Like for regular applications, blueprints are considered to be contained
+in a folder. While multiple blueprints can originate from the same folder,
+it does not have to be the case and it's usually not recommended.
+
+The folder is inferred from the second argument to :class:`Blueprint` which
+is usually `__name__`. This argument specifies what logical Python
+module or package corresponds to the blueprint. If it points to an actual
+Python package that package (which is a folder on the filesystem) is the
+resource folder. If it's a module, the package the module is contained in
+will be the resource folder. You can access the
+:attr:`Blueprint.root_path` property to see what the resource folder is::
+
+ >>> simple_page.root_path
+ '/Users/username/TestProject/yourapplication'
+
+To quickly open sources from this folder you can use the
+:meth:`~Blueprint.open_resource` function::
+
+ with simple_page.open_resource('static/style.css') as f:
+ code = f.read()
+
+Static Files
+````````````
+
+A blueprint can expose a folder with static files by providing the path
+to the folder on the filesystem with the ``static_folder`` argument.
+It is either an absolute path or relative to the blueprint's location::
+
+ admin = Blueprint('admin', __name__, static_folder='static')
+
+By default the rightmost part of the path is where it is exposed on the
+web. This can be changed with the ``static_url_path`` argument. Because the
+folder is called ``static`` here it will be available at the
+``url_prefix`` of the blueprint + ``/static``. If the blueprint
+has the prefix ``/admin``, the static URL will be ``/admin/static``.
+
+The endpoint is named ``blueprint_name.static``. You can generate URLs
+to it with :func:`url_for` like you would with the static folder of the
+application::
+
+ url_for('admin.static', filename='style.css')
+
+However, if the blueprint does not have a ``url_prefix``, it is not
+possible to access the blueprint's static folder. This is because the
+URL would be ``/static`` in this case, and the application's ``/static``
+route takes precedence. Unlike template folders, blueprint static
+folders are not searched if the file does not exist in the application
+static folder.
+
+Templates
+`````````
+
+If you want the blueprint to expose templates you can do that by providing
+the `template_folder` parameter to the :class:`Blueprint` constructor::
+
+ admin = Blueprint('admin', __name__, template_folder='templates')
+
+For static files, the path can be absolute or relative to the blueprint
+resource folder.
+
+The template folder is added to the search path of templates but with a lower
+priority than the actual application's template folder. That way you can
+easily override templates that a blueprint provides in the actual application.
+This also means that if you don't want a blueprint template to be accidentally
+overridden, make sure that no other blueprint or actual application template
+has the same relative path. When multiple blueprints provide the same relative
+template path the first blueprint registered takes precedence over the others.
+
+
+So if you have a blueprint in the folder ``yourapplication/admin`` and you
+want to render the template ``'admin/index.html'`` and you have provided
+``templates`` as a `template_folder` you will have to create a file like
+this: :file:`yourapplication/admin/templates/admin/index.html`. The reason
+for the extra ``admin`` folder is to avoid getting our template overridden
+by a template named ``index.html`` in the actual application template
+folder.
+
+To further reiterate this: if you have a blueprint named ``admin`` and you
+want to render a template called :file:`index.html` which is specific to this
+blueprint, the best idea is to lay out your templates like this::
+
+ yourpackage/
+ blueprints/
+ admin/
+ templates/
+ admin/
+ index.html
+ __init__.py
+
+And then when you want to render the template, use :file:`admin/index.html` as
+the name to look up the template by. If you encounter problems loading
+the correct templates enable the ``EXPLAIN_TEMPLATE_LOADING`` config
+variable which will instruct Flask to print out the steps it goes through
+to locate templates on every ``render_template`` call.
+
+Building URLs
+-------------
+
+If you want to link from one page to another you can use the
+:func:`url_for` function just like you normally would do just that you
+prefix the URL endpoint with the name of the blueprint and a dot (``.``)::
+
+ url_for('admin.index')
+
+Additionally if you are in a view function of a blueprint or a rendered
+template and you want to link to another endpoint of the same blueprint,
+you can use relative redirects by prefixing the endpoint with a dot only::
+
+ url_for('.index')
+
+This will link to ``admin.index`` for instance in case the current request
+was dispatched to any other admin blueprint endpoint.
+
+
+Blueprint Error Handlers
+------------------------
+
+Blueprints support the ``errorhandler`` decorator just like the :class:`Flask`
+application object, so it is easy to make Blueprint-specific custom error
+pages.
+
+Here is an example for a "404 Page Not Found" exception::
+
+ @simple_page.errorhandler(404)
+ def page_not_found(e):
+ return render_template('pages/404.html')
+
+Most errorhandlers will simply work as expected; however, there is a caveat
+concerning handlers for 404 and 405 exceptions. These errorhandlers are only
+invoked from an appropriate ``raise`` statement or a call to ``abort`` in another
+of the blueprint's view functions; they are not invoked by, e.g., an invalid URL
+access. This is because the blueprint does not "own" a certain URL space, so
+the application instance has no way of knowing which blueprint error handler it
+should run if given an invalid URL. If you would like to execute different
+handling strategies for these errors based on URL prefixes, they may be defined
+at the application level using the ``request`` proxy object::
+
+ @app.errorhandler(404)
+ @app.errorhandler(405)
+ def _handle_api_error(ex):
+ if request.path.startswith('/api/'):
+ return jsonify(error=str(ex)), ex.code
+ else:
+ return ex
+
+See :doc:`/errorhandling`.
diff --git a/src/flask-main/docs/changes.rst b/src/flask-main/docs/changes.rst
new file mode 100644
index 0000000..955deaf
--- /dev/null
+++ b/src/flask-main/docs/changes.rst
@@ -0,0 +1,4 @@
+Changes
+=======
+
+.. include:: ../CHANGES.rst
diff --git a/src/flask-main/docs/cli.rst b/src/flask-main/docs/cli.rst
new file mode 100644
index 0000000..a72e6d5
--- /dev/null
+++ b/src/flask-main/docs/cli.rst
@@ -0,0 +1,556 @@
+.. currentmodule:: flask
+
+Command Line Interface
+======================
+
+Installing Flask installs the ``flask`` script, a `Click`_ command line
+interface, in your virtualenv. Executed from the terminal, this script gives
+access to built-in, extension, and application-defined commands. The ``--help``
+option will give more information about any commands and options.
+
+.. _Click: https://click.palletsprojects.com/
+
+
+Application Discovery
+---------------------
+
+The ``flask`` command is installed by Flask, not your application; it must be
+told where to find your application in order to use it. The ``--app``
+option is used to specify how to load the application.
+
+While ``--app`` supports a variety of options for specifying your
+application, most use cases should be simple. Here are the typical values:
+
+(nothing)
+ The name "app" or "wsgi" is imported (as a ".py" file, or package),
+ automatically detecting an app (``app`` or ``application``) or
+ factory (``create_app`` or ``make_app``).
+
+``--app hello``
+ The given name is imported, automatically detecting an app (``app``
+ or ``application``) or factory (``create_app`` or ``make_app``).
+
+----
+
+``--app`` has three parts: an optional path that sets the current working
+directory, a Python file or dotted import path, and an optional variable
+name of the instance or factory. If the name is a factory, it can optionally
+be followed by arguments in parentheses. The following values demonstrate these
+parts:
+
+``--app src/hello``
+ Sets the current working directory to ``src`` then imports ``hello``.
+
+``--app hello.web``
+ Imports the path ``hello.web``.
+
+``--app hello:app2``
+ Uses the ``app2`` Flask instance in ``hello``.
+
+``--app 'hello:create_app("dev")'``
+ The ``create_app`` factory in ``hello`` is called with the string ``'dev'``
+ as the argument.
+
+If ``--app`` is not set, the command will try to import "app" or
+"wsgi" (as a ".py" file, or package) and try to detect an application
+instance or factory.
+
+Within the given import, the command looks for an application instance named
+``app`` or ``application``, then any application instance. If no instance is
+found, the command looks for a factory function named ``create_app`` or
+``make_app`` that returns an instance.
+
+If parentheses follow the factory name, their contents are parsed as
+Python literals and passed as arguments and keyword arguments to the
+function. This means that strings must still be in quotes.
+
+
+Run the Development Server
+--------------------------
+
+The :func:`run ` command will start the development server. It
+replaces the :meth:`Flask.run` method in most cases. ::
+
+ $ flask --app hello run
+ * Serving Flask app "hello"
+ * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+
+.. warning:: Do not use this command to run your application in production.
+ Only use the development server during development. The development server
+ is provided for convenience, but is not designed to be particularly secure,
+ stable, or efficient. See :doc:`/deploying/index` for how to run in production.
+
+If another program is already using port 5000, you'll see
+``OSError: [Errno 98]`` or ``OSError: [WinError 10013]`` when the
+server tries to start. See :ref:`address-already-in-use` for how to
+handle that.
+
+
+Debug Mode
+~~~~~~~~~~
+
+In debug mode, the ``flask run`` command will enable the interactive debugger and the
+reloader by default, and make errors easier to see and debug. To enable debug mode, use
+the ``--debug`` option.
+
+.. code-block:: console
+
+ $ flask --app hello run --debug
+ * Serving Flask app "hello"
+ * Debug mode: on
+ * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+ * Restarting with inotify reloader
+ * Debugger is active!
+ * Debugger PIN: 223-456-919
+
+The ``--debug`` option can also be passed to the top level ``flask`` command to enable
+debug mode for any command. The following two ``run`` calls are equivalent.
+
+.. code-block:: console
+
+ $ flask --app hello --debug run
+ $ flask --app hello run --debug
+
+
+Watch and Ignore Files with the Reloader
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using debug mode, the reloader will trigger whenever your Python code or imported
+modules change. The reloader can watch additional files with the ``--extra-files``
+option. Multiple paths are separated with ``:``, or ``;`` on Windows.
+
+.. code-block:: text
+
+ $ flask run --extra-files file1:dirA/file2:dirB/
+ * Running on http://127.0.0.1:8000/
+ * Detected change in '/path/to/file1', reloading
+
+The reloader can also ignore files using :mod:`fnmatch` patterns with the
+``--exclude-patterns`` option. Multiple patterns are separated with ``:``, or ``;`` on
+Windows.
+
+
+Open a Shell
+------------
+
+To explore the data in your application, you can start an interactive Python
+shell with the :func:`shell ` command. An application
+context will be active, and the app instance will be imported. ::
+
+ $ flask shell
+ Python 3.10.0 (default, Oct 27 2021, 06:59:51) [GCC 11.1.0] on linux
+ App: example [production]
+ Instance: /home/david/Projects/pallets/flask/instance
+ >>>
+
+Use :meth:`~Flask.shell_context_processor` to add other automatic imports.
+
+
+.. _dotenv:
+
+Environment Variables From dotenv
+---------------------------------
+
+The ``flask`` command supports setting any option for any command with
+environment variables. The variables are named like ``FLASK_OPTION`` or
+``FLASK_COMMAND_OPTION``, for example ``FLASK_APP`` or
+``FLASK_RUN_PORT``.
+
+Rather than passing options every time you run a command, or environment
+variables every time you open a new terminal, you can use Flask's dotenv
+support to set environment variables automatically.
+
+If `python-dotenv`_ is installed, running the ``flask`` command will set
+environment variables defined in the files ``.env`` and ``.flaskenv``.
+You can also specify an extra file to load with the ``--env-file``
+option. Dotenv files can be used to avoid having to set ``--app`` or
+``FLASK_APP`` manually, and to set configuration using environment
+variables similar to how some deployment services work.
+
+Variables set on the command line are used over those set in :file:`.env`,
+which are used over those set in :file:`.flaskenv`. :file:`.flaskenv` should be
+used for public variables, such as ``FLASK_APP``, while :file:`.env` should not
+be committed to your repository so that it can set private variables.
+
+Directories are scanned upwards from the directory you call ``flask``
+from to locate the files.
+
+The files are only loaded by the ``flask`` command or calling
+:meth:`~Flask.run`. If you would like to load these files when running in
+production, you should call :func:`~cli.load_dotenv` manually.
+
+.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
+
+
+Setting Command Options
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Click is configured to load default values for command options from
+environment variables. The variables use the pattern
+``FLASK_COMMAND_OPTION``. For example, to set the port for the run
+command, instead of ``flask run --port 8000``:
+
+.. tabs::
+
+ .. group-tab:: Bash
+
+ .. code-block:: text
+
+ $ export FLASK_RUN_PORT=8000
+ $ flask run
+ * Running on http://127.0.0.1:8000/
+
+ .. group-tab:: Fish
+
+ .. code-block:: text
+
+ $ set -x FLASK_RUN_PORT 8000
+ $ flask run
+ * Running on http://127.0.0.1:8000/
+
+ .. group-tab:: CMD
+
+ .. code-block:: text
+
+ > set FLASK_RUN_PORT=8000
+ > flask run
+ * Running on http://127.0.0.1:8000/
+
+ .. group-tab:: Powershell
+
+ .. code-block:: text
+
+ > $env:FLASK_RUN_PORT = 8000
+ > flask run
+ * Running on http://127.0.0.1:8000/
+
+These can be added to the ``.flaskenv`` file just like ``FLASK_APP`` to
+control default command options.
+
+
+Disable dotenv
+~~~~~~~~~~~~~~
+
+The ``flask`` command will show a message if it detects dotenv files but
+python-dotenv is not installed.
+
+.. code-block:: bash
+
+ $ flask run
+ * Tip: There are .env files present. Do "pip install python-dotenv" to use them.
+
+You can tell Flask not to load dotenv files even when python-dotenv is
+installed by setting the ``FLASK_SKIP_DOTENV`` environment variable.
+This can be useful if you want to load them manually, or if you're using
+a project runner that loads them already. Keep in mind that the
+environment variables must be set before the app loads or it won't
+configure as expected.
+
+.. tabs::
+
+ .. group-tab:: Bash
+
+ .. code-block:: text
+
+ $ export FLASK_SKIP_DOTENV=1
+ $ flask run
+
+ .. group-tab:: Fish
+
+ .. code-block:: text
+
+ $ set -x FLASK_SKIP_DOTENV 1
+ $ flask run
+
+ .. group-tab:: CMD
+
+ .. code-block:: text
+
+ > set FLASK_SKIP_DOTENV=1
+ > flask run
+
+ .. group-tab:: Powershell
+
+ .. code-block:: text
+
+ > $env:FLASK_SKIP_DOTENV = 1
+ > flask run
+
+
+Environment Variables From virtualenv
+-------------------------------------
+
+If you do not want to install dotenv support, you can still set environment
+variables by adding them to the end of the virtualenv's :file:`activate`
+script. Activating the virtualenv will set the variables.
+
+.. tabs::
+
+ .. group-tab:: Bash
+
+ Unix Bash, :file:`.venv/bin/activate`::
+
+ $ export FLASK_APP=hello
+
+ .. group-tab:: Fish
+
+ Fish, :file:`.venv/bin/activate.fish`::
+
+ $ set -x FLASK_APP hello
+
+ .. group-tab:: CMD
+
+ Windows CMD, :file:`.venv\\Scripts\\activate.bat`::
+
+ > set FLASK_APP=hello
+
+ .. group-tab:: Powershell
+
+ Windows Powershell, :file:`.venv\\Scripts\\activate.ps1`::
+
+ > $env:FLASK_APP = "hello"
+
+It is preferred to use dotenv support over this, since :file:`.flaskenv` can be
+committed to the repository so that it works automatically wherever the project
+is checked out.
+
+
+Custom Commands
+---------------
+
+The ``flask`` command is implemented using `Click`_. See that project's
+documentation for full information about writing commands.
+
+This example adds the command ``create-user`` that takes the argument
+``name``. ::
+
+ import click
+ from flask import Flask
+
+ app = Flask(__name__)
+
+ @app.cli.command("create-user")
+ @click.argument("name")
+ def create_user(name):
+ ...
+
+::
+
+ $ flask create-user admin
+
+This example adds the same command, but as ``user create``, a command in a
+group. This is useful if you want to organize multiple related commands. ::
+
+ import click
+ from flask import Flask
+ from flask.cli import AppGroup
+
+ app = Flask(__name__)
+ user_cli = AppGroup('user')
+
+ @user_cli.command('create')
+ @click.argument('name')
+ def create_user(name):
+ ...
+
+ app.cli.add_command(user_cli)
+
+::
+
+ $ flask user create demo
+
+See :ref:`testing-cli` for an overview of how to test your custom
+commands.
+
+
+Registering Commands with Blueprints
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If your application uses blueprints, you can optionally register CLI
+commands directly onto them. When your blueprint is registered onto your
+application, the associated commands will be available to the ``flask``
+command. By default, those commands will be nested in a group matching
+the name of the blueprint.
+
+.. code-block:: python
+
+ from flask import Blueprint
+
+ bp = Blueprint('students', __name__)
+
+ @bp.cli.command('create')
+ @click.argument('name')
+ def create(name):
+ ...
+
+ app.register_blueprint(bp)
+
+.. code-block:: text
+
+ $ flask students create alice
+
+You can alter the group name by specifying the ``cli_group`` parameter
+when creating the :class:`Blueprint` object, or later with
+:meth:`app.register_blueprint(bp, cli_group='...') `.
+The following are equivalent:
+
+.. code-block:: python
+
+ bp = Blueprint('students', __name__, cli_group='other')
+ # or
+ app.register_blueprint(bp, cli_group='other')
+
+.. code-block:: text
+
+ $ flask other create alice
+
+Specifying ``cli_group=None`` will remove the nesting and merge the
+commands directly to the application's level:
+
+.. code-block:: python
+
+ bp = Blueprint('students', __name__, cli_group=None)
+ # or
+ app.register_blueprint(bp, cli_group=None)
+
+.. code-block:: text
+
+ $ flask create alice
+
+
+Application Context
+~~~~~~~~~~~~~~~~~~~
+
+Commands added using the Flask app's :attr:`~Flask.cli` or
+:class:`~flask.cli.FlaskGroup` :meth:`~cli.AppGroup.command` decorator
+will be executed with an application context pushed, so your custom
+commands and parameters have access to the app and its configuration. The
+:func:`~cli.with_appcontext` decorator can be used to get the same
+behavior, but is not needed in most cases.
+
+.. code-block:: python
+
+ import click
+ from flask.cli import with_appcontext
+
+ @click.command()
+ @with_appcontext
+ def do_work():
+ ...
+
+ app.cli.add_command(do_work)
+
+
+Plugins
+-------
+
+Flask will automatically load commands specified in the ``flask.commands``
+`entry point`_. This is useful for extensions that want to add commands when
+they are installed. Entry points are specified in :file:`pyproject.toml`:
+
+.. code-block:: toml
+
+ [project.entry-points."flask.commands"]
+ my-command = "my_extension.commands:cli"
+
+.. _entry point: https://packaging.python.org/tutorials/packaging-projects/#entry-points
+
+Inside :file:`my_extension/commands.py` you can then export a Click
+object::
+
+ import click
+
+ @click.command()
+ def cli():
+ ...
+
+Once that package is installed in the same virtualenv as your Flask project,
+you can run ``flask my-command`` to invoke the command.
+
+
+.. _custom-scripts:
+
+Custom Scripts
+--------------
+
+When you are using the app factory pattern, it may be more convenient to define
+your own Click script. Instead of using ``--app`` and letting Flask load
+your application, you can create your own Click object and export it as a
+`console script`_ entry point.
+
+Create an instance of :class:`~cli.FlaskGroup` and pass it the factory::
+
+ import click
+ from flask import Flask
+ from flask.cli import FlaskGroup
+
+ def create_app():
+ app = Flask('wiki')
+ # other setup
+ return app
+
+ @click.group(cls=FlaskGroup, create_app=create_app)
+ def cli():
+ """Management script for the Wiki application."""
+
+Define the entry point in :file:`pyproject.toml`:
+
+.. code-block:: toml
+
+ [project.scripts]
+ wiki = "wiki:cli"
+
+Install the application in the virtualenv in editable mode and the custom
+script is available. Note that you don't need to set ``--app``. ::
+
+ $ pip install -e .
+ $ wiki run
+
+.. admonition:: Errors in Custom Scripts
+
+ When using a custom script, if you introduce an error in your
+ module-level code, the reloader will fail because it can no longer
+ load the entry point.
+
+ The ``flask`` command, being separate from your code, does not have
+ this issue and is recommended in most cases.
+
+.. _console script: https://packaging.python.org/tutorials/packaging-projects/#console-scripts
+
+
+PyCharm Integration
+-------------------
+
+PyCharm Professional provides a special Flask run configuration to run the development
+server. For the Community Edition, and for other commands besides ``run``, you need to
+create a custom run configuration. These instructions should be similar for any other
+IDE you use.
+
+In PyCharm, with your project open, click on *Run* from the menu bar and go to *Edit
+Configurations*. You'll see a screen similar to this:
+
+.. image:: _static/pycharm-run-config.png
+ :align: center
+ :class: screenshot
+ :alt: Screenshot of PyCharm run configuration.
+
+Once you create a configuration for the ``flask run``, you can copy and change it to
+call any other command.
+
+Click the *+ (Add New Configuration)* button and select *Python*. Give the configuration
+a name such as "flask run".
+
+Click the *Script path* dropdown and change it to *Module name*, then input ``flask``.
+
+The *Parameters* field is set to the CLI command to execute along with any arguments.
+This example uses ``--app hello run --debug``, which will run the development server in
+debug mode. ``--app hello`` should be the import or file with your Flask app.
+
+If you installed your project as a package in your virtualenv, you may uncheck the
+*PYTHONPATH* options. This will more accurately match how you deploy later.
+
+Click *OK* to save and close the configuration. Select the configuration in the main
+PyCharm window and click the play button next to it to run the server.
+
+Now that you have a configuration for ``flask run``, you can copy that configuration and
+change the *Parameters* argument to run a different CLI command.
diff --git a/src/flask-main/docs/conf.py b/src/flask-main/docs/conf.py
new file mode 100644
index 0000000..af8adf0
--- /dev/null
+++ b/src/flask-main/docs/conf.py
@@ -0,0 +1,101 @@
+import packaging.version
+from pallets_sphinx_themes import get_version
+from pallets_sphinx_themes import ProjectLink
+
+# Project --------------------------------------------------------------
+
+project = "Flask"
+copyright = "2010 Pallets"
+author = "Pallets"
+release, version = get_version("Flask")
+
+# General --------------------------------------------------------------
+
+default_role = "code"
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.extlinks",
+ "sphinx.ext.intersphinx",
+ "sphinxcontrib.log_cabinet",
+ "sphinx_tabs.tabs",
+ "pallets_sphinx_themes",
+]
+autodoc_member_order = "bysource"
+autodoc_typehints = "description"
+autodoc_preserve_defaults = True
+extlinks = {
+ "issue": ("https://github.com/pallets/flask/issues/%s", "#%s"),
+ "pr": ("https://github.com/pallets/flask/pull/%s", "#%s"),
+ "ghsa": ("https://github.com/pallets/flask/security/advisories/GHSA-%s", "GHSA-%s"),
+}
+intersphinx_mapping = {
+ "python": ("https://docs.python.org/3/", None),
+ "werkzeug": ("https://werkzeug.palletsprojects.com/", None),
+ "click": ("https://click.palletsprojects.com/", None),
+ "jinja": ("https://jinja.palletsprojects.com/", None),
+ "itsdangerous": ("https://itsdangerous.palletsprojects.com/", None),
+ "sqlalchemy": ("https://docs.sqlalchemy.org/", None),
+ "wtforms": ("https://wtforms.readthedocs.io/", None),
+ "blinker": ("https://blinker.readthedocs.io/", None),
+}
+
+# HTML -----------------------------------------------------------------
+
+html_theme = "flask"
+html_theme_options = {"index_sidebar_logo": False}
+html_context = {
+ "project_links": [
+ ProjectLink("Donate", "https://palletsprojects.com/donate"),
+ ProjectLink("PyPI Releases", "https://pypi.org/project/Flask/"),
+ ProjectLink("Source Code", "https://github.com/pallets/flask/"),
+ ProjectLink("Issue Tracker", "https://github.com/pallets/flask/issues/"),
+ ProjectLink("Chat", "https://discord.gg/pallets"),
+ ]
+}
+html_sidebars = {
+ "index": ["project.html", "localtoc.html", "searchbox.html", "ethicalads.html"],
+ "**": ["localtoc.html", "relations.html", "searchbox.html", "ethicalads.html"],
+}
+singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]}
+html_static_path = ["_static"]
+html_favicon = "_static/flask-icon.svg"
+html_logo = "_static/flask-logo.svg"
+html_title = f"Flask Documentation ({version})"
+html_show_sourcelink = False
+
+gettext_uuid = True
+gettext_compact = False
+
+# Local Extensions -----------------------------------------------------
+
+
+def github_link(name, rawtext, text, lineno, inliner, options=None, content=None):
+ app = inliner.document.settings.env.app
+ release = app.config.release
+ base_url = "https://github.com/pallets/flask/tree/"
+
+ if text.endswith(">"):
+ words, text = text[:-1].rsplit("<", 1)
+ words = words.strip()
+ else:
+ words = None
+
+ if packaging.version.parse(release).is_devrelease:
+ url = f"{base_url}main/{text}"
+ else:
+ url = f"{base_url}{release}/{text}"
+
+ if words is None:
+ words = url
+
+ from docutils.nodes import reference
+ from docutils.parsers.rst.roles import set_classes
+
+ options = options or {}
+ set_classes(options)
+ node = reference(rawtext, words, refuri=url, **options)
+ return [node], []
+
+
+def setup(app):
+ app.add_role("gh", github_link)
diff --git a/src/flask-main/docs/config.rst b/src/flask-main/docs/config.rst
new file mode 100644
index 0000000..e7d4410
--- /dev/null
+++ b/src/flask-main/docs/config.rst
@@ -0,0 +1,839 @@
+Configuration Handling
+======================
+
+Applications need some kind of configuration. There are different settings
+you might want to change depending on the application environment like
+toggling the debug mode, setting the secret key, and other such
+environment-specific things.
+
+The way Flask is designed usually requires the configuration to be
+available when the application starts up. You can hard code the
+configuration in the code, which for many small applications is not
+actually that bad, but there are better ways.
+
+Independent of how you load your config, there is a config object
+available which holds the loaded configuration values:
+The :attr:`~flask.Flask.config` attribute of the :class:`~flask.Flask`
+object. This is the place where Flask itself puts certain configuration
+values and also where extensions can put their configuration values. But
+this is also where you can have your own configuration.
+
+
+Configuration Basics
+--------------------
+
+The :attr:`~flask.Flask.config` is actually a subclass of a dictionary and
+can be modified just like any dictionary::
+
+ app = Flask(__name__)
+ app.config['TESTING'] = True
+
+Certain configuration values are also forwarded to the
+:attr:`~flask.Flask` object so you can read and write them from there::
+
+ app.testing = True
+
+To update multiple keys at once you can use the :meth:`dict.update`
+method::
+
+ app.config.update(
+ TESTING=True,
+ SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
+ )
+
+
+Debug Mode
+----------
+
+The :data:`DEBUG` config value is special because it may behave inconsistently if
+changed after the app has begun setting up. In order to set debug mode reliably, use the
+``--debug`` option on the ``flask`` or ``flask run`` command. ``flask run`` will use the
+interactive debugger and reloader by default in debug mode.
+
+.. code-block:: text
+
+ $ flask --app hello run --debug
+
+Using the option is recommended. While it is possible to set :data:`DEBUG` in your
+config or code, this is strongly discouraged. It can't be read early by the
+``flask run`` command, and some systems or extensions may have already configured
+themselves based on a previous value.
+
+
+Builtin Configuration Values
+----------------------------
+
+The following configuration values are used internally by Flask:
+
+.. py:data:: DEBUG
+
+ Whether debug mode is enabled. When using ``flask run`` to start the development
+ server, an interactive debugger will be shown for unhandled exceptions, and the
+ server will be reloaded when code changes. The :attr:`~flask.Flask.debug` attribute
+ maps to this config key. This is set with the ``FLASK_DEBUG`` environment variable.
+ It may not behave as expected if set in code.
+
+ **Do not enable debug mode when deploying in production.**
+
+ Default: ``False``
+
+.. py:data:: TESTING
+
+ Enable testing mode. Exceptions are propagated rather than handled by the
+ the app's error handlers. Extensions may also change their behavior to
+ facilitate easier testing. You should enable this in your own tests.
+
+ Default: ``False``
+
+.. py:data:: PROPAGATE_EXCEPTIONS
+
+ Exceptions are re-raised rather than being handled by the app's error
+ handlers. If not set, this is implicitly true if ``TESTING`` or ``DEBUG``
+ is enabled.
+
+ Default: ``None``
+
+.. py:data:: TRAP_HTTP_EXCEPTIONS
+
+ If there is no handler for an ``HTTPException``-type exception, re-raise it
+ to be handled by the interactive debugger instead of returning it as a
+ simple error response.
+
+ Default: ``False``
+
+.. py:data:: TRAP_BAD_REQUEST_ERRORS
+
+ Trying to access a key that doesn't exist from request dicts like ``args``
+ and ``form`` will return a 400 Bad Request error page. Enable this to treat
+ the error as an unhandled exception instead so that you get the interactive
+ debugger. This is a more specific version of ``TRAP_HTTP_EXCEPTIONS``. If
+ unset, it is enabled in debug mode.
+
+ Default: ``None``
+
+.. py:data:: SECRET_KEY
+
+ A secret key that will be used for securely signing the session cookie
+ and can be used for any other security related needs by extensions or your
+ application. It should be a long random ``bytes`` or ``str``. For
+ example, copy the output of this to your config::
+
+ $ python -c 'import secrets; print(secrets.token_hex())'
+ '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
+
+ **Do not reveal the secret key when posting questions or committing code.**
+
+ Default: ``None``
+
+.. py:data:: SECRET_KEY_FALLBACKS
+
+ A list of old secret keys that can still be used for unsigning. This allows
+ a project to implement key rotation without invalidating active sessions or
+ other recently-signed secrets.
+
+ Keys should be removed after an appropriate period of time, as checking each
+ additional key adds some overhead.
+
+ Order should not matter, but the default implementation will test the last
+ key in the list first, so it might make sense to order oldest to newest.
+
+ Flask's built-in secure cookie session supports this. Extensions that use
+ :data:`SECRET_KEY` may not support this yet.
+
+ Default: ``None``
+
+ .. versionadded:: 3.1
+
+.. py:data:: SESSION_COOKIE_NAME
+
+ The name of the session cookie. Can be changed in case you already have a
+ cookie with the same name.
+
+ Default: ``'session'``
+
+.. py:data:: SESSION_COOKIE_DOMAIN
+
+ The value of the ``Domain`` parameter on the session cookie. If not set, browsers
+ will only send the cookie to the exact domain it was set from. Otherwise, they
+ will send it to any subdomain of the given value as well.
+
+ Not setting this value is more restricted and secure than setting it.
+
+ Default: ``None``
+
+ .. warning::
+ If this is changed after the browser created a cookie is created with
+ one setting, it may result in another being created. Browsers may send
+ send both in an undefined order. In that case, you may want to change
+ :data:`SESSION_COOKIE_NAME` as well or otherwise invalidate old sessions.
+
+ .. versionchanged:: 2.3
+ Not set by default, does not fall back to ``SERVER_NAME``.
+
+.. py:data:: SESSION_COOKIE_PATH
+
+ The path that the session cookie will be valid for. If not set, the cookie
+ will be valid underneath ``APPLICATION_ROOT`` or ``/`` if that is not set.
+
+ Default: ``None``
+
+.. py:data:: SESSION_COOKIE_HTTPONLY
+
+ Browsers will not allow JavaScript access to cookies marked as "HTTP only"
+ for security.
+
+ Default: ``True``
+
+.. py:data:: SESSION_COOKIE_SECURE
+
+ Browsers will only send cookies with requests over HTTPS if the cookie is
+ marked "secure". The application must be served over HTTPS for this to make
+ sense.
+
+ Default: ``False``
+
+.. py:data:: SESSION_COOKIE_PARTITIONED
+
+ Browsers will send cookies based on the top-level document's domain, rather
+ than only the domain of the document setting the cookie. This prevents third
+ party cookies set in iframes from "leaking" between separate sites.
+
+ Browsers are beginning to disallow non-partitioned third party cookies, so
+ you need to mark your cookies partitioned if you expect them to work in such
+ embedded situations.
+
+ Enabling this implicitly enables :data:`SESSION_COOKIE_SECURE` as well, as
+ it is only valid when served over HTTPS.
+
+ Default: ``False``
+
+ .. versionadded:: 3.1
+
+.. py:data:: SESSION_COOKIE_SAMESITE
+
+ Restrict how cookies are sent with requests from external sites. Can
+ be set to ``'Lax'`` (recommended) or ``'Strict'``.
+ See :ref:`security-cookie`.
+
+ Default: ``None``
+
+ .. versionadded:: 1.0
+
+.. py:data:: PERMANENT_SESSION_LIFETIME
+
+ If ``session.permanent`` is true, the cookie's expiration will be set this
+ number of seconds in the future. Can either be a
+ :class:`datetime.timedelta` or an ``int``.
+
+ Flask's default cookie implementation validates that the cryptographic
+ signature is not older than this value.
+
+ Default: ``timedelta(days=31)`` (``2678400`` seconds)
+
+.. py:data:: SESSION_REFRESH_EACH_REQUEST
+
+ Control whether the cookie is sent with every response when
+ ``session.permanent`` is true. Sending the cookie every time (the default)
+ can more reliably keep the session from expiring, but uses more bandwidth.
+ Non-permanent sessions are not affected.
+
+ Default: ``True``
+
+.. py:data:: USE_X_SENDFILE
+
+ When serving files, set the ``X-Sendfile`` header instead of serving the
+ data with Flask. Some web servers, such as Apache, recognize this and serve
+ the data more efficiently. This only makes sense when using such a server.
+
+ Default: ``False``
+
+.. py:data:: SEND_FILE_MAX_AGE_DEFAULT
+
+ When serving files, set the cache control max age to this number of
+ seconds. Can be a :class:`datetime.timedelta` or an ``int``.
+ Override this value on a per-file basis using
+ :meth:`~flask.Flask.get_send_file_max_age` on the application or
+ blueprint.
+
+ If ``None``, ``send_file`` tells the browser to use conditional
+ requests will be used instead of a timed cache, which is usually
+ preferable.
+
+ Default: ``None``
+
+.. py:data:: TRUSTED_HOSTS
+
+ Validate :attr:`.Request.host` and other attributes that use it against
+ these trusted values. Raise a :exc:`~werkzeug.exceptions.SecurityError` if
+ the host is invalid, which results in a 400 error. If it is ``None``, all
+ hosts are valid. Each value is either an exact match, or can start with
+ a dot ``.`` to match any subdomain.
+
+ Validation is done during routing against this value. ``before_request`` and
+ ``after_request`` callbacks will still be called.
+
+ Default: ``None``
+
+ .. versionadded:: 3.1
+
+.. py:data:: SERVER_NAME
+
+ Inform the application what host and port it is bound to.
+
+ Must be set if ``subdomain_matching`` is enabled, to be able to extract the
+ subdomain from the request.
+
+ Must be set for ``url_for`` to generate external URLs outside of a
+ request context.
+
+ Default: ``None``
+
+ .. versionchanged:: 3.1
+ Does not restrict requests to only this domain, for both
+ ``subdomain_matching`` and ``host_matching``.
+
+ .. versionchanged:: 1.0
+ Does not implicitly enable ``subdomain_matching``.
+
+ .. versionchanged:: 2.3
+ Does not affect ``SESSION_COOKIE_DOMAIN``.
+
+.. py:data:: APPLICATION_ROOT
+
+ Inform the application what path it is mounted under by the application /
+ web server. This is used for generating URLs outside the context of a
+ request (inside a request, the dispatcher is responsible for setting
+ ``SCRIPT_NAME`` instead; see :doc:`/patterns/appdispatch`
+ for examples of dispatch configuration).
+
+ Will be used for the session cookie path if ``SESSION_COOKIE_PATH`` is not
+ set.
+
+ Default: ``'/'``
+
+.. py:data:: PREFERRED_URL_SCHEME
+
+ Use this scheme for generating external URLs when not in a request context.
+
+ Default: ``'http'``
+
+.. py:data:: MAX_CONTENT_LENGTH
+
+ The maximum number of bytes that will be read during this request. If
+ this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge`
+ error is raised. If it is set to ``None``, no limit is enforced at the
+ Flask application level. However, if it is ``None`` and the request has no
+ ``Content-Length`` header and the WSGI server does not indicate that it
+ terminates the stream, then no data is read to avoid an infinite stream.
+
+ Each request defaults to this config. It can be set on a specific
+ :attr:`.Request.max_content_length` to apply the limit to that specific
+ view. This should be set appropriately based on an application's or view's
+ specific needs.
+
+ Default: ``None``
+
+ .. versionadded:: 0.6
+
+.. py:data:: MAX_FORM_MEMORY_SIZE
+
+ The maximum size in bytes any non-file form field may be in a
+ ``multipart/form-data`` body. If this limit is exceeded, a 413
+ :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it is
+ set to ``None``, no limit is enforced at the Flask application level.
+
+ Each request defaults to this config. It can be set on a specific
+ :attr:`.Request.max_form_memory_parts` to apply the limit to that specific
+ view. This should be set appropriately based on an application's or view's
+ specific needs.
+
+ Default: ``500_000``
+
+ .. versionadded:: 3.1
+
+.. py:data:: MAX_FORM_PARTS
+
+ The maximum number of fields that may be present in a
+ ``multipart/form-data`` body. If this limit is exceeded, a 413
+ :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it
+ is set to ``None``, no limit is enforced at the Flask application level.
+
+ Each request defaults to this config. It can be set on a specific
+ :attr:`.Request.max_form_parts` to apply the limit to that specific view.
+ This should be set appropriately based on an application's or view's
+ specific needs.
+
+ Default: ``1_000``
+
+ .. versionadded:: 3.1
+
+.. py:data:: TEMPLATES_AUTO_RELOAD
+
+ Reload templates when they are changed. If not set, it will be enabled in
+ debug mode.
+
+ Default: ``None``
+
+.. py:data:: EXPLAIN_TEMPLATE_LOADING
+
+ Log debugging information tracing how a template file was loaded. This can
+ be useful to figure out why a template was not loaded or the wrong file
+ appears to be loaded.
+
+ Default: ``False``
+
+.. py:data:: MAX_COOKIE_SIZE
+
+ Warn if cookie headers are larger than this many bytes. Defaults to
+ ``4093``. Larger cookies may be silently ignored by browsers. Set to
+ ``0`` to disable the warning.
+
+.. py:data:: PROVIDE_AUTOMATIC_OPTIONS
+
+ Set to ``False`` to disable the automatic addition of OPTIONS
+ responses. This can be overridden per route by altering the
+ ``provide_automatic_options`` attribute.
+
+.. versionadded:: 0.4
+ ``LOGGER_NAME``
+
+.. versionadded:: 0.5
+ ``SERVER_NAME``
+
+.. versionadded:: 0.6
+ ``MAX_CONTENT_LENGTH``
+
+.. versionadded:: 0.7
+ ``PROPAGATE_EXCEPTIONS``, ``PRESERVE_CONTEXT_ON_EXCEPTION``
+
+.. versionadded:: 0.8
+ ``TRAP_BAD_REQUEST_ERRORS``, ``TRAP_HTTP_EXCEPTIONS``,
+ ``APPLICATION_ROOT``, ``SESSION_COOKIE_DOMAIN``,
+ ``SESSION_COOKIE_PATH``, ``SESSION_COOKIE_HTTPONLY``,
+ ``SESSION_COOKIE_SECURE``
+
+.. versionadded:: 0.9
+ ``PREFERRED_URL_SCHEME``
+
+.. versionadded:: 0.10
+ ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_PRETTYPRINT_REGULAR``
+
+.. versionadded:: 0.11
+ ``SESSION_REFRESH_EACH_REQUEST``, ``TEMPLATES_AUTO_RELOAD``,
+ ``LOGGER_HANDLER_POLICY``, ``EXPLAIN_TEMPLATE_LOADING``
+
+.. versionchanged:: 1.0
+ ``LOGGER_NAME`` and ``LOGGER_HANDLER_POLICY`` were removed. See
+ :doc:`/logging` for information about configuration.
+
+ Added :data:`ENV` to reflect the :envvar:`FLASK_ENV` environment
+ variable.
+
+ Added :data:`SESSION_COOKIE_SAMESITE` to control the session
+ cookie's ``SameSite`` option.
+
+ Added :data:`MAX_COOKIE_SIZE` to control a warning from Werkzeug.
+
+.. versionchanged:: 2.2
+ Removed ``PRESERVE_CONTEXT_ON_EXCEPTION``.
+
+.. versionchanged:: 2.3
+ ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_MIMETYPE``, and
+ ``JSONIFY_PRETTYPRINT_REGULAR`` were removed. The default ``app.json`` provider has
+ equivalent attributes instead.
+
+.. versionchanged:: 2.3
+ ``ENV`` was removed.
+
+.. versionadded:: 3.10
+ Added :data:`PROVIDE_AUTOMATIC_OPTIONS` to control the default
+ addition of autogenerated OPTIONS responses.
+
+
+Configuring from Python Files
+-----------------------------
+
+Configuration becomes more useful if you can store it in a separate file, ideally
+located outside the actual application package. You can deploy your application, then
+separately configure it for the specific deployment.
+
+A common pattern is this::
+
+ app = Flask(__name__)
+ app.config.from_object('yourapplication.default_settings')
+ app.config.from_envvar('YOURAPPLICATION_SETTINGS')
+
+This first loads the configuration from the
+`yourapplication.default_settings` module and then overrides the values
+with the contents of the file the :envvar:`YOURAPPLICATION_SETTINGS`
+environment variable points to. This environment variable can be set
+in the shell before starting the server:
+
+.. tabs::
+
+ .. group-tab:: Bash
+
+ .. code-block:: text
+
+ $ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
+ $ flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: Fish
+
+ .. code-block:: text
+
+ $ set -x YOURAPPLICATION_SETTINGS /path/to/settings.cfg
+ $ flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: CMD
+
+ .. code-block:: text
+
+ > set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
+ > flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: Powershell
+
+ .. code-block:: text
+
+ > $env:YOURAPPLICATION_SETTINGS = "\path\to\settings.cfg"
+ > flask run
+ * Running on http://127.0.0.1:5000/
+
+The configuration files themselves are actual Python files. Only values
+in uppercase are actually stored in the config object later on. So make
+sure to use uppercase letters for your config keys.
+
+Here is an example of a configuration file::
+
+ # Example configuration
+ SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
+
+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` object's
+documentation.
+
+
+Configuring from Data Files
+---------------------------
+
+It is also possible to load configuration from a file in a format of
+your choice using :meth:`~flask.Config.from_file`. For example to load
+from a TOML file:
+
+.. code-block:: python
+
+ import tomllib
+ app.config.from_file("config.toml", load=tomllib.load, text=False)
+
+Or from a JSON file:
+
+.. code-block:: python
+
+ import json
+ app.config.from_file("config.json", load=json.load)
+
+
+Configuring from Environment Variables
+--------------------------------------
+
+In addition to pointing to configuration files using environment
+variables, you may find it useful (or necessary) to control your
+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:
+
+.. tabs::
+
+ .. group-tab:: Bash
+
+ .. code-block:: text
+
+ $ export FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
+ $ export FLASK_MAIL_ENABLED=false
+ $ flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: Fish
+
+ .. code-block:: text
+
+ $ set -x FLASK_SECRET_KEY "5f352379324c22463451387a0aec5d2f"
+ $ set -x FLASK_MAIL_ENABLED false
+ $ flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: CMD
+
+ .. code-block:: text
+
+ > set FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
+ > set FLASK_MAIL_ENABLED=false
+ > flask run
+ * Running on http://127.0.0.1:5000/
+
+ .. group-tab:: Powershell
+
+ .. code-block:: text
+
+ > $env:FLASK_SECRET_KEY = "5f352379324c22463451387a0aec5d2f"
+ > $env:FLASK_MAIL_ENABLED = "false"
+ > 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.
+
+.. code-block:: python
+
+ app.config.from_prefixed_env()
+ app.config["SECRET_KEY"] # Is "5f352379324c22463451387a0aec5d2f"
+
+The prefix is ``FLASK_`` by default. This is configurable via the
+``prefix`` 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`.
+
+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.
+
+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"
+
+On Windows, environment variable keys are always uppercase, therefore
+the above example would end up as ``MYAPI__CREDENTIALS__USERNAME``.
+
+For even more config loading features, including merging and
+case-insensitive Windows support, try a dedicated library such as
+Dynaconf_, which includes integration with Flask.
+
+.. _Dynaconf: https://www.dynaconf.com/
+
+
+Configuration Best Practices
+----------------------------
+
+The downside with the approach mentioned earlier is that it makes testing
+a little harder. There is no single 100% solution for this problem in
+general, but there are a couple of things you can keep in mind to improve
+that experience:
+
+1. Create your application in a function and register blueprints on it.
+ That way you can create multiple instances of your application with
+ different configurations attached which makes unit testing a lot
+ easier. You can use this to pass in configuration as needed.
+
+2. Do not write code that needs the configuration at import time. If you
+ 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
+------------------------
+
+Most applications need more than one configuration. There should be at
+least separate configurations for the production server and the one used
+during development. The easiest way to handle this is to use a default
+configuration that is always loaded and part of the version control, and a
+separate configuration that overrides the values as necessary as mentioned
+in the example above::
+
+ app = Flask(__name__)
+ app.config.from_object('yourapplication.default_settings')
+ app.config.from_envvar('YOURAPPLICATION_SETTINGS')
+
+Then you just have to add a separate :file:`config.py` file and export
+``YOURAPPLICATION_SETTINGS=/path/to/config.py`` and you are done. However
+there are alternative ways as well. For example you could use imports or
+subclassing.
+
+What is very popular in the Django world is to make the import explicit in
+the config file by adding ``from yourapplication.default_settings
+import *`` to the top of the file and then overriding the changes by hand.
+You could also inspect an environment variable like
+``YOURAPPLICATION_MODE`` and set that to `production`, `development` etc
+and import different hard-coded files based on that.
+
+An interesting pattern is also to use classes and inheritance for
+configuration::
+
+ class Config(object):
+ TESTING = False
+
+ class ProductionConfig(Config):
+ DATABASE_URI = 'mysql://user@localhost/foo'
+
+ class DevelopmentConfig(Config):
+ DATABASE_URI = "sqlite:////tmp/foo.db"
+
+ class TestingConfig(Config):
+ DATABASE_URI = 'sqlite:///:memory:'
+ TESTING = True
+
+To enable such a config you just have to call into
+:meth:`~flask.Config.from_object`::
+
+ app.config.from_object('configmodule.ProductionConfig')
+
+Note that :meth:`~flask.Config.from_object` does not instantiate the class
+object. If you need to instantiate the class, such as to access a property,
+then you must do so before calling :meth:`~flask.Config.from_object`::
+
+ from configmodule import ProductionConfig
+ app.config.from_object(ProductionConfig())
+
+ # Alternatively, import via string:
+ from werkzeug.utils import import_string
+ cfg = import_string('configmodule.ProductionConfig')()
+ app.config.from_object(cfg)
+
+Instantiating the configuration object allows you to use ``@property`` in
+your configuration classes::
+
+ class Config(object):
+ """Base config, uses staging database server."""
+ TESTING = False
+ DB_SERVER = '192.168.1.56'
+
+ @property
+ def DATABASE_URI(self): # Note: all caps
+ return f"mysql://user@{self.DB_SERVER}/foo"
+
+ class ProductionConfig(Config):
+ """Uses production database server."""
+ DB_SERVER = '192.168.19.32'
+
+ class DevelopmentConfig(Config):
+ DB_SERVER = 'localhost'
+
+ class TestingConfig(Config):
+ DB_SERVER = 'localhost'
+ DATABASE_URI = 'sqlite:///:memory:'
+
+There are many different ways and it's up to you how you want to manage
+your configuration files. However here a list of good recommendations:
+
+- Keep a default configuration in version control. Either populate the
+ config with this default configuration or import it in your own
+ configuration files before overriding values.
+- Use an environment variable to switch between the configurations.
+ This can be done from outside the Python interpreter and makes
+ development and deployment much easier because you can quickly and
+ easily switch between different configs without having to touch the
+ code at all. If you are working often on different projects you can
+ even create your own script for sourcing that activates a virtualenv
+ and exports the development configuration for you.
+- Use a tool like `fabric`_ to push code and configuration separately
+ to the production server(s).
+
+.. _fabric: https://www.fabfile.org/
+
+
+.. _instance-folders:
+
+Instance Folders
+----------------
+
+.. versionadded:: 0.8
+
+Flask 0.8 introduces instance folders. Flask for a long time made it
+possible to refer to paths relative to the application's folder directly
+(via :attr:`Flask.root_path`). This was also how many developers loaded
+configurations stored next to the application. Unfortunately however this
+only works well if applications are not packages in which case the root
+path refers to the contents of the package.
+
+With Flask 0.8 a new attribute was introduced:
+:attr:`Flask.instance_path`. It refers to a new concept called the
+“instance folder”. The instance folder is designed to not be under
+version control and be deployment specific. It's the perfect place to
+drop things that either change at runtime or configuration files.
+
+You can either explicitly provide the path of the instance folder when
+creating the Flask application or you can let Flask autodetect the
+instance folder. For explicit configuration use the `instance_path`
+parameter::
+
+ app = Flask(__name__, instance_path='/path/to/instance/folder')
+
+Please keep in mind that this path *must* be absolute when provided.
+
+If the `instance_path` parameter is not provided the following default
+locations are used:
+
+- Uninstalled module::
+
+ /myapp.py
+ /instance
+
+- Uninstalled package::
+
+ /myapp
+ /__init__.py
+ /instance
+
+- Installed module or package::
+
+ $PREFIX/lib/pythonX.Y/site-packages/myapp
+ $PREFIX/var/myapp-instance
+
+ ``$PREFIX`` is the prefix of your Python installation. This can be
+ ``/usr`` or the path to your virtualenv. You can print the value of
+ ``sys.prefix`` to see what the prefix is set to.
+
+Since the config object provided loading of configuration files from
+relative filenames we made it possible to change the loading via filenames
+to be relative to the instance path if wanted. The behavior of relative
+paths in config files can be flipped between “relative to the application
+root” (the default) to “relative to instance folder” via the
+`instance_relative_config` switch to the application constructor::
+
+ app = Flask(__name__, instance_relative_config=True)
+
+Here is a full example of how to configure Flask to preload the config
+from a module and then override the config from a file in the instance
+folder if it exists::
+
+ app = Flask(__name__, instance_relative_config=True)
+ app.config.from_object('yourapplication.default_settings')
+ app.config.from_pyfile('application.cfg', silent=True)
+
+The path to the instance folder can be found via the
+:attr:`Flask.instance_path`. Flask also provides a shortcut to open a
+file from the instance folder with :meth:`Flask.open_instance_resource`.
+
+Example usage for both::
+
+ filename = os.path.join(app.instance_path, 'application.cfg')
+ with open(filename) as f:
+ config = f.read()
+
+ # or via open_instance_resource:
+ with app.open_instance_resource('application.cfg') as f:
+ config = f.read()
diff --git a/src/flask-main/docs/contributing.rst b/src/flask-main/docs/contributing.rst
new file mode 100644
index 0000000..ca4b3ae
--- /dev/null
+++ b/src/flask-main/docs/contributing.rst
@@ -0,0 +1,8 @@
+Contributing
+============
+
+See the Pallets `detailed contributing documentation `_ for many ways
+to contribute, including reporting issues, requesting features, asking or
+answering questions, and making PRs.
+
+.. _contrib: https://palletsprojects.com/contributing/
diff --git a/src/flask-main/docs/debugging.rst b/src/flask-main/docs/debugging.rst
new file mode 100644
index 0000000..f6b56ca
--- /dev/null
+++ b/src/flask-main/docs/debugging.rst
@@ -0,0 +1,99 @@
+Debugging Application Errors
+============================
+
+
+In Production
+-------------
+
+**Do not run the development server, or enable the built-in debugger, in
+a production environment.** The debugger allows executing arbitrary
+Python code from the browser. It's protected by a pin, but that should
+not be relied on for security.
+
+Use an error logging tool, such as Sentry, as described in
+:ref:`error-logging-tools`, or enable logging and notifications as
+described in :doc:`/logging`.
+
+If you have access to the server, you could add some code to start an
+external debugger if ``request.remote_addr`` matches your IP. Some IDE
+debuggers also have a remote mode so breakpoints on the server can be
+interacted with locally. Only enable a debugger temporarily.
+
+
+The Built-In Debugger
+---------------------
+
+The built-in Werkzeug development server provides a debugger which shows
+an interactive traceback in the browser when an unhandled error occurs
+during a request. This debugger should only be used during development.
+
+.. image:: _static/debugger.png
+ :align: center
+ :class: screenshot
+ :alt: screenshot of debugger in action
+
+.. warning::
+
+ The debugger allows executing arbitrary Python code from the
+ browser. It is protected by a pin, but still represents a major
+ security risk. Do not run the development server or debugger in a
+ production environment.
+
+The debugger is enabled by default when the development server is run in debug mode.
+
+.. code-block:: text
+
+ $ flask --app hello run --debug
+
+When running from Python code, passing ``debug=True`` enables debug mode, which is
+mostly equivalent.
+
+.. code-block:: python
+
+ app.run(debug=True)
+
+:doc:`/server` and :doc:`/cli` have more information about running the debugger and
+debug mode. More information about the debugger can be found in the `Werkzeug
+documentation `__.
+
+
+External Debuggers
+------------------
+
+External debuggers, such as those provided by IDEs, can offer a more
+powerful debugging experience than the built-in debugger. They can also
+be used to step through code during a request before an error is raised,
+or if no error is raised. Some even have a remote mode so you can debug
+code running on another machine.
+
+When using an external debugger, the app should still be in debug mode, otherwise Flask
+turns unhandled errors into generic 500 error pages. However, the built-in debugger and
+reloader should be disabled so they don't interfere with the external debugger.
+
+.. code-block:: text
+
+ $ flask --app hello run --debug --no-debugger --no-reload
+
+When running from Python:
+
+.. code-block:: python
+
+ app.run(debug=True, use_debugger=False, use_reloader=False)
+
+Disabling these isn't required, an external debugger will continue to work with the
+following caveats.
+
+- If the built-in debugger is not disabled, it will catch unhandled exceptions before
+ the external debugger can.
+- If the reloader is not disabled, it could cause an unexpected reload if code changes
+ during a breakpoint.
+- The development server will still catch unhandled exceptions if the built-in
+ debugger is disabled, otherwise it would crash on any error. If you want that (and
+ usually you don't) pass ``passthrough_errors=True`` to ``app.run``.
+
+ .. code-block:: python
+
+ app.run(
+ debug=True, passthrough_errors=True,
+ use_debugger=False, use_reloader=False
+ )
diff --git a/src/flask-main/docs/deploying/apache-httpd.rst b/src/flask-main/docs/deploying/apache-httpd.rst
new file mode 100644
index 0000000..bdeaf62
--- /dev/null
+++ b/src/flask-main/docs/deploying/apache-httpd.rst
@@ -0,0 +1,66 @@
+Apache httpd
+============
+
+`Apache httpd`_ is a fast, production level HTTP server. When serving
+your application with one of the WSGI servers listed in :doc:`index`, it
+is often good or necessary to put a dedicated HTTP server in front of
+it. This "reverse proxy" can handle incoming requests, TLS, and other
+security and performance concerns better than the WSGI server.
+
+httpd can be installed using your system package manager, or a pre-built
+executable for Windows. Installing and running httpd itself is outside
+the scope of this doc. This page outlines the basics of configuring
+httpd to proxy your application. Be sure to read its documentation to
+understand what features are available.
+
+.. _Apache httpd: https://httpd.apache.org/
+
+
+Domain Name
+-----------
+
+Acquiring and configuring a domain name is outside the scope of this
+doc. In general, you will buy a domain name from a registrar, pay for
+server space with a hosting provider, and then point your registrar
+at the hosting provider's name servers.
+
+To simulate this, you can also edit your ``hosts`` file, located at
+``/etc/hosts`` on Linux. Add a line that associates a name with the
+local IP.
+
+Modern Linux systems may be configured to treat any domain name that
+ends with ``.localhost`` like this without adding it to the ``hosts``
+file.
+
+.. code-block:: python
+ :caption: ``/etc/hosts``
+
+ 127.0.0.1 hello.localhost
+
+
+Configuration
+-------------
+
+The httpd configuration is located at ``/etc/httpd/conf/httpd.conf`` on
+Linux. It may be different depending on your operating system. Check the
+docs and look for ``httpd.conf``.
+
+Remove or comment out any existing ``DocumentRoot`` directive. Add the
+config lines below. We'll assume the WSGI server is listening locally at
+``http://127.0.0.1:8000``.
+
+.. code-block:: apache
+ :caption: ``/etc/httpd/conf/httpd.conf``
+
+ LoadModule proxy_module modules/mod_proxy.so
+ LoadModule proxy_http_module modules/mod_proxy_http.so
+ ProxyPass / http://127.0.0.1:8000/
+ RequestHeader set X-Forwarded-Proto http
+ RequestHeader set X-Forwarded-Prefix /
+
+The ``LoadModule`` lines might already exist. If so, make sure they are
+uncommented instead of adding them manually.
+
+Then :doc:`proxy_fix` so that your application uses the ``X-Forwarded``
+headers. ``X-Forwarded-For`` and ``X-Forwarded-Host`` are automatically
+set by ``ProxyPass``.
diff --git a/src/flask-main/docs/deploying/asgi.rst b/src/flask-main/docs/deploying/asgi.rst
new file mode 100644
index 0000000..1dc0aa2
--- /dev/null
+++ b/src/flask-main/docs/deploying/asgi.rst
@@ -0,0 +1,27 @@
+ASGI
+====
+
+If you'd like to use an ASGI server you will need to utilise WSGI to
+ASGI middleware. The asgiref
+`WsgiToAsgi `_
+adapter is recommended as it integrates with the event loop used for
+Flask's :ref:`async_await` support. You can use the adapter by
+wrapping the Flask app,
+
+.. code-block:: python
+
+ from asgiref.wsgi import WsgiToAsgi
+ from flask import Flask
+
+ app = Flask(__name__)
+
+ ...
+
+ asgi_app = WsgiToAsgi(app)
+
+and then serving the ``asgi_app`` with the ASGI server, e.g. using
+`Hypercorn `_,
+
+.. sourcecode:: text
+
+ $ hypercorn module:asgi_app
diff --git a/src/flask-main/docs/deploying/eventlet.rst b/src/flask-main/docs/deploying/eventlet.rst
new file mode 100644
index 0000000..8a718b2
--- /dev/null
+++ b/src/flask-main/docs/deploying/eventlet.rst
@@ -0,0 +1,80 @@
+eventlet
+========
+
+Prefer using :doc:`gunicorn` with eventlet workers rather than using
+`eventlet`_ directly. Gunicorn provides a much more configurable and
+production-tested server.
+
+`eventlet`_ allows writing asynchronous, coroutine-based code that looks
+like standard synchronous Python. It uses `greenlet`_ to enable task
+switching without writing ``async/await`` or using ``asyncio``.
+
+:doc:`gevent` is another library that does the same thing. Certain
+dependencies you have, or other considerations, may affect which of the
+two you choose to use.
+
+eventlet provides a WSGI server that can handle many connections at once
+instead of one per worker process. You must actually use eventlet in
+your own code to see any benefit to using the server.
+
+.. _eventlet: https://eventlet.net/
+.. _greenlet: https://greenlet.readthedocs.io/en/latest/
+
+
+Installing
+----------
+
+When using eventlet, greenlet>=1.0 is required, otherwise context locals
+such as ``request`` will not work as expected. When using PyPy,
+PyPy>=7.3.7 is required.
+
+Create a virtualenv, install your application, then install
+``eventlet``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install eventlet
+
+
+Running
+-------
+
+To use eventlet to serve your application, write a script that imports
+its ``wsgi.server``, as well as your app or app factory.
+
+.. code-block:: python
+ :caption: ``wsgi.py``
+
+ import eventlet
+ from eventlet import wsgi
+ from hello import create_app
+
+ app = create_app()
+ wsgi.server(eventlet.listen(("127.0.0.1", 8000)), app)
+
+.. code-block:: text
+
+ $ python wsgi.py
+ (x) wsgi starting up on http://127.0.0.1:8000
+
+
+Binding Externally
+------------------
+
+eventlet should not be run as root because it would cause your
+application code to run as root, which is not secure. However, this
+means it will not be possible to bind to port 80 or 443. Instead, a
+reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used
+in front of eventlet.
+
+You can bind to all external IPs on a non-privileged port by using
+``0.0.0.0`` in the server arguments shown in the previous section.
+Don't do this when using a reverse proxy setup, otherwise it will be
+possible to bypass the proxy.
+
+``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
+IP address in your browser.
diff --git a/src/flask-main/docs/deploying/gevent.rst b/src/flask-main/docs/deploying/gevent.rst
new file mode 100644
index 0000000..448b93e
--- /dev/null
+++ b/src/flask-main/docs/deploying/gevent.rst
@@ -0,0 +1,80 @@
+gevent
+======
+
+Prefer using :doc:`gunicorn` or :doc:`uwsgi` with gevent workers rather
+than using `gevent`_ directly. Gunicorn and uWSGI provide much more
+configurable and production-tested servers.
+
+`gevent`_ allows writing asynchronous, coroutine-based code that looks
+like standard synchronous Python. It uses `greenlet`_ to enable task
+switching without writing ``async/await`` or using ``asyncio``.
+
+:doc:`eventlet` is another library that does the same thing. Certain
+dependencies you have, or other considerations, may affect which of the
+two you choose to use.
+
+gevent provides a WSGI server that can handle many connections at once
+instead of one per worker process. You must actually use gevent in your
+own code to see any benefit to using the server.
+
+.. _gevent: https://www.gevent.org/
+.. _greenlet: https://greenlet.readthedocs.io/en/latest/
+
+
+Installing
+----------
+
+When using gevent, greenlet>=1.0 is required, otherwise context locals
+such as ``request`` will not work as expected. When using PyPy,
+PyPy>=7.3.7 is required.
+
+Create a virtualenv, install your application, then install ``gevent``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install gevent
+
+
+Running
+-------
+
+To use gevent to serve your application, write a script that imports its
+``WSGIServer``, as well as your app or app factory.
+
+.. code-block:: python
+ :caption: ``wsgi.py``
+
+ from gevent.pywsgi import WSGIServer
+ from hello import create_app
+
+ app = create_app()
+ http_server = WSGIServer(("127.0.0.1", 8000), app)
+ http_server.serve_forever()
+
+.. code-block:: text
+
+ $ python wsgi.py
+
+No output is shown when the server starts.
+
+
+Binding Externally
+------------------
+
+gevent should not be run as root because it would cause your
+application code to run as root, which is not secure. However, this
+means it will not be possible to bind to port 80 or 443. Instead, a
+reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used
+in front of gevent.
+
+You can bind to all external IPs on a non-privileged port by using
+``0.0.0.0`` in the server arguments shown in the previous section. Don't
+do this when using a reverse proxy setup, otherwise it will be possible
+to bypass the proxy.
+
+``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
+IP address in your browser.
diff --git a/src/flask-main/docs/deploying/gunicorn.rst b/src/flask-main/docs/deploying/gunicorn.rst
new file mode 100644
index 0000000..c50edc2
--- /dev/null
+++ b/src/flask-main/docs/deploying/gunicorn.rst
@@ -0,0 +1,130 @@
+Gunicorn
+========
+
+`Gunicorn`_ is a pure Python WSGI server with simple configuration and
+multiple worker implementations for performance tuning.
+
+* It tends to integrate easily with hosting platforms.
+* It does not support Windows (but does run on WSL).
+* It is easy to install as it does not require additional dependencies
+ or compilation.
+* It has built-in async worker support using gevent or eventlet.
+
+This page outlines the basics of running Gunicorn. Be sure to read its
+`documentation`_ and use ``gunicorn --help`` to understand what features
+are available.
+
+.. _Gunicorn: https://gunicorn.org/
+.. _documentation: https://docs.gunicorn.org/
+
+
+Installing
+----------
+
+Gunicorn is easy to install, as it does not require external
+dependencies or compilation. It runs on Windows only under WSL.
+
+Create a virtualenv, install your application, then install
+``gunicorn``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install gunicorn
+
+
+Running
+-------
+
+The only required argument to Gunicorn tells it how to load your Flask
+application. The syntax is ``{module_import}:{app_variable}``.
+``module_import`` is the dotted import name to the module with your
+application. ``app_variable`` is the variable with the application. It
+can also be a function call (with any arguments) if you're using the
+app factory pattern.
+
+.. code-block:: text
+
+ # equivalent to 'from hello import app'
+ $ gunicorn -w 4 'hello:app'
+
+ # equivalent to 'from hello import create_app; create_app()'
+ $ gunicorn -w 4 'hello:create_app()'
+
+ Starting gunicorn 20.1.0
+ Listening at: http://127.0.0.1:8000 (x)
+ Using worker: sync
+ Booting worker with pid: x
+ Booting worker with pid: x
+ Booting worker with pid: x
+ Booting worker with pid: x
+
+The ``-w`` option specifies the number of processes to run; a starting
+value could be ``CPU * 2``. The default is only 1 worker, which is
+probably not what you want for the default worker type.
+
+Logs for each request aren't shown by default, only worker info and
+errors are shown. To show access logs on stdout, use the
+``--access-logfile=-`` option.
+
+
+Binding Externally
+------------------
+
+Gunicorn should not be run as root because it would cause your
+application code to run as root, which is not secure. However, this
+means it will not be possible to bind to port 80 or 443. Instead, a
+reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used
+in front of Gunicorn.
+
+You can bind to all external IPs on a non-privileged port using the
+``-b 0.0.0.0`` option. Don't do this when using a reverse proxy setup,
+otherwise it will be possible to bypass the proxy.
+
+.. code-block:: text
+
+ $ gunicorn -w 4 -b 0.0.0.0 'hello:create_app()'
+ Listening at: http://0.0.0.0:8000 (x)
+
+``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
+IP address in your browser.
+
+
+Async with gevent or eventlet
+-----------------------------
+
+The default sync worker is appropriate for many use cases. If you need
+asynchronous support, Gunicorn provides workers using either `gevent`_
+or `eventlet`_. This is not the same as Python's ``async/await``, or the
+ASGI server spec. You must actually use gevent/eventlet in your own code
+to see any benefit to using the workers.
+
+When using either gevent or eventlet, greenlet>=1.0 is required,
+otherwise context locals such as ``request`` will not work as expected.
+When using PyPy, PyPy>=7.3.7 is required.
+
+To use gevent:
+
+.. code-block:: text
+
+ $ gunicorn -k gevent 'hello:create_app()'
+ Starting gunicorn 20.1.0
+ Listening at: http://127.0.0.1:8000 (x)
+ Using worker: gevent
+ Booting worker with pid: x
+
+To use eventlet:
+
+.. code-block:: text
+
+ $ gunicorn -k eventlet 'hello:create_app()'
+ Starting gunicorn 20.1.0
+ Listening at: http://127.0.0.1:8000 (x)
+ Using worker: eventlet
+ Booting worker with pid: x
+
+.. _gevent: https://www.gevent.org/
+.. _eventlet: https://eventlet.net/
diff --git a/src/flask-main/docs/deploying/index.rst b/src/flask-main/docs/deploying/index.rst
new file mode 100644
index 0000000..4135596
--- /dev/null
+++ b/src/flask-main/docs/deploying/index.rst
@@ -0,0 +1,79 @@
+Deploying to Production
+=======================
+
+After developing your application, you'll want to make it available
+publicly to other users. When you're developing locally, you're probably
+using the built-in development server, debugger, and reloader. These
+should not be used in production. Instead, you should use a dedicated
+WSGI server or hosting platform, some of which will be described here.
+
+"Production" means "not development", which applies whether you're
+serving your application publicly to millions of users or privately /
+locally to a single user. **Do not use the development server when
+deploying to production. It is intended for use only during local
+development. It is not designed to be particularly secure, stable, or
+efficient.**
+
+Self-Hosted Options
+-------------------
+
+Flask is a WSGI *application*. A WSGI *server* is used to run the
+application, converting incoming HTTP requests to the standard WSGI
+environ, and converting outgoing WSGI responses to HTTP responses.
+
+The primary goal of these docs is to familiarize you with the concepts
+involved in running a WSGI application using a production WSGI server
+and HTTP server. There are many WSGI servers and HTTP servers, with many
+configuration possibilities. The pages below discuss the most common
+servers, and show the basics of running each one. The next section
+discusses platforms that can manage this for you.
+
+.. toctree::
+ :maxdepth: 1
+
+ gunicorn
+ waitress
+ mod_wsgi
+ uwsgi
+ gevent
+ eventlet
+ asgi
+
+WSGI servers have HTTP servers built-in. However, a dedicated HTTP
+server may be safer, more efficient, or more capable. Putting an HTTP
+server in front of the WSGI server is called a "reverse proxy."
+
+.. toctree::
+ :maxdepth: 1
+
+ proxy_fix
+ nginx
+ apache-httpd
+
+This list is not exhaustive, and you should evaluate these and other
+servers based on your application's needs. Different servers will have
+different capabilities, configuration, and support.
+
+
+Hosting Platforms
+-----------------
+
+There are many services available for hosting web applications without
+needing to maintain your own server, networking, domain, etc. Some
+services may have a free tier up to a certain time or bandwidth. Many of
+these services use one of the WSGI servers described above, or a similar
+interface. The links below are for some of the most common platforms,
+which have instructions for Flask, WSGI, or Python.
+
+- `PythonAnywhere `_
+- `Google App Engine `_
+- `Google Cloud Run `_
+- `AWS Elastic Beanstalk `_
+- `Microsoft Azure `_
+
+This list is not exhaustive, and you should evaluate these and other
+services based on your application's needs. Different services will have
+different capabilities, configuration, pricing, and support.
+
+You'll probably need to :doc:`proxy_fix` when using most hosting
+platforms.
diff --git a/src/flask-main/docs/deploying/mod_wsgi.rst b/src/flask-main/docs/deploying/mod_wsgi.rst
new file mode 100644
index 0000000..23e8227
--- /dev/null
+++ b/src/flask-main/docs/deploying/mod_wsgi.rst
@@ -0,0 +1,94 @@
+mod_wsgi
+========
+
+`mod_wsgi`_ is a WSGI server integrated with the `Apache httpd`_ server.
+The modern `mod_wsgi-express`_ command makes it easy to configure and
+start the server without needing to write Apache httpd configuration.
+
+* Tightly integrated with Apache httpd.
+* Supports Windows directly.
+* Requires a compiler and the Apache development headers to install.
+* Does not require a reverse proxy setup.
+
+This page outlines the basics of running mod_wsgi-express, not the more
+complex installation and configuration with httpd. Be sure to read the
+`mod_wsgi-express`_, `mod_wsgi`_, and `Apache httpd`_ documentation to
+understand what features are available.
+
+.. _mod_wsgi-express: https://pypi.org/project/mod-wsgi/
+.. _mod_wsgi: https://modwsgi.readthedocs.io/
+.. _Apache httpd: https://httpd.apache.org/
+
+
+Installing
+----------
+
+Installing mod_wsgi requires a compiler and the Apache server and
+development headers installed. You will get an error if they are not.
+How to install them depends on the OS and package manager that you use.
+
+Create a virtualenv, install your application, then install
+``mod_wsgi``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install mod_wsgi
+
+
+Running
+-------
+
+The only argument to ``mod_wsgi-express`` specifies a script containing
+your Flask application, which must be called ``application``. You can
+write a small script to import your app with this name, or to create it
+if using the app factory pattern.
+
+.. code-block:: python
+ :caption: ``wsgi.py``
+
+ from hello import app
+
+ application = app
+
+.. code-block:: python
+ :caption: ``wsgi.py``
+
+ from hello import create_app
+
+ application = create_app()
+
+Now run the ``mod_wsgi-express start-server`` command.
+
+.. code-block:: text
+
+ $ mod_wsgi-express start-server wsgi.py --processes 4
+
+The ``--processes`` option specifies the number of worker processes to
+run; a starting value could be ``CPU * 2``.
+
+Logs for each request aren't show in the terminal. If an error occurs,
+its information is written to the error log file shown when starting the
+server.
+
+
+Binding Externally
+------------------
+
+Unlike the other WSGI servers in these docs, mod_wsgi can be run as
+root to bind to privileged ports like 80 and 443. However, it must be
+configured to drop permissions to a different user and group for the
+worker processes.
+
+For example, if you created a ``hello`` user and group, you should
+install your virtualenv and application as that user, then tell
+mod_wsgi to drop to that user after starting.
+
+.. code-block:: text
+
+ $ sudo /home/hello/.venv/bin/mod_wsgi-express start-server \
+ /home/hello/wsgi.py \
+ --user hello --group hello --port 80 --processes 4
diff --git a/src/flask-main/docs/deploying/nginx.rst b/src/flask-main/docs/deploying/nginx.rst
new file mode 100644
index 0000000..6b25c07
--- /dev/null
+++ b/src/flask-main/docs/deploying/nginx.rst
@@ -0,0 +1,69 @@
+nginx
+=====
+
+`nginx`_ is a fast, production level HTTP server. When serving your
+application with one of the WSGI servers listed in :doc:`index`, it is
+often good or necessary to put a dedicated HTTP server in front of it.
+This "reverse proxy" can handle incoming requests, TLS, and other
+security and performance concerns better than the WSGI server.
+
+Nginx can be installed using your system package manager, or a pre-built
+executable for Windows. Installing and running Nginx itself is outside
+the scope of this doc. This page outlines the basics of configuring
+Nginx to proxy your application. Be sure to read its documentation to
+understand what features are available.
+
+.. _nginx: https://nginx.org/
+
+
+Domain Name
+-----------
+
+Acquiring and configuring a domain name is outside the scope of this
+doc. In general, you will buy a domain name from a registrar, pay for
+server space with a hosting provider, and then point your registrar
+at the hosting provider's name servers.
+
+To simulate this, you can also edit your ``hosts`` file, located at
+``/etc/hosts`` on Linux. Add a line that associates a name with the
+local IP.
+
+Modern Linux systems may be configured to treat any domain name that
+ends with ``.localhost`` like this without adding it to the ``hosts``
+file.
+
+.. code-block:: python
+ :caption: ``/etc/hosts``
+
+ 127.0.0.1 hello.localhost
+
+
+Configuration
+-------------
+
+The nginx configuration is located at ``/etc/nginx/nginx.conf`` on
+Linux. It may be different depending on your operating system. Check the
+docs and look for ``nginx.conf``.
+
+Remove or comment out any existing ``server`` section. Add a ``server``
+section and use the ``proxy_pass`` directive to point to the address the
+WSGI server is listening on. We'll assume the WSGI server is listening
+locally at ``http://127.0.0.1:8000``.
+
+.. code-block:: nginx
+ :caption: ``/etc/nginx.conf``
+
+ server {
+ listen 80;
+ server_name _;
+
+ location / {
+ proxy_pass http://127.0.0.1:8000/;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Prefix /;
+ }
+ }
+
+Then :doc:`proxy_fix` so that your application uses these headers.
diff --git a/src/flask-main/docs/deploying/proxy_fix.rst b/src/flask-main/docs/deploying/proxy_fix.rst
new file mode 100644
index 0000000..e2c42e8
--- /dev/null
+++ b/src/flask-main/docs/deploying/proxy_fix.rst
@@ -0,0 +1,33 @@
+Tell Flask it is Behind a Proxy
+===============================
+
+When using a reverse proxy, or many Python hosting platforms, the proxy
+will intercept and forward all external requests to the local WSGI
+server.
+
+From the WSGI server and Flask application's perspectives, requests are
+now coming from the HTTP server to the local address, rather than from
+the remote address to the external server address.
+
+HTTP servers should set ``X-Forwarded-`` headers to pass on the real
+values to the application. The application can then be told to trust and
+use those values by wrapping it with the
+:doc:`werkzeug:middleware/proxy_fix` middleware provided by Werkzeug.
+
+This middleware should only be used if the application is actually
+behind a proxy, and should be configured with the number of proxies that
+are chained in front of it. Not all proxies set all the headers. Since
+incoming headers can be faked, you must set how many proxies are setting
+each header so the middleware knows what to trust.
+
+.. code-block:: python
+
+ from werkzeug.middleware.proxy_fix import ProxyFix
+
+ app.wsgi_app = ProxyFix(
+ app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1
+ )
+
+Remember, only apply this middleware if you are behind a proxy, and set
+the correct number of proxies that set each header. It can be a security
+issue if you get this configuration wrong.
diff --git a/src/flask-main/docs/deploying/uwsgi.rst b/src/flask-main/docs/deploying/uwsgi.rst
new file mode 100644
index 0000000..1f9d5ec
--- /dev/null
+++ b/src/flask-main/docs/deploying/uwsgi.rst
@@ -0,0 +1,145 @@
+uWSGI
+=====
+
+`uWSGI`_ is a fast, compiled server suite with extensive configuration
+and capabilities beyond a basic server.
+
+* It can be very performant due to being a compiled program.
+* It is complex to configure beyond the basic application, and has so
+ many options that it can be difficult for beginners to understand.
+* It does not support Windows (but does run on WSL).
+* It requires a compiler to install in some cases.
+
+This page outlines the basics of running uWSGI. Be sure to read its
+documentation to understand what features are available.
+
+.. _uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/
+
+
+Installing
+----------
+
+uWSGI has multiple ways to install it. The most straightforward is to
+install the ``pyuwsgi`` package, which provides precompiled wheels for
+common platforms. However, it does not provide SSL support, which can be
+provided with a reverse proxy instead.
+
+Create a virtualenv, install your application, then install ``pyuwsgi``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install pyuwsgi
+
+If you have a compiler available, you can install the ``uwsgi`` package
+instead. Or install the ``pyuwsgi`` package from sdist instead of wheel.
+Either method will include SSL support.
+
+.. code-block:: text
+
+ $ pip install uwsgi
+
+ # or
+ $ pip install --no-binary pyuwsgi pyuwsgi
+
+
+Running
+-------
+
+The most basic way to run uWSGI is to tell it to start an HTTP server
+and import your application.
+
+.. code-block:: text
+
+ $ uwsgi --http 127.0.0.1:8000 --master -p 4 -w hello:app
+
+ *** Starting uWSGI 2.0.20 (64bit) on [x] ***
+ *** Operational MODE: preforking ***
+ mounting hello:app on /
+ spawned uWSGI master process (pid: x)
+ spawned uWSGI worker 1 (pid: x, cores: 1)
+ spawned uWSGI worker 2 (pid: x, cores: 1)
+ spawned uWSGI worker 3 (pid: x, cores: 1)
+ spawned uWSGI worker 4 (pid: x, cores: 1)
+ spawned uWSGI http 1 (pid: x)
+
+If you're using the app factory pattern, you'll need to create a small
+Python file to create the app, then point uWSGI at that.
+
+.. code-block:: python
+ :caption: ``wsgi.py``
+
+ from hello import create_app
+
+ app = create_app()
+
+.. code-block:: text
+
+ $ uwsgi --http 127.0.0.1:8000 --master -p 4 -w wsgi:app
+
+The ``--http`` option starts an HTTP server at 127.0.0.1 port 8000. The
+``--master`` option specifies the standard worker manager. The ``-p``
+option starts 4 worker processes; a starting value could be ``CPU * 2``.
+The ``-w`` option tells uWSGI how to import your application
+
+
+Binding Externally
+------------------
+
+uWSGI should not be run as root with the configuration shown in this doc
+because it would cause your application code to run as root, which is
+not secure. However, this means it will not be possible to bind to port
+80 or 443. Instead, a reverse proxy such as :doc:`nginx` or
+:doc:`apache-httpd` should be used in front of uWSGI. It is possible to
+run uWSGI as root securely, but that is beyond the scope of this doc.
+
+uWSGI has optimized integration with `Nginx uWSGI`_ and
+`Apache mod_proxy_uwsgi`_, and possibly other servers, instead of using
+a standard HTTP proxy. That configuration is beyond the scope of this
+doc, see the links for more information.
+
+.. _Nginx uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/Nginx.html
+.. _Apache mod_proxy_uwsgi: https://uwsgi-docs.readthedocs.io/en/latest/Apache.html#mod-proxy-uwsgi
+
+You can bind to all external IPs on a non-privileged port using the
+``--http 0.0.0.0:8000`` option. Don't do this when using a reverse proxy
+setup, otherwise it will be possible to bypass the proxy.
+
+.. code-block:: text
+
+ $ uwsgi --http 0.0.0.0:8000 --master -p 4 -w wsgi:app
+
+``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
+IP address in your browser.
+
+
+Async with gevent
+-----------------
+
+The default sync worker is appropriate for many use cases. If you need
+asynchronous support, uWSGI provides a `gevent`_ worker. This is not the
+same as Python's ``async/await``, or the ASGI server spec. You must
+actually use gevent in your own code to see any benefit to using the
+worker.
+
+When using gevent, greenlet>=1.0 is required, otherwise context locals
+such as ``request`` will not work as expected. When using PyPy,
+PyPy>=7.3.7 is required.
+
+.. code-block:: text
+
+ $ uwsgi --http 127.0.0.1:8000 --master --gevent 100 -w wsgi:app
+
+ *** Starting uWSGI 2.0.20 (64bit) on [x] ***
+ *** Operational MODE: async ***
+ mounting hello:app on /
+ spawned uWSGI master process (pid: x)
+ spawned uWSGI worker 1 (pid: x, cores: 100)
+ spawned uWSGI http 1 (pid: x)
+ *** running gevent loop engine [addr:x] ***
+
+
+.. _gevent: https://www.gevent.org/
diff --git a/src/flask-main/docs/deploying/waitress.rst b/src/flask-main/docs/deploying/waitress.rst
new file mode 100644
index 0000000..7bdd695
--- /dev/null
+++ b/src/flask-main/docs/deploying/waitress.rst
@@ -0,0 +1,75 @@
+Waitress
+========
+
+`Waitress`_ is a pure Python WSGI server.
+
+* It is easy to configure.
+* It supports Windows directly.
+* It is easy to install as it does not require additional dependencies
+ or compilation.
+* It does not support streaming requests, full request data is always
+ buffered.
+* It uses a single process with multiple thread workers.
+
+This page outlines the basics of running Waitress. Be sure to read its
+documentation and ``waitress-serve --help`` to understand what features
+are available.
+
+.. _Waitress: https://docs.pylonsproject.org/projects/waitress/
+
+
+Installing
+----------
+
+Create a virtualenv, install your application, then install
+``waitress``.
+
+.. code-block:: text
+
+ $ cd hello-app
+ $ python -m venv .venv
+ $ . .venv/bin/activate
+ $ pip install . # install your application
+ $ pip install waitress
+
+
+Running
+-------
+
+The only required argument to ``waitress-serve`` tells it how to load
+your Flask application. The syntax is ``{module}:{app}``. ``module`` is
+the dotted import name to the module with your application. ``app`` is
+the variable with the application. If you're using the app factory
+pattern, use ``--call {module}:{factory}`` instead.
+
+.. code-block:: text
+
+ # equivalent to 'from hello import app'
+ $ waitress-serve --host 127.0.0.1 hello:app
+
+ # equivalent to 'from hello import create_app; create_app()'
+ $ waitress-serve --host 127.0.0.1 --call hello:create_app
+
+ Serving on http://127.0.0.1:8080
+
+The ``--host`` option binds the server to local ``127.0.0.1`` only.
+
+Logs for each request aren't shown, only errors are shown. Logging can
+be configured through the Python interface instead of the command line.
+
+
+Binding Externally
+------------------
+
+Waitress should not be run as root because it would cause your
+application code to run as root, which is not secure. However, this
+means it will not be possible to bind to port 80 or 443. Instead, a
+reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used
+in front of Waitress.
+
+You can bind to all external IPs on a non-privileged port by not
+specifying the ``--host`` option. Don't do this when using a reverse
+proxy setup, otherwise it will be possible to bypass the proxy.
+
+``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
+IP address in your browser.
diff --git a/src/flask-main/docs/design.rst b/src/flask-main/docs/design.rst
new file mode 100644
index 0000000..d8776a9
--- /dev/null
+++ b/src/flask-main/docs/design.rst
@@ -0,0 +1,229 @@
+Design Decisions in Flask
+=========================
+
+If you are curious why Flask does certain things the way it does and not
+differently, this section is for you. This should give you an idea about
+some of the design decisions that may appear arbitrary and surprising at
+first, especially in direct comparison with other frameworks.
+
+
+The Explicit Application Object
+-------------------------------
+
+A Python web application based on WSGI has to have one central callable
+object that implements the actual application. In Flask this is an
+instance of the :class:`~flask.Flask` class. Each Flask application has
+to create an instance of this class itself and pass it the name of the
+module, but why can't Flask do that itself?
+
+Without such an explicit application object the following code::
+
+ from flask import Flask
+ app = Flask(__name__)
+
+ @app.route('/')
+ def index():
+ return 'Hello World!'
+
+Would look like this instead::
+
+ from hypothetical_flask import route
+
+ @route('/')
+ def index():
+ return 'Hello World!'
+
+There are three major reasons for this. The most important one is that
+implicit application objects require that there may only be one instance at
+the time. There are ways to fake multiple applications with a single
+application object, like maintaining a stack of applications, but this
+causes some problems I won't outline here in detail. Now the question is:
+when does a microframework need more than one application at the same
+time? A good example for this is unit testing. When you want to test
+something it can be very helpful to create a minimal application to test
+specific behavior. When the application object is deleted everything it
+allocated will be freed again.
+
+Another thing that becomes possible when you have an explicit object lying
+around in your code is that you can subclass the base class
+(:class:`~flask.Flask`) to alter specific behavior. This would not be
+possible without hacks if the object were created ahead of time for you
+based on a class that is not exposed to you.
+
+But there is another very important reason why Flask depends on an
+explicit instantiation of that class: the package name. Whenever you
+create a Flask instance you usually pass it `__name__` as package name.
+Flask depends on that information to properly load resources relative
+to your module. With Python's outstanding support for reflection it can
+then access the package to figure out where the templates and static files
+are stored (see :meth:`~flask.Flask.open_resource`). Now obviously there
+are frameworks around that do not need any configuration and will still be
+able to load templates relative to your application module. But they have
+to use the current working directory for that, which is a very unreliable
+way to determine where the application is. The current working directory
+is process-wide and if you are running multiple applications in one
+process (which could happen in a webserver without you knowing) the paths
+will be off. Worse: many webservers do not set the working directory to
+the directory of your application but to the document root which does not
+have to be the same folder.
+
+The third reason is "explicit is better than implicit". That object is
+your WSGI application, you don't have to remember anything else. If you
+want to apply a WSGI middleware, just wrap it and you're done (though
+there are better ways to do that so that you do not lose the reference
+to the application object :meth:`~flask.Flask.wsgi_app`).
+
+Furthermore this design makes it possible to use a factory function to
+create the application which is very helpful for unit testing and similar
+things (:doc:`/patterns/appfactories`).
+
+The Routing System
+------------------
+
+Flask uses the Werkzeug routing system which was designed to
+automatically order routes by complexity. This means that you can declare
+routes in arbitrary order and they will still work as expected. This is a
+requirement if you want to properly implement decorator based routing
+since decorators could be fired in undefined order when the application is
+split into multiple modules.
+
+Another design decision with the Werkzeug routing system is that routes
+in Werkzeug try to ensure that URLs are unique. Werkzeug will go quite far
+with that in that it will automatically redirect to a canonical URL if a route
+is ambiguous.
+
+
+One Template Engine
+-------------------
+
+Flask decides on one template engine: Jinja. Why doesn't Flask have a
+pluggable template engine interface? You can obviously use a different
+template engine, but Flask will still configure Jinja for you. While
+that limitation that Jinja is *always* configured will probably go away,
+the decision to bundle one template engine and use that will not.
+
+Template engines are like programming languages and each of those engines
+has a certain understanding about how things work. On the surface they
+all work the same: you tell the engine to evaluate a template with a set
+of variables and take the return value as string.
+
+But that's about where similarities end. Jinja for example has an
+extensive filter system, a certain way to do template inheritance,
+support for reusable blocks (macros) that can be used from inside
+templates and also from Python code, supports iterative template
+rendering, configurable syntax and more. On the other hand an engine
+like Genshi is based on XML stream evaluation, template inheritance by
+taking the availability of XPath into account and more. Mako on the
+other hand treats templates similar to Python modules.
+
+When it comes to connecting a template engine with an application or
+framework there is more than just rendering templates. For instance,
+Flask uses Jinja's extensive autoescaping support. Also it provides
+ways to access macros from Jinja templates.
+
+A template abstraction layer that would not take the unique features of
+the template engines away is a science on its own and a too large
+undertaking for a microframework like Flask.
+
+Furthermore extensions can then easily depend on one template language
+being present. You can easily use your own templating language, but an
+extension could still depend on Jinja itself.
+
+
+What does "micro" mean?
+-----------------------
+
+“Micro” does not mean that your whole web application has to fit into a single
+Python file (although it certainly can), nor does it mean that Flask is lacking
+in functionality. The "micro" in microframework means Flask aims to keep the
+core simple but extensible. Flask won't make many decisions for you, such as
+what database to use. Those decisions that it does make, such as what
+templating engine to use, are easy to change. Everything else is up to you, so
+that Flask can be everything you need and nothing you don't.
+
+By default, Flask does not include a database abstraction layer, form
+validation or anything else where different libraries already exist that can
+handle that. Instead, Flask supports extensions to add such functionality to
+your application as if it was implemented in Flask itself. Numerous extensions
+provide database integration, form validation, upload handling, various open
+authentication technologies, and more. Flask may be "micro", but it's ready for
+production use on a variety of needs.
+
+Why does Flask call itself a microframework and yet it depends on two
+libraries (namely Werkzeug and Jinja). Why shouldn't it? If we look
+over to the Ruby side of web development there we have a protocol very
+similar to WSGI. Just that it's called Rack there, but besides that it
+looks very much like a WSGI rendition for Ruby. But nearly all
+applications in Ruby land do not work with Rack directly, but on top of a
+library with the same name. This Rack library has two equivalents in
+Python: WebOb (formerly Paste) and Werkzeug. Paste is still around but
+from my understanding it's sort of deprecated in favour of WebOb. The
+development of WebOb and Werkzeug started side by side with similar ideas
+in mind: be a good implementation of WSGI for other applications to take
+advantage.
+
+Flask is a framework that takes advantage of the work already done by
+Werkzeug to properly interface WSGI (which can be a complex task at
+times). Thanks to recent developments in the Python package
+infrastructure, packages with dependencies are no longer an issue and
+there are very few reasons against having libraries that depend on others.
+
+
+Context Locals
+--------------
+
+Flask uses special context locals and proxies to provide access to the
+current app and request data to any code running during a request, CLI command,
+etc. Context locals are specific to the worker handling the activity, such as a
+thread, process, coroutine, or greenlet.
+
+The context and proxies help solve two development issues: circular imports, and
+passing around global data. :data:`.current_app` can be used to access the
+application object without needing to import the app object directly, avoiding
+circular import issues. :data:`.request`, :data:`.session`, and :data:`.g` can
+be imported to access the current data for the request, rather than needing to
+pass them as arguments through every single function in your project.
+
+
+Async/await and ASGI support
+----------------------------
+
+Flask supports ``async`` coroutines for view functions by executing the
+coroutine on a separate thread instead of using an event loop on the
+main thread as an async-first (ASGI) framework would. This is necessary
+for Flask to remain backwards compatible with extensions and code built
+before ``async`` was introduced into Python. This compromise introduces
+a performance cost compared with the ASGI frameworks, due to the
+overhead of the threads.
+
+Due to how tied to WSGI Flask's code is, it's not clear if it's possible
+to make the ``Flask`` class support ASGI and WSGI at the same time. Work
+is currently being done in Werkzeug to work with ASGI, which may
+eventually enable support in Flask as well.
+
+See :doc:`/async-await` for more discussion.
+
+
+What Flask is, What Flask is Not
+--------------------------------
+
+Flask will never have a database layer. It will not have a form library
+or anything else in that direction. Flask itself just bridges to Werkzeug
+to implement a proper WSGI application and to Jinja to handle templating.
+It also binds to a few common standard library packages such as logging.
+Everything else is up for extensions.
+
+Why is this the case? Because people have different preferences and
+requirements and Flask could not meet those if it would force any of this
+into the core. The majority of web applications will need a template
+engine in some sort. However not every application needs a SQL database.
+
+As your codebase grows, you are free to make the design decisions appropriate
+for your project. Flask will continue to provide a very simple glue layer to
+the best that Python has to offer. You can implement advanced patterns in
+SQLAlchemy or another database tool, introduce non-relational data persistence
+as appropriate, and take advantage of framework-agnostic tools built for WSGI,
+the Python web interface.
+
+The idea of Flask is to build a good foundation for all applications.
+Everything else is up to you or extensions.
diff --git a/src/flask-main/docs/errorhandling.rst b/src/flask-main/docs/errorhandling.rst
new file mode 100644
index 0000000..faca58c
--- /dev/null
+++ b/src/flask-main/docs/errorhandling.rst
@@ -0,0 +1,523 @@
+Handling Application Errors
+===========================
+
+Applications fail, servers fail. Sooner or later you will see an exception
+in production. Even if your code is 100% correct, you will still see
+exceptions from time to time. Why? Because everything else involved will
+fail. Here are some situations where perfectly fine code can lead to server
+errors:
+
+- the client terminated the request early and the application was still
+ reading from the incoming data
+- the database server was overloaded and could not handle the query
+- a filesystem is full
+- a harddrive crashed
+- a backend server overloaded
+- a programming error in a library you are using
+- network connection of the server to another system failed
+
+And that's just a small sample of issues you could be facing. So how do we
+deal with that sort of problem? By default if your application runs in
+production mode, and an exception is raised Flask will display a very simple
+page for you and log the exception to the :attr:`~flask.Flask.logger`.
+
+But there is more you can do, and we will cover some better setups to deal
+with errors including custom exceptions and 3rd party tools.
+
+
+.. _error-logging-tools:
+
+Error Logging Tools
+-------------------
+
+Sending error mails, even if just for critical ones, can become
+overwhelming if enough users are hitting the error and log files are
+typically never looked at. This is why we recommend using `Sentry
+`_ for dealing with application errors. It's
+available as a source-available project `on GitHub
+`_ and is also available as a `hosted version
+`_ which you can try for free. Sentry
+aggregates duplicate errors, captures the full stack trace and local
+variables for debugging, and sends you mails based on new errors or
+frequency thresholds.
+
+To use Sentry you need to install the ``sentry-sdk`` client with extra
+``flask`` dependencies.
+
+.. code-block:: text
+
+ $ pip install sentry-sdk[flask]
+
+And then add this to your Flask app:
+
+.. code-block:: python
+
+ import sentry_sdk
+ from sentry_sdk.integrations.flask import FlaskIntegration
+
+ sentry_sdk.init('YOUR_DSN_HERE', integrations=[FlaskIntegration()])
+
+The ``YOUR_DSN_HERE`` value needs to be replaced with the DSN value you
+get from your Sentry installation.
+
+After installation, failures leading to an Internal Server Error
+are automatically reported to Sentry and from there you can
+receive error notifications.
+
+See also:
+
+- Sentry also supports catching errors from a worker queue
+ (RQ, Celery, etc.) in a similar fashion. See the `Python SDK docs
+ `__ for more information.
+- `Flask-specific documentation `__
+
+
+Error Handlers
+--------------
+
+When an error occurs in Flask, an appropriate `HTTP status code
+`__ will be
+returned. 400-499 indicate errors with the client's request data, or
+about the data requested. 500-599 indicate errors with the server or
+application itself.
+
+You might want to show custom error pages to the user when an error occurs.
+This can be done by registering error handlers.
+
+An error handler is a function that returns a response when a type of error is
+raised, similar to how a view is a function that returns a response when a
+request URL is matched. It is passed the instance of the error being handled,
+which is most likely a :exc:`~werkzeug.exceptions.HTTPException`.
+
+The status code of the response will not be set to the handler's code. Make
+sure to provide the appropriate HTTP status code when returning a response from
+a handler.
+
+
+Registering
+```````````
+
+Register handlers by decorating a function with
+:meth:`~flask.Flask.errorhandler`. Or use
+:meth:`~flask.Flask.register_error_handler` to register the function later.
+Remember to set the error code when returning the response.
+
+.. code-block:: python
+
+ @app.errorhandler(werkzeug.exceptions.BadRequest)
+ def handle_bad_request(e):
+ return 'bad request!', 400
+
+ # or, without the decorator
+ app.register_error_handler(400, handle_bad_request)
+
+:exc:`werkzeug.exceptions.HTTPException` subclasses like
+:exc:`~werkzeug.exceptions.BadRequest` and their HTTP codes are interchangeable
+when registering handlers. (``BadRequest.code == 400``)
+
+Non-standard HTTP codes cannot be registered by code because they are not known
+by Werkzeug. Instead, define a subclass of
+:class:`~werkzeug.exceptions.HTTPException` with the appropriate code and
+register and raise that exception class.
+
+.. code-block:: python
+
+ class InsufficientStorage(werkzeug.exceptions.HTTPException):
+ code = 507
+ description = 'Not enough storage space.'
+
+ app.register_error_handler(InsufficientStorage, handle_507)
+
+ raise InsufficientStorage()
+
+Handlers can be registered for any exception class, not just
+:exc:`~werkzeug.exceptions.HTTPException` subclasses or HTTP status
+codes. Handlers can be registered for a specific class, or for all subclasses
+of a parent class.
+
+
+Handling
+````````
+
+When building a Flask application you *will* run into exceptions. If some part
+of your code breaks while handling a request (and you have no error handlers
+registered), a "500 Internal Server Error"
+(:exc:`~werkzeug.exceptions.InternalServerError`) will be returned by default.
+Similarly, "404 Not Found"
+(:exc:`~werkzeug.exceptions.NotFound`) error will occur if a request is sent to an unregistered route.
+If a route receives an unallowed request method, a "405 Method Not Allowed"
+(:exc:`~werkzeug.exceptions.MethodNotAllowed`) will be raised. These are all
+subclasses of :class:`~werkzeug.exceptions.HTTPException` and are provided by
+default in Flask.
+
+Flask gives you the ability to raise any HTTP exception registered by
+Werkzeug. However, the default HTTP exceptions return simple exception
+pages. You might want to show custom error pages to the user when an error occurs.
+This can be done by registering error handlers.
+
+When Flask catches an exception while handling a request, it is first looked up by code.
+If no handler is registered for the code, Flask looks up the error by its class hierarchy; the most specific handler is chosen.
+If no handler is registered, :class:`~werkzeug.exceptions.HTTPException` subclasses show a
+generic message about their code, while other exceptions are converted to a
+generic "500 Internal Server Error".
+
+For example, if an instance of :exc:`ConnectionRefusedError` is raised,
+and a handler is registered for :exc:`ConnectionError` and
+:exc:`ConnectionRefusedError`, the more specific :exc:`ConnectionRefusedError`
+handler is called with the exception instance to generate the response.
+
+Handlers registered on the blueprint take precedence over those registered
+globally on the application, assuming a blueprint is handling the request that
+raises the exception. However, the blueprint cannot handle 404 routing errors
+because the 404 occurs at the routing level before the blueprint can be
+determined.
+
+
+Generic Exception Handlers
+``````````````````````````
+
+It is possible to register error handlers for very generic base classes
+such as ``HTTPException`` or even ``Exception``. However, be aware that
+these will catch more than you might expect.
+
+For example, an error handler for ``HTTPException`` might be useful for turning
+the default HTML errors pages into JSON. However, this
+handler will trigger for things you don't cause directly, such as 404
+and 405 errors during routing. Be sure to craft your handler carefully
+so you don't lose information about the HTTP error.
+
+.. code-block:: python
+
+ from flask import json
+ from werkzeug.exceptions import HTTPException
+
+ @app.errorhandler(HTTPException)
+ def handle_exception(e):
+ """Return JSON instead of HTML for HTTP errors."""
+ # start with the correct headers and status code from the error
+ response = e.get_response()
+ # replace the body with JSON
+ response.data = json.dumps({
+ "code": e.code,
+ "name": e.name,
+ "description": e.description,
+ })
+ response.content_type = "application/json"
+ return response
+
+An error handler for ``Exception`` might seem useful for changing how
+all errors, even unhandled ones, are presented to the user. However,
+this is similar to doing ``except Exception:`` in Python, it will
+capture *all* otherwise unhandled errors, including all HTTP status
+codes.
+
+In most cases it will be safer to register handlers for more
+specific exceptions. Since ``HTTPException`` instances are valid WSGI
+responses, you could also pass them through directly.
+
+.. code-block:: python
+
+ from werkzeug.exceptions import HTTPException
+
+ @app.errorhandler(Exception)
+ def handle_exception(e):
+ # pass through HTTP errors
+ if isinstance(e, HTTPException):
+ return e
+
+ # now you're handling non-HTTP exceptions only
+ return render_template("500_generic.html", e=e), 500
+
+Error handlers still respect the exception class hierarchy. If you
+register handlers for both ``HTTPException`` and ``Exception``, the
+``Exception`` handler will not handle ``HTTPException`` subclasses
+because the ``HTTPException`` handler is more specific.
+
+
+Unhandled Exceptions
+````````````````````
+
+When there is no error handler registered for an exception, a 500
+Internal Server Error will be returned instead. See
+:meth:`flask.Flask.handle_exception` for information about this
+behavior.
+
+If there is an error handler registered for ``InternalServerError``,
+this will be invoked. As of Flask 1.1.0, this error handler will always
+be passed an instance of ``InternalServerError``, not the original
+unhandled error.
+
+The original error is available as ``e.original_exception``.
+
+An error handler for "500 Internal Server Error" will be passed uncaught
+exceptions in addition to explicit 500 errors. In debug mode, a handler
+for "500 Internal Server Error" will not be used. Instead, the
+interactive debugger will be shown.
+
+
+Custom Error Pages
+------------------
+
+Sometimes when building a Flask application, you might want to raise a
+:exc:`~werkzeug.exceptions.HTTPException` to signal to the user that
+something is wrong with the request. Fortunately, Flask comes with a handy
+:func:`~flask.abort` function that aborts a request with a HTTP error from
+werkzeug as desired. It will also provide a plain black and white error page
+for you with a basic description, but nothing fancy.
+
+Depending on the error code it is less or more likely for the user to
+actually see such an error.
+
+Consider the code below, we might have a user profile route, and if the user
+fails to pass a username we can raise a "400 Bad Request". If the user passes a
+username and we can't find it, we raise a "404 Not Found".
+
+.. code-block:: python
+
+ from flask import abort, render_template, request
+
+ # a username needs to be supplied in the query args
+ # a successful request would be like /profile?username=jack
+ @app.route("/profile")
+ def user_profile():
+ username = request.arg.get("username")
+ # if a username isn't supplied in the request, return a 400 bad request
+ if username is None:
+ abort(400)
+
+ user = get_user(username=username)
+ # if a user can't be found by their username, return 404 not found
+ if user is None:
+ abort(404)
+
+ return render_template("profile.html", user=user)
+
+Here is another example implementation for a "404 Page Not Found" exception:
+
+.. code-block:: python
+
+ from flask import render_template
+
+ @app.errorhandler(404)
+ def page_not_found(e):
+ # note that we set the 404 status explicitly
+ return render_template('404.html'), 404
+
+When using :doc:`/patterns/appfactories`:
+
+.. code-block:: python
+
+ from flask import Flask, render_template
+
+ def page_not_found(e):
+ return render_template('404.html'), 404
+
+ def create_app(config_filename):
+ app = Flask(__name__)
+ app.register_error_handler(404, page_not_found)
+ return app
+
+An example template might be this:
+
+.. code-block:: html+jinja
+
+ {% extends "layout.html" %}
+ {% block title %}Page Not Found{% endblock %}
+ {% block body %}
+
Page Not Found
+
What you were looking for is just not there.
+
go somewhere nice
+ {% endblock %}
+
+
+Further Examples
+````````````````
+
+The above examples wouldn't actually be an improvement on the default
+exception pages. We can create a custom 500.html template like this:
+
+.. code-block:: html+jinja
+
+ {% extends "layout.html" %}
+ {% block title %}Internal Server Error{% endblock %}
+ {% block body %}
+
Internal Server Error
+
Oops... we seem to have made a mistake, sorry!
+
Go somewhere nice instead
+ {% endblock %}
+
+It can be implemented by rendering the template on "500 Internal Server Error":
+
+.. code-block:: python
+
+ from flask import render_template
+
+ @app.errorhandler(500)
+ def internal_server_error(e):
+ # note that we set the 500 status explicitly
+ return render_template('500.html'), 500
+
+When using :doc:`/patterns/appfactories`:
+
+.. code-block:: python
+
+ from flask import Flask, render_template
+
+ def internal_server_error(e):
+ return render_template('500.html'), 500
+
+ def create_app():
+ app = Flask(__name__)
+ app.register_error_handler(500, internal_server_error)
+ return app
+
+When using :doc:`/blueprints`:
+
+.. code-block:: python
+
+ from flask import Blueprint
+
+ blog = Blueprint('blog', __name__)
+
+ # as a decorator
+ @blog.errorhandler(500)
+ def internal_server_error(e):
+ return render_template('500.html'), 500
+
+ # or with register_error_handler
+ blog.register_error_handler(500, internal_server_error)
+
+
+Blueprint Error Handlers
+------------------------
+
+In :doc:`/blueprints`, most error handlers will work as expected.
+However, there is a caveat concerning handlers for 404 and 405
+exceptions. These error handlers are only invoked from an appropriate
+``raise`` statement or a call to ``abort`` in another of the blueprint's
+view functions; they are not invoked by, e.g., an invalid URL access.
+
+This is because the blueprint does not "own" a certain URL space, so
+the application instance has no way of knowing which blueprint error
+handler it should run if given an invalid URL. If you would like to
+execute different handling strategies for these errors based on URL
+prefixes, they may be defined at the application level using the
+``request`` proxy object.
+
+.. code-block:: python
+
+ from flask import jsonify, render_template
+
+ # at the application level
+ # not the blueprint level
+ @app.errorhandler(404)
+ def page_not_found(e):
+ # if a request is in our blog URL space
+ if request.path.startswith('/blog/'):
+ # we return a custom blog 404 page
+ return render_template("blog/404.html"), 404
+ else:
+ # otherwise we return our generic site-wide 404 page
+ return render_template("404.html"), 404
+
+ @app.errorhandler(405)
+ def method_not_allowed(e):
+ # if a request has the wrong method to our API
+ if request.path.startswith('/api/'):
+ # we return a json saying so
+ return jsonify(message="Method Not Allowed"), 405
+ else:
+ # otherwise we return a generic site-wide 405 page
+ return render_template("405.html"), 405
+
+
+Returning API Errors as JSON
+----------------------------
+
+When building APIs in Flask, some developers realise that the built-in
+exceptions are not expressive enough for APIs and that the content type of
+:mimetype:`text/html` they are emitting is not very useful for API consumers.
+
+Using the same techniques as above and :func:`~flask.json.jsonify` we can return JSON
+responses to API errors. :func:`~flask.abort` is called
+with a ``description`` parameter. The error handler will
+use that as the JSON error message, and set the status code to 404.
+
+.. code-block:: python
+
+ from flask import abort, jsonify
+
+ @app.errorhandler(404)
+ def resource_not_found(e):
+ return jsonify(error=str(e)), 404
+
+ @app.route("/cheese")
+ def get_one_cheese():
+ resource = get_resource()
+
+ if resource is None:
+ abort(404, description="Resource not found")
+
+ return jsonify(resource)
+
+We can also create custom exception classes. For instance, we can
+introduce a new custom exception for an API that can take a proper human readable message,
+a status code for the error and some optional payload to give more context
+for the error.
+
+This is a simple example:
+
+.. code-block:: python
+
+ from flask import jsonify, request
+
+ class InvalidAPIUsage(Exception):
+ status_code = 400
+
+ def __init__(self, message, status_code=None, payload=None):
+ super().__init__()
+ self.message = message
+ if status_code is not None:
+ self.status_code = status_code
+ self.payload = payload
+
+ def to_dict(self):
+ rv = dict(self.payload or ())
+ rv['message'] = self.message
+ return rv
+
+ @app.errorhandler(InvalidAPIUsage)
+ def invalid_api_usage(e):
+ return jsonify(e.to_dict()), e.status_code
+
+ # an API app route for getting user information
+ # a correct request might be /api/user?user_id=420
+ @app.route("/api/user")
+ def user_api(user_id):
+ user_id = request.arg.get("user_id")
+ if not user_id:
+ raise InvalidAPIUsage("No user id provided!")
+
+ user = get_user(user_id=user_id)
+ if not user:
+ raise InvalidAPIUsage("No such user!", status_code=404)
+
+ return jsonify(user.to_dict())
+
+A view can now raise that exception with an error message. Additionally
+some extra payload can be provided as a dictionary through the `payload`
+parameter.
+
+
+Logging
+-------
+
+See :doc:`/logging` for information about how to log exceptions, such as
+by emailing them to admins.
+
+
+Debugging
+---------
+
+See :doc:`/debugging` for information about how to debug errors in
+development and production.
diff --git a/src/flask-main/docs/extensiondev.rst b/src/flask-main/docs/extensiondev.rst
new file mode 100644
index 0000000..ae5ed33
--- /dev/null
+++ b/src/flask-main/docs/extensiondev.rst
@@ -0,0 +1,305 @@
+Flask Extension Development
+===========================
+
+.. currentmodule:: flask
+
+Extensions are extra packages that add functionality to a Flask
+application. While `PyPI`_ contains many Flask extensions, you may not
+find one that fits your need. If this is the case, you can create your
+own, and publish it for others to use as well.
+
+This guide will show how to create a Flask extension, and some of the
+common patterns and requirements involved. Since extensions can do
+anything, this guide won't be able to cover every possibility.
+
+The best ways to learn about extensions are to look at how other
+extensions you use are written, and discuss with others. Discuss your
+design ideas with others on our `Discord Chat`_ or
+`GitHub Discussions`_.
+
+The best extensions share common patterns, so that anyone familiar with
+using one extension won't feel completely lost with another. This can
+only work if collaboration happens early.
+
+
+Naming
+------
+
+A Flask extension typically has ``flask`` in its name as a prefix or
+suffix. If it wraps another library, it should include the library name
+as well. This makes it easy to search for extensions, and makes their
+purpose clearer.
+
+A general Python packaging recommendation is that the install name from
+the package index and the name used in ``import`` statements should be
+related. The import name is lowercase, with words separated by
+underscores (``_``). The install name is either lower case or title
+case, with words separated by dashes (``-``). If it wraps another
+library, prefer using the same case as that library's name.
+
+Here are some example install and import names:
+
+- ``Flask-Name`` imported as ``flask_name``
+- ``flask-name-lower`` imported as ``flask_name_lower``
+- ``Flask-ComboName`` imported as ``flask_comboname``
+- ``Name-Flask`` imported as ``name_flask``
+
+
+The Extension Class and Initialization
+--------------------------------------
+
+All extensions will need some entry point that initializes the
+extension with the application. The most common pattern is to create a
+class that represents the extension's configuration and behavior, with
+an ``init_app`` method to apply the extension instance to the given
+application instance.
+
+.. code-block:: python
+
+ class HelloExtension:
+ def __init__(self, app=None):
+ if app is not None:
+ self.init_app(app)
+
+ def init_app(self, app):
+ app.before_request(...)
+
+It is important that the app is not stored on the extension, don't do
+``self.app = app``. The only time the extension should have direct
+access to an app is during ``init_app``, otherwise it should use
+:data:`.current_app`.
+
+This allows the extension to support the application factory pattern,
+avoids circular import issues when importing the extension instance
+elsewhere in a user's code, and makes testing with different
+configurations easier.
+
+.. code-block:: python
+
+ hello = HelloExtension()
+
+ def create_app():
+ app = Flask(__name__)
+ hello.init_app(app)
+ return app
+
+Above, the ``hello`` extension instance exists independently of the
+application. This means that other modules in a user's project can do
+``from project import hello`` and use the extension in blueprints before
+the app exists.
+
+The :attr:`Flask.extensions` dict can be used to store a reference to
+the extension on the application, or some other state specific to the
+application. Be aware that this is a single namespace, so use a name
+unique to your extension, such as the extension's name without the
+"flask" prefix.
+
+
+Adding Behavior
+---------------
+
+There are many ways that an extension can add behavior. Any setup
+methods that are available on the :class:`Flask` object can be used
+during an extension's ``init_app`` method.
+
+A common pattern is to use :meth:`~Flask.before_request` to initialize
+some data or a connection at the beginning of each request, then
+:meth:`~Flask.teardown_request` to clean it up at the end. This can be
+stored on :data:`.g`, discussed more below.
+
+A more lazy approach is to provide a method that initializes and caches
+the data or connection. For example, a ``ext.get_db`` method could
+create a database connection the first time it's called, so that a view
+that doesn't use the database doesn't create a connection.
+
+Besides doing something before and after every view, your extension
+might want to add some specific views as well. In this case, you could
+define a :class:`Blueprint`, then call :meth:`~Flask.register_blueprint`
+during ``init_app`` to add the blueprint to the app.
+
+
+Configuration Techniques
+------------------------
+
+There can be multiple levels and sources of configuration for an
+extension. You should consider what parts of your extension fall into
+each one.
+
+- Configuration per application instance, through ``app.config``
+ values. This is configuration that could reasonably change for each
+ deployment of an application. A common example is a URL to an
+ external resource, such as a database. Configuration keys should
+ start with the extension's name so that they don't interfere with
+ other extensions.
+- Configuration per extension instance, through ``__init__``
+ arguments. This configuration usually affects how the extension
+ is used, such that it wouldn't make sense to change it per
+ deployment.
+- Configuration per extension instance, through instance attributes
+ and decorator methods. It might be more ergonomic to assign to
+ ``ext.value``, or use a ``@ext.register`` decorator to register a
+ function, after the extension instance has been created.
+- Global configuration through class attributes. Changing a class
+ attribute like ``Ext.connection_class`` can customize default
+ behavior without making a subclass. This could be combined
+ per-extension configuration to override defaults.
+- Subclassing and overriding methods and attributes. Making the API of
+ the extension itself something that can be overridden provides a
+ very powerful tool for advanced customization.
+
+The :class:`~flask.Flask` object itself uses all of these techniques.
+
+It's up to you to decide what configuration is appropriate for your
+extension, based on what you need and what you want to support.
+
+Configuration should not be changed after the application setup phase is
+complete and the server begins handling requests. Configuration is
+global, any changes to it are not guaranteed to be visible to other
+workers.
+
+
+Data During a Request
+---------------------
+
+When writing a Flask application, the :data:`~flask.g` object is used to
+store information during a request. For example the
+:doc:`tutorial ` stores a connection to a SQLite
+database as ``g.db``. Extensions can also use this, with some care.
+Since ``g`` is a single global namespace, extensions must use unique
+names that won't collide with user data. For example, use the extension
+name as a prefix, or as a namespace.
+
+.. code-block:: python
+
+ # an internal prefix with the extension name
+ g._hello_user_id = 2
+
+ # or an internal prefix as a namespace
+ from types import SimpleNamespace
+ g._hello = SimpleNamespace()
+ g._hello.user_id = 2
+
+The data in ``g`` lasts for an application context. An application context is
+active during a request, CLI command, or ``with app.app_context()`` block. If
+you're storing something that should be closed, use
+:meth:`~flask.Flask.teardown_appcontext` to ensure that it gets closed when the
+app context ends. If it should only be valid during a request, or would not be
+used in the CLI outside a request, use :meth:`~flask.Flask.teardown_request`.
+
+
+Views and Models
+----------------
+
+Your extension views might want to interact with specific models in your
+database, or some other extension or data connected to your application.
+For example, let's consider a ``Flask-SimpleBlog`` extension that works
+with Flask-SQLAlchemy to provide a ``Post`` model and views to write
+and read posts.
+
+The ``Post`` model needs to subclass the Flask-SQLAlchemy ``db.Model``
+object, but that's only available once you've created an instance of
+that extension, not when your extension is defining its views. So how
+can the view code, defined before the model exists, access the model?
+
+One method could be to use :doc:`views`. During ``__init__``, create
+the model, then create the views by passing the model to the view
+class's :meth:`~views.View.as_view` method.
+
+.. code-block:: python
+
+ class PostAPI(MethodView):
+ def __init__(self, model):
+ self.model = model
+
+ def get(self, id):
+ post = self.model.query.get(id)
+ return jsonify(post.to_json())
+
+ class BlogExtension:
+ def __init__(self, db):
+ class Post(db.Model):
+ id = db.Column(primary_key=True)
+ title = db.Column(db.String, nullable=False)
+
+ self.post_model = Post
+
+ def init_app(self, app):
+ api_view = PostAPI.as_view(model=self.post_model)
+
+ db = SQLAlchemy()
+ blog = BlogExtension(db)
+ db.init_app(app)
+ blog.init_app(app)
+
+Another technique could be to use an attribute on the extension, such as
+``self.post_model`` from above. Add the extension to ``app.extensions``
+in ``init_app``, then access
+``current_app.extensions["simple_blog"].post_model`` from views.
+
+You may also want to provide base classes so that users can provide
+their own ``Post`` model that conforms to the API your extension
+expects. So they could implement ``class Post(blog.BasePost)``, then
+set it as ``blog.post_model``.
+
+As you can see, this can get a bit complex. Unfortunately, there's no
+perfect solution here, only different strategies and tradeoffs depending
+on your needs and how much customization you want to offer. Luckily,
+this sort of resource dependency is not a common need for most
+extensions. Remember, if you need help with design, ask on our
+`Discord Chat`_ or `GitHub Discussions`_.
+
+
+Recommended Extension Guidelines
+--------------------------------
+
+Flask previously had the concept of "approved extensions", where the
+Flask maintainers evaluated the quality, support, and compatibility of
+the extensions before listing them. While the list became too difficult
+to maintain over time, the guidelines are still relevant to all
+extensions maintained and developed today, as they help the Flask
+ecosystem remain consistent and compatible.
+
+1. An extension requires a maintainer. In the event an extension author
+ would like to move beyond the project, the project should find a new
+ maintainer and transfer access to the repository, documentation,
+ PyPI, and any other services. The `Pallets-Eco`_ organization on
+ GitHub allows for community maintenance with oversight from the
+ Pallets maintainers.
+2. The naming scheme is *Flask-ExtensionName* or *ExtensionName-Flask*.
+ It must provide exactly one package or module named
+ ``flask_extension_name``.
+3. The extension must use an open source license. The Python web
+ ecosystem tends to prefer BSD or MIT. It must be open source and
+ publicly available.
+4. The extension's API must have the following characteristics:
+
+ - It must support multiple applications running in the same Python
+ process. Use ``current_app`` instead of ``self.app``, store
+ configuration and state per application instance.
+ - It must be possible to use the factory pattern for creating
+ applications. Use the ``ext.init_app()`` pattern.
+
+5. From a clone of the repository, an extension with its dependencies
+ must be installable in editable mode with ``pip install -e .``.
+6. It must ship tests that can be invoked with a common tool like
+ ``tox -e py``, ``nox -s test`` or ``pytest``. If not using ``tox``,
+ the test dependencies should be specified in a requirements file.
+ The tests must be part of the sdist distribution.
+7. A link to the documentation or project website must be in the PyPI
+ metadata or the readme. The documentation should use the Flask theme
+ from the `Official Pallets Themes`_.
+8. The extension's dependencies should not use upper bounds or assume
+ any particular version scheme, but should use lower bounds to
+ indicate minimum compatibility support. For example,
+ ``sqlalchemy>=1.4``.
+9. Indicate the versions of Python supported using ``python_requires=">=version"``.
+ Flask and Pallets policy is to support all Python versions that are not
+ within six months of end of life (EOL). See Python's `EOL calendar`_ for
+ timing.
+
+.. _PyPI: https://pypi.org/search/?c=Framework+%3A%3A+Flask
+.. _Discord Chat: https://discord.gg/pallets
+.. _GitHub Discussions: https://github.com/pallets/flask/discussions
+.. _Official Pallets Themes: https://pypi.org/project/Pallets-Sphinx-Themes/
+.. _Pallets-Eco: https://github.com/pallets-eco
+.. _EOL calendar: https://devguide.python.org/versions/
diff --git a/src/flask-main/docs/extensions.rst b/src/flask-main/docs/extensions.rst
new file mode 100644
index 0000000..4713ec8
--- /dev/null
+++ b/src/flask-main/docs/extensions.rst
@@ -0,0 +1,48 @@
+Extensions
+==========
+
+Extensions are extra packages that add functionality to a Flask
+application. For example, an extension might add support for sending
+email or connecting to a database. Some extensions add entire new
+frameworks to help build certain types of applications, like a REST API.
+
+
+Finding Extensions
+------------------
+
+Flask extensions are usually named "Flask-Foo" or "Foo-Flask". You can
+search PyPI for packages tagged with `Framework :: Flask `_.
+
+
+Using Extensions
+----------------
+
+Consult each extension's documentation for installation, configuration,
+and usage instructions. Generally, extensions pull their own
+configuration from :attr:`app.config ` and are
+passed an application instance during initialization. For example,
+an extension called "Flask-Foo" might be used like this::
+
+ from flask_foo import Foo
+
+ foo = Foo()
+
+ app = Flask(__name__)
+ app.config.update(
+ FOO_BAR='baz',
+ FOO_SPAM='eggs',
+ )
+
+ foo.init_app(app)
+
+
+Building Extensions
+-------------------
+
+While `PyPI `_ contains many Flask extensions, you may not find
+an extension that fits your need. If this is the case, you can create
+your own, and publish it for others to use as well. Read
+:doc:`extensiondev` to develop your own Flask extension.
+
+
+.. _pypi: https://pypi.org/search/?c=Framework+%3A%3A+Flask
diff --git a/src/flask-main/docs/index.rst b/src/flask-main/docs/index.rst
new file mode 100644
index 0000000..63fdb86
--- /dev/null
+++ b/src/flask-main/docs/index.rst
@@ -0,0 +1,88 @@
+.. rst-class:: hide-header
+
+Welcome to Flask
+================
+
+.. image:: _static/flask-name.svg
+ :align: center
+ :height: 200px
+
+Welcome to Flask's documentation. Flask is a lightweight WSGI web application framework.
+It is designed to make getting started quick and easy, with the ability to scale up to
+complex applications.
+
+Get started with :doc:`installation`
+and then get an overview with the :doc:`quickstart`. There is also a
+more detailed :doc:`tutorial/index` that shows how to create a small but
+complete application with Flask. Common patterns are described in the
+:doc:`patterns/index` section. The rest of the docs describe each
+component of Flask in detail, with a full reference in the :doc:`api`
+section.
+
+Flask depends on the `Werkzeug`_ WSGI toolkit, the `Jinja`_ template engine, and the
+`Click`_ CLI toolkit. Be sure to check their documentation as well as Flask's when
+looking for information.
+
+.. _Werkzeug: https://werkzeug.palletsprojects.com
+.. _Jinja: https://jinja.palletsprojects.com
+.. _Click: https://click.palletsprojects.com
+
+
+User's Guide
+------------
+
+Flask provides configuration and conventions, with sensible defaults, to get started.
+This section of the documentation explains the different parts of the Flask framework
+and how they can be used, customized, and extended. Beyond Flask itself, look for
+community-maintained extensions to add even more functionality.
+
+.. toctree::
+ :maxdepth: 2
+
+ installation
+ quickstart
+ tutorial/index
+ templating
+ testing
+ errorhandling
+ debugging
+ logging
+ config
+ signals
+ views
+ lifecycle
+ appcontext
+ blueprints
+ extensions
+ cli
+ server
+ shell
+ patterns/index
+ web-security
+ deploying/index
+ async-await
+
+
+API Reference
+-------------
+
+If you are looking for information on a specific function, class or
+method, this part of the documentation is for you.
+
+.. toctree::
+ :maxdepth: 2
+
+ api
+
+
+Additional Notes
+----------------
+
+.. toctree::
+ :maxdepth: 2
+
+ design
+ extensiondev
+ contributing
+ license
+ changes
diff --git a/src/flask-main/docs/installation.rst b/src/flask-main/docs/installation.rst
new file mode 100644
index 0000000..aed389e
--- /dev/null
+++ b/src/flask-main/docs/installation.rst
@@ -0,0 +1,144 @@
+Installation
+============
+
+
+Python Version
+--------------
+
+We recommend using the latest version of Python. Flask supports Python 3.10 and newer.
+
+
+Dependencies
+------------
+
+These distributions will be installed automatically when installing Flask.
+
+* `Werkzeug`_ implements WSGI, the standard Python interface between
+ applications and servers.
+* `Jinja`_ is a template language that renders the pages your application
+ serves.
+* `MarkupSafe`_ comes with Jinja. It escapes untrusted input when rendering
+ templates to avoid injection attacks.
+* `ItsDangerous`_ securely signs data to ensure its integrity. This is used
+ to protect Flask's session cookie.
+* `Click`_ is a framework for writing command line applications. It provides
+ the ``flask`` command and allows adding custom management commands.
+* `Blinker`_ provides support for :doc:`signals`.
+
+.. _Werkzeug: https://palletsprojects.com/p/werkzeug/
+.. _Jinja: https://palletsprojects.com/p/jinja/
+.. _MarkupSafe: https://palletsprojects.com/p/markupsafe/
+.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
+.. _Click: https://palletsprojects.com/p/click/
+.. _Blinker: https://blinker.readthedocs.io/
+
+
+Optional dependencies
+~~~~~~~~~~~~~~~~~~~~~
+
+These distributions will not be installed automatically. Flask will detect and
+use them if you install them.
+
+* `python-dotenv`_ enables support for :ref:`dotenv` when running ``flask``
+ commands.
+* `Watchdog`_ provides a faster, more efficient reloader for the development
+ server.
+
+.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
+.. _watchdog: https://pythonhosted.org/watchdog/
+
+
+greenlet
+~~~~~~~~
+
+You may choose to use gevent or eventlet with your application. In this
+case, greenlet>=1.0 is required. When using PyPy, PyPy>=7.3.7 is
+required.
+
+These are not minimum supported versions, they only indicate the first
+versions that added necessary features. You should use the latest
+versions of each.
+
+
+Virtual environments
+--------------------
+
+Use a virtual environment to manage the dependencies for your project, both in
+development and in production.
+
+What problem does a virtual environment solve? The more Python projects you
+have, the more likely it is that you need to work with different versions of
+Python libraries, or even Python itself. Newer versions of libraries for one
+project can break compatibility in another project.
+
+Virtual environments are independent groups of Python libraries, one for each
+project. Packages installed for one project will not affect other projects or
+the operating system's packages.
+
+Python comes bundled with the :mod:`venv` module to create virtual
+environments.
+
+
+.. _install-create-env:
+
+Create an environment
+~~~~~~~~~~~~~~~~~~~~~
+
+Create a project folder and a :file:`.venv` folder within:
+
+.. tabs::
+
+ .. group-tab:: macOS/Linux
+
+ .. code-block:: text
+
+ $ mkdir myproject
+ $ cd myproject
+ $ python3 -m venv .venv
+
+ .. group-tab:: Windows
+
+ .. code-block:: text
+
+ > mkdir myproject
+ > cd myproject
+ > py -3 -m venv .venv
+
+
+.. _install-activate-env:
+
+Activate the environment
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before you work on your project, activate the corresponding environment:
+
+.. tabs::
+
+ .. group-tab:: macOS/Linux
+
+ .. code-block:: text
+
+ $ . .venv/bin/activate
+
+ .. group-tab:: Windows
+
+ .. code-block:: text
+
+ > .venv\Scripts\activate
+
+Your shell prompt will change to show the name of the activated
+environment.
+
+
+Install Flask
+-------------
+
+Within the activated environment, use the following command to install
+Flask:
+
+.. code-block:: sh
+
+ $ pip install Flask
+
+Flask is now installed. Check out the :doc:`/quickstart` or go to the
+:doc:`Documentation Overview `.
diff --git a/src/flask-main/docs/license.rst b/src/flask-main/docs/license.rst
new file mode 100644
index 0000000..2a445f9
--- /dev/null
+++ b/src/flask-main/docs/license.rst
@@ -0,0 +1,5 @@
+BSD-3-Clause License
+====================
+
+.. literalinclude:: ../LICENSE.txt
+ :language: text
diff --git a/src/flask-main/docs/lifecycle.rst b/src/flask-main/docs/lifecycle.rst
new file mode 100644
index 0000000..37d45cd
--- /dev/null
+++ b/src/flask-main/docs/lifecycle.rst
@@ -0,0 +1,171 @@
+Application Structure and Lifecycle
+===================================
+
+Flask makes it pretty easy to write a web application. But there are quite a few
+different parts to an application and to each request it handles. Knowing what happens
+during application setup, serving, and handling requests will help you know what's
+possible in Flask and how to structure your application.
+
+
+Application Setup
+-----------------
+
+The first step in creating a Flask application is creating the application object. Each
+Flask application is an instance of the :class:`.Flask` class, which collects all
+configuration, extensions, and views.
+
+.. code-block:: python
+
+ from flask import Flask
+
+ app = Flask(__name__)
+ app.config.from_mapping(
+ SECRET_KEY="dev",
+ )
+ app.config.from_prefixed_env()
+
+ @app.route("/")
+ def index():
+ return "Hello, World!"
+
+This is known as the "application setup phase", it's the code you write that's outside
+any view functions or other handlers. It can be split up between different modules and
+sub-packages, but all code that you want to be part of your application must be imported
+in order for it to be registered.
+
+All application setup must be completed before you start serving your application and
+handling requests. This is because WSGI servers divide work between multiple workers, or
+can be distributed across multiple machines. If the configuration changed in one worker,
+there's no way for Flask to ensure consistency between other workers.
+
+Flask tries to help developers catch some of these setup ordering issues by showing an
+error if setup-related methods are called after requests are handled. In that case
+you'll see this error:
+
+ The setup method 'route' can no longer be called on the application. It has already
+ handled its first request, any changes will not be applied consistently.
+ Make sure all imports, decorators, functions, etc. needed to set up the application
+ are done before running it.
+
+However, it is not possible for Flask to detect all cases of out-of-order setup. In
+general, don't do anything to modify the ``Flask`` app object and ``Blueprint`` objects
+from within view functions that run during requests. This includes:
+
+- Adding routes, view functions, and other request handlers with ``@app.route``,
+ ``@app.errorhandler``, ``@app.before_request``, etc.
+- Registering blueprints.
+- Loading configuration with ``app.config``.
+- Setting up the Jinja template environment with ``app.jinja_env``.
+- Setting a session interface, instead of the default itsdangerous cookie.
+- Setting a JSON provider with ``app.json``, instead of the default provider.
+- Creating and initializing Flask extensions.
+
+
+Serving the Application
+-----------------------
+
+Flask is a WSGI application framework. The other half of WSGI is the WSGI server. During
+development, Flask, through Werkzeug, provides a development WSGI server with the
+``flask run`` CLI command. When you are done with development, use a production server
+to serve your application, see :doc:`deploying/index`.
+
+Regardless of what server you're using, it will follow the :pep:`3333` WSGI spec. The
+WSGI server will be told how to access your Flask application object, which is the WSGI
+application. Then it will start listening for HTTP requests, translate the request data
+into a WSGI environ, and call the WSGI application with that data. The WSGI application
+will return data that is translated into an HTTP response.
+
+#. Browser or other client makes HTTP request.
+#. WSGI server receives request.
+#. WSGI server converts HTTP data to WSGI ``environ`` dict.
+#. WSGI server calls WSGI application with the ``environ``.
+#. Flask, the WSGI application, does all its internal processing to route the request
+ to a view function, handle errors, etc.
+#. Flask translates View function return into WSGI response data, passes it to WSGI
+ server.
+#. WSGI server creates and send an HTTP response.
+#. Client receives the HTTP response.
+
+
+Middleware
+~~~~~~~~~~
+
+The WSGI application above is a callable that behaves in a certain way. Middleware
+is a WSGI application that wraps another WSGI application. It's a similar concept to
+Python decorators. The outermost middleware will be called by the server. It can modify
+the data passed to it, then call the WSGI application (or further middleware) that it
+wraps, and so on. And it can take the return value of that call and modify it further.
+
+From the WSGI server's perspective, there is one WSGI application, the one it calls
+directly. Typically, Flask is the "real" application at the end of the chain of
+middleware. But even Flask can call further WSGI applications, although that's an
+advanced, uncommon use case.
+
+A common middleware you'll see used with Flask is Werkzeug's
+:class:`~werkzeug.middleware.proxy_fix.ProxyFix`, which modifies the request to look
+like it came directly from a client even if it passed through HTTP proxies on the way.
+There are other middleware that can handle serving static files, authentication, etc.
+
+
+How a Request is Handled
+------------------------
+
+For us, the interesting part of the steps above is when Flask gets called by the WSGI
+server (or middleware). At that point, it will do quite a lot to handle the request and
+generate the response. At the most basic, it will match the URL to a view function, call
+the view function, and pass the return value back to the server. But there are many more
+parts that you can use to customize its behavior.
+
+#. WSGI server calls the Flask object, which calls :meth:`.Flask.wsgi_app`.
+#. An :class:`.AppContext` object is created. This converts the WSGI ``environ``
+ dict into a :class:`.Request` object.
+#. The :doc:`app context ` is pushed, which makes
+ :data:`.current_app`, :data:`.g`, :data:`.request`, and :data:`.session`
+ available.
+#. The :data:`.appcontext_pushed` signal is sent.
+#. The URL is matched against the URL rules registered with the :meth:`~.Flask.route`
+ decorator during application setup. If there is no match, the error - usually a 404,
+ 405, or redirect - is stored to be handled later.
+#. The :data:`.request_started` signal is sent.
+#. Any :meth:`~.Flask.url_value_preprocessor` decorated functions are called.
+#. Any :meth:`~.Flask.before_request` decorated functions are called. If any of
+ these function returns a value it is treated as the response immediately.
+#. If the URL didn't match a route a few steps ago, that error is raised now.
+#. The :meth:`~.Flask.route` decorated view function associated with the matched URL
+ is called and returns a value to be used as the response.
+#. If any step so far raised an exception, and there is an :meth:`~.Flask.errorhandler`
+ decorated function that matches the exception class or HTTP error code, it is
+ called to handle the error and return a response.
+#. Whatever returned a response value - a before request function, the view, or an
+ error handler, that value is converted to a :class:`.Response` object.
+#. Any :func:`~.after_this_request` decorated functions are called, which can modify
+ the response object. They are then cleared.
+#. Any :meth:`~.Flask.after_request` decorated functions are called, which can modify
+ the response object.
+#. The session is saved, persisting any modified session data using the app's
+ :attr:`~.Flask.session_interface`.
+#. The :data:`.request_finished` signal is sent.
+#. If any step so far raised an exception, and it was not handled by an error handler
+ function, it is handled now. HTTP exceptions are treated as responses with their
+ corresponding status code, other exceptions are converted to a generic 500 response.
+ The :data:`.got_request_exception` signal is sent.
+#. The response object's status, headers, and body are returned to the WSGI server.
+#. Any :meth:`~.Flask.teardown_request` decorated functions are called.
+#. The :data:`.request_tearing_down` signal is sent.
+#. Any :meth:`~.Flask.teardown_appcontext` decorated functions are called.
+#. The :data:`.appcontext_tearing_down` signal is sent.
+#. The app context is popped, :data:`.current_app`, :data:`.g`, :data:`.request`,
+ and :data:`.session` are no longer available.
+#. The :data:`.appcontext_popped` signal is sent.
+
+When executing a CLI command or plain app context without request data, the same
+order of steps is followed, omitting the steps that refer to the request.
+
+A :class:`Blueprint` can add handlers for these events that are specific to the
+blueprint. The handlers for a blueprint will run if the blueprint
+owns the route that matches the request.
+
+There are even more decorators and customization points than this, but that aren't part
+of every request lifecycle. They're more specific to certain things you might use during
+a request, such as templates, building URLs, or handling JSON data. See the rest of this
+documentation, as well as the :doc:`api` to explore further.
diff --git a/src/flask-main/docs/logging.rst b/src/flask-main/docs/logging.rst
new file mode 100644
index 0000000..3958824
--- /dev/null
+++ b/src/flask-main/docs/logging.rst
@@ -0,0 +1,183 @@
+Logging
+=======
+
+Flask uses standard Python :mod:`logging`. Messages about your Flask
+application are logged with :meth:`app.logger `,
+which takes the same name as :attr:`app.name `. This
+logger can also be used to log your own messages.
+
+.. code-block:: python
+
+ @app.route('/login', methods=['POST'])
+ def login():
+ user = get_user(request.form['username'])
+
+ if user.check_password(request.form['password']):
+ login_user(user)
+ app.logger.info('%s logged in successfully', user.username)
+ return redirect(url_for('index'))
+ else:
+ app.logger.info('%s failed to log in', user.username)
+ abort(401)
+
+If you don't configure logging, Python's default log level is usually
+'warning'. Nothing below the configured level will be visible.
+
+
+Basic Configuration
+-------------------
+
+When you want to configure logging for your project, you should do it as soon
+as possible when the program starts. If :meth:`app.logger `
+is accessed before logging is configured, it will add a default handler. If
+possible, configure logging before creating the application object.
+
+This example uses :func:`~logging.config.dictConfig` to create a logging
+configuration similar to Flask's default, except for all logs::
+
+ from logging.config import dictConfig
+
+ dictConfig({
+ 'version': 1,
+ 'formatters': {'default': {
+ 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
+ }},
+ 'handlers': {'wsgi': {
+ 'class': 'logging.StreamHandler',
+ 'stream': 'ext://flask.logging.wsgi_errors_stream',
+ 'formatter': 'default'
+ }},
+ 'root': {
+ 'level': 'INFO',
+ 'handlers': ['wsgi']
+ }
+ })
+
+ app = Flask(__name__)
+
+
+Default Configuration
+`````````````````````
+
+If you do not configure logging yourself, Flask will add a
+:class:`~logging.StreamHandler` to :meth:`app.logger `
+automatically. During requests, it will write to the stream specified by the
+WSGI server in ``environ['wsgi.errors']`` (which is usually
+:data:`sys.stderr`). Outside a request, it will log to :data:`sys.stderr`.
+
+
+Removing the Default Handler
+````````````````````````````
+
+If you configured logging after accessing
+:meth:`app.logger `, and need to remove the default
+handler, you can import and remove it::
+
+ from flask.logging import default_handler
+
+ app.logger.removeHandler(default_handler)
+
+
+Email Errors to Admins
+----------------------
+
+When running the application on a remote server for production, you probably
+won't be looking at the log messages very often. The WSGI server will probably
+send log messages to a file, and you'll only check that file if a user tells
+you something went wrong.
+
+To be proactive about discovering and fixing bugs, you can configure a
+:class:`logging.handlers.SMTPHandler` to send an email when errors and higher
+are logged. ::
+
+ import logging
+ from logging.handlers import SMTPHandler
+
+ mail_handler = SMTPHandler(
+ mailhost='127.0.0.1',
+ fromaddr='server-error@example.com',
+ toaddrs=['admin@example.com'],
+ subject='Application Error'
+ )
+ mail_handler.setLevel(logging.ERROR)
+ mail_handler.setFormatter(logging.Formatter(
+ '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
+ ))
+
+ if not app.debug:
+ app.logger.addHandler(mail_handler)
+
+This requires that you have an SMTP server set up on the same server. See the
+Python docs for more information about configuring the handler.
+
+
+Injecting Request Information
+-----------------------------
+
+Seeing more information about the request, such as the IP address, may help
+debugging some errors. You can subclass :class:`logging.Formatter` to inject
+your own fields that can be used in messages. You can change the formatter for
+Flask's default handler, the mail handler defined above, or any other
+handler. ::
+
+ from flask import has_request_context, request
+ from flask.logging import default_handler
+
+ class RequestFormatter(logging.Formatter):
+ def format(self, record):
+ if has_request_context():
+ record.url = request.url
+ record.remote_addr = request.remote_addr
+ else:
+ record.url = None
+ record.remote_addr = None
+
+ return super().format(record)
+
+ formatter = RequestFormatter(
+ '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
+ '%(levelname)s in %(module)s: %(message)s'
+ )
+ default_handler.setFormatter(formatter)
+ mail_handler.setFormatter(formatter)
+
+
+Other Libraries
+---------------
+
+Other libraries may use logging extensively, and you want to see relevant
+messages from those logs too. The simplest way to do this is to add handlers
+to the root logger instead of only the app logger. ::
+
+ from flask.logging import default_handler
+
+ root = logging.getLogger()
+ root.addHandler(default_handler)
+ root.addHandler(mail_handler)
+
+Depending on your project, it may be more useful to configure each logger you
+care about separately, instead of configuring only the root logger. ::
+
+ for logger in (
+ logging.getLogger(app.name),
+ logging.getLogger('sqlalchemy'),
+ logging.getLogger('other_package'),
+ ):
+ logger.addHandler(default_handler)
+ logger.addHandler(mail_handler)
+
+
+Werkzeug
+````````
+
+Werkzeug logs basic request/response information to the ``'werkzeug'`` logger.
+If the root logger has no handlers configured, Werkzeug adds a
+:class:`~logging.StreamHandler` to its logger.
+
+
+Flask Extensions
+````````````````
+
+Depending on the situation, an extension may choose to log to
+:meth:`app.logger ` or its own named logger. Consult each
+extension's documentation for details.
diff --git a/src/flask-main/docs/make.bat b/src/flask-main/docs/make.bat
new file mode 100644
index 0000000..922152e
--- /dev/null
+++ b/src/flask-main/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/src/flask-main/docs/patterns/appdispatch.rst b/src/flask-main/docs/patterns/appdispatch.rst
new file mode 100644
index 0000000..f22c806
--- /dev/null
+++ b/src/flask-main/docs/patterns/appdispatch.rst
@@ -0,0 +1,189 @@
+Application Dispatching
+=======================
+
+Application dispatching is the process of combining multiple Flask
+applications on the WSGI level. You can combine not only Flask
+applications but any WSGI application. This would allow you to run a
+Django and a Flask application in the same interpreter side by side if
+you want. The usefulness of this depends on how the applications work
+internally.
+
+The fundamental difference from :doc:`packages` is that in this case you
+are running the same or different Flask applications that are entirely
+isolated from each other. They run different configurations and are
+dispatched on the WSGI level.
+
+
+Working with this Document
+--------------------------
+
+Each of the techniques and examples below results in an ``application``
+object that can be run with any WSGI server. For development, use the
+``flask run`` command to start a development server. For production, see
+:doc:`/deploying/index`.
+
+.. code-block:: python
+
+ from flask import Flask
+
+ app = Flask(__name__)
+
+ @app.route('/')
+ def hello_world():
+ return 'Hello World!'
+
+
+Combining Applications
+----------------------
+
+If you have entirely separated applications and you want them to work next
+to each other in the same Python interpreter process you can take
+advantage of the :class:`werkzeug.wsgi.DispatcherMiddleware`. The idea
+here is that each Flask application is a valid WSGI application and they
+are combined by the dispatcher middleware into a larger one that is
+dispatched based on prefix.
+
+For example you could have your main application run on ``/`` and your
+backend interface on ``/backend``.
+
+.. code-block:: python
+
+ from werkzeug.middleware.dispatcher import DispatcherMiddleware
+ from frontend_app import application as frontend
+ from backend_app import application as backend
+
+ application = DispatcherMiddleware(frontend, {
+ '/backend': backend
+ })
+
+
+Dispatch by Subdomain
+---------------------
+
+Sometimes you might want to use multiple instances of the same application
+with different configurations. Assuming the application is created inside
+a function and you can call that function to instantiate it, that is
+really easy to implement. In order to develop your application to support
+creating new instances in functions have a look at the
+:doc:`appfactories` pattern.
+
+A very common example would be creating applications per subdomain. For
+instance you configure your webserver to dispatch all requests for all
+subdomains to your application and you then use the subdomain information
+to create user-specific instances. Once you have your server set up to
+listen on all subdomains you can use a very simple WSGI application to do
+the dynamic application creation.
+
+The perfect level for abstraction in that regard is the WSGI layer. You
+write your own WSGI application that looks at the request that comes and
+delegates it to your Flask application. If that application does not
+exist yet, it is dynamically created and remembered.
+
+.. code-block:: python
+
+ from threading import Lock
+
+ class SubdomainDispatcher:
+
+ def __init__(self, domain, create_app):
+ self.domain = domain
+ self.create_app = create_app
+ self.lock = Lock()
+ self.instances = {}
+
+ def get_application(self, host):
+ host = host.split(':')[0]
+ assert host.endswith(self.domain), 'Configuration error'
+ subdomain = host[:-len(self.domain)].rstrip('.')
+ with self.lock:
+ app = self.instances.get(subdomain)
+ if app is None:
+ app = self.create_app(subdomain)
+ self.instances[subdomain] = app
+ return app
+
+ def __call__(self, environ, start_response):
+ app = self.get_application(environ['HTTP_HOST'])
+ return app(environ, start_response)
+
+
+This dispatcher can then be used like this:
+
+.. code-block:: python
+
+ from myapplication import create_app, get_user_for_subdomain
+ from werkzeug.exceptions import NotFound
+
+ def make_app(subdomain):
+ user = get_user_for_subdomain(subdomain)
+ if user is None:
+ # if there is no user for that subdomain we still have
+ # to return a WSGI application that handles that request.
+ # We can then just return the NotFound() exception as
+ # application which will render a default 404 page.
+ # You might also redirect the user to the main page then
+ return NotFound()
+
+ # otherwise create the application for the specific user
+ return create_app(user)
+
+ application = SubdomainDispatcher('example.com', make_app)
+
+
+Dispatch by Path
+----------------
+
+Dispatching by a path on the URL is very similar. Instead of looking at
+the ``Host`` header to figure out the subdomain one simply looks at the
+request path up to the first slash.
+
+.. code-block:: python
+
+ from threading import Lock
+ from wsgiref.util import shift_path_info
+
+ class PathDispatcher:
+
+ def __init__(self, default_app, create_app):
+ self.default_app = default_app
+ self.create_app = create_app
+ self.lock = Lock()
+ self.instances = {}
+
+ def get_application(self, prefix):
+ with self.lock:
+ app = self.instances.get(prefix)
+ if app is None:
+ app = self.create_app(prefix)
+ if app is not None:
+ self.instances[prefix] = app
+ return app
+
+ def __call__(self, environ, start_response):
+ app = self.get_application(_peek_path_info(environ))
+ if app is not None:
+ shift_path_info(environ)
+ else:
+ app = self.default_app
+ return app(environ, start_response)
+
+ def _peek_path_info(environ):
+ segments = environ.get("PATH_INFO", "").lstrip("/").split("/", 1)
+ if segments:
+ return segments[0]
+
+ return None
+
+The big difference between this and the subdomain one is that this one
+falls back to another application if the creator function returns ``None``.
+
+.. code-block:: python
+
+ from myapplication import create_app, default_app, get_user_for_prefix
+
+ def make_app(prefix):
+ user = get_user_for_prefix(prefix)
+ if user is not None:
+ return create_app(user)
+
+ application = PathDispatcher(default_app, make_app)
diff --git a/src/flask-main/docs/patterns/appfactories.rst b/src/flask-main/docs/patterns/appfactories.rst
new file mode 100644
index 0000000..0f24878
--- /dev/null
+++ b/src/flask-main/docs/patterns/appfactories.rst
@@ -0,0 +1,118 @@
+Application Factories
+=====================
+
+If you are already using packages and blueprints for your application
+(:doc:`/blueprints`) there are a couple of really nice ways to further improve
+the experience. A common pattern is creating the application object when
+the blueprint is imported. But if you move the creation of this object
+into a function, you can then create multiple instances of this app later.
+
+So why would you want to do this?
+
+1. Testing. You can have instances of the application with different
+ settings to test every case.
+2. Multiple instances. Imagine you want to run different versions of the
+ same application. Of course you could have multiple instances with
+ different configs set up in your webserver, but if you use factories,
+ you can have multiple instances of the same application running in the
+ same application process which can be handy.
+
+So how would you then actually implement that?
+
+Basic Factories
+---------------
+
+The idea is to set up the application in a function. Like this::
+
+ def create_app(config_filename):
+ app = Flask(__name__)
+ app.config.from_pyfile(config_filename)
+
+ from yourapplication.model import db
+ db.init_app(app)
+
+ from yourapplication.views.admin import admin
+ from yourapplication.views.frontend import frontend
+ app.register_blueprint(admin)
+ app.register_blueprint(frontend)
+
+ return app
+
+The downside is that you cannot use the application object in the blueprints
+at import time. You can however use it from within a request. How do you
+get access to the application with the config? Use
+:data:`~flask.current_app`::
+
+ from flask import current_app, Blueprint, render_template
+ admin = Blueprint('admin', __name__, url_prefix='/admin')
+
+ @admin.route('/')
+ def index():
+ return render_template(current_app.config['INDEX_TEMPLATE'])
+
+Here we look up the name of a template in the config.
+
+Factories & Extensions
+----------------------
+
+It's preferable to create your extensions and app factories so that the
+extension object does not initially get bound to the application.
+
+Using `Flask-SQLAlchemy `_,
+as an example, you should not do something along those lines::
+
+ def create_app(config_filename):
+ app = Flask(__name__)
+ app.config.from_pyfile(config_filename)
+
+ db = SQLAlchemy(app)
+
+But, rather, in model.py (or equivalent)::
+
+ db = SQLAlchemy()
+
+and in your application.py (or equivalent)::
+
+ def create_app(config_filename):
+ app = Flask(__name__)
+ app.config.from_pyfile(config_filename)
+
+ from yourapplication.model import db
+ db.init_app(app)
+
+Using this design pattern, no application-specific state is stored on the
+extension object, so one extension object can be used for multiple apps.
+For more information about the design of extensions refer to :doc:`/extensiondev`.
+
+Using Applications
+------------------
+
+To run such an application, you can use the :command:`flask` command:
+
+.. code-block:: text
+
+ $ flask --app hello run
+
+Flask will automatically detect the factory if it is named
+``create_app`` or ``make_app`` in ``hello``. You can also pass arguments
+to the factory like this:
+
+.. code-block:: text
+
+ $ flask --app 'hello:create_app(local_auth=True)' run
+
+Then the ``create_app`` factory in ``hello`` is called with the keyword
+argument ``local_auth=True``. See :doc:`/cli` for more detail.
+
+Factory Improvements
+--------------------
+
+The factory function above is not very clever, but you can improve it.
+The following changes are straightforward to implement:
+
+1. Make it possible to pass in configuration values for unit tests so that
+ you don't have to create config files on the filesystem.
+2. Call a function from a blueprint when the application is setting up so
+ that you have a place to modify attributes of the application (like
+ hooking in before/after request handlers etc.)
+3. Add in WSGI middlewares when the application is being created if necessary.
diff --git a/src/flask-main/docs/patterns/caching.rst b/src/flask-main/docs/patterns/caching.rst
new file mode 100644
index 0000000..9bf7b72
--- /dev/null
+++ b/src/flask-main/docs/patterns/caching.rst
@@ -0,0 +1,16 @@
+Caching
+=======
+
+When your application runs slow, throw some caches in. Well, at least
+it's the easiest way to speed up things. What does a cache do? Say you
+have a function that takes some time to complete but the results would
+still be good enough if they were 5 minutes old. So then the idea is that
+you actually put the result of that calculation into a cache for some
+time.
+
+Flask itself does not provide caching for you, but `Flask-Caching`_, an
+extension for Flask does. Flask-Caching supports various backends, and it is
+even possible to develop your own caching backend.
+
+
+.. _Flask-Caching: https://flask-caching.readthedocs.io/en/latest/
diff --git a/src/flask-main/docs/patterns/celery.rst b/src/flask-main/docs/patterns/celery.rst
new file mode 100644
index 0000000..2e9a43a
--- /dev/null
+++ b/src/flask-main/docs/patterns/celery.rst
@@ -0,0 +1,242 @@
+Background Tasks with Celery
+============================
+
+If your application has a long running task, such as processing some uploaded data or
+sending email, you don't want to wait for it to finish during a request. Instead, use a
+task queue to send the necessary data to another process that will run the task in the
+background while the request returns immediately.
+
+`Celery`_ is a powerful task queue that can be used for simple background tasks as well
+as complex multi-stage programs and schedules. This guide will show you how to configure
+Celery using Flask. Read Celery's `First Steps with Celery`_ guide to learn how to use
+Celery itself.
+
+.. _Celery: https://celery.readthedocs.io
+.. _First Steps with Celery: https://celery.readthedocs.io/en/latest/getting-started/first-steps-with-celery.html
+
+The Flask repository contains `an example `_
+based on the information on this page, which also shows how to use JavaScript to submit
+tasks and poll for progress and results.
+
+
+Install
+-------
+
+Install Celery from PyPI, for example using pip:
+
+.. code-block:: text
+
+ $ pip install celery
+
+
+Integrate Celery with Flask
+---------------------------
+
+You can use Celery without any integration with Flask, but it's convenient to configure
+it through Flask's config, and to let tasks access the Flask application.
+
+Celery uses similar ideas to Flask, with a ``Celery`` app object that has configuration
+and registers tasks. While creating a Flask app, use the following code to create and
+configure a Celery app as well.
+
+.. code-block:: python
+
+ from celery import Celery, Task
+
+ def celery_init_app(app: Flask) -> Celery:
+ class FlaskTask(Task):
+ def __call__(self, *args: object, **kwargs: object) -> object:
+ with app.app_context():
+ return self.run(*args, **kwargs)
+
+ celery_app = Celery(app.name, task_cls=FlaskTask)
+ celery_app.config_from_object(app.config["CELERY"])
+ celery_app.set_default()
+ app.extensions["celery"] = celery_app
+ return celery_app
+
+This creates and returns a ``Celery`` app object. Celery `configuration`_ is taken from
+the ``CELERY`` key in the Flask configuration. The Celery app is set as the default, so
+that it is seen during each request. The ``Task`` subclass automatically runs task
+functions with a Flask app context active, so that services like your database
+connections are available.
+
+.. _configuration: https://celery.readthedocs.io/en/stable/userguide/configuration.html
+
+Here's a basic ``example.py`` that configures Celery to use Redis for communication. We
+enable a result backend, but ignore results by default. This allows us to store results
+only for tasks where we care about the result.
+
+.. code-block:: python
+
+ from flask import Flask
+
+ app = Flask(__name__)
+ app.config.from_mapping(
+ CELERY=dict(
+ broker_url="redis://localhost",
+ result_backend="redis://localhost",
+ task_ignore_result=True,
+ ),
+ )
+ celery_app = celery_init_app(app)
+
+Point the ``celery worker`` command at this and it will find the ``celery_app`` object.
+
+.. code-block:: text
+
+ $ celery -A example worker --loglevel INFO
+
+You can also run the ``celery beat`` command to run tasks on a schedule. See Celery's
+docs for more information about defining schedules.
+
+.. code-block:: text
+
+ $ celery -A example beat --loglevel INFO
+
+
+Application Factory
+-------------------
+
+When using the Flask application factory pattern, call the ``celery_init_app`` function
+inside the factory. It sets ``app.extensions["celery"]`` to the Celery app object, which
+can be used to get the Celery app from the Flask app returned by the factory.
+
+.. code-block:: python
+
+ def create_app() -> Flask:
+ app = Flask(__name__)
+ app.config.from_mapping(
+ CELERY=dict(
+ broker_url="redis://localhost",
+ result_backend="redis://localhost",
+ task_ignore_result=True,
+ ),
+ )
+ app.config.from_prefixed_env()
+ celery_init_app(app)
+ return app
+
+To use ``celery`` commands, Celery needs an app object, but that's no longer directly
+available. Create a ``make_celery.py`` file that calls the Flask app factory and gets
+the Celery app from the returned Flask app.
+
+.. code-block:: python
+
+ from example import create_app
+
+ flask_app = create_app()
+ celery_app = flask_app.extensions["celery"]
+
+Point the ``celery`` command to this file.
+
+.. code-block:: text
+
+ $ celery -A make_celery worker --loglevel INFO
+ $ celery -A make_celery beat --loglevel INFO
+
+
+Defining Tasks
+--------------
+
+Using ``@celery_app.task`` to decorate task functions requires access to the
+``celery_app`` object, which won't be available when using the factory pattern. It also
+means that the decorated tasks are tied to the specific Flask and Celery app instances,
+which could be an issue during testing if you change configuration for a test.
+
+Instead, use Celery's ``@shared_task`` decorator. This creates task objects that will
+access whatever the "current app" is, which is a similar concept to Flask's blueprints
+and app context. This is why we called ``celery_app.set_default()`` above.
+
+Here's an example task that adds two numbers together and returns the result.
+
+.. code-block:: python
+
+ from celery import shared_task
+
+ @shared_task(ignore_result=False)
+ def add_together(a: int, b: int) -> int:
+ return a + b
+
+Earlier, we configured Celery to ignore task results by default. Since we want to know
+the return value of this task, we set ``ignore_result=False``. On the other hand, a task
+that didn't need a result, such as sending an email, wouldn't set this.
+
+
+Calling Tasks
+-------------
+
+The decorated function becomes a task object with methods to call it in the background.
+The simplest way is to use the ``delay(*args, **kwargs)`` method. See Celery's docs for
+more methods.
+
+A Celery worker must be running to run the task. Starting a worker is shown in the
+previous sections.
+
+.. code-block:: python
+
+ from flask import request
+
+ @app.post("/add")
+ def start_add() -> dict[str, object]:
+ a = request.form.get("a", type=int)
+ b = request.form.get("b", type=int)
+ result = add_together.delay(a, b)
+ return {"result_id": result.id}
+
+The route doesn't get the task's result immediately. That would defeat the purpose by
+blocking the response. Instead, we return the running task's result id, which we can use
+later to get the result.
+
+
+Getting Results
+---------------
+
+To fetch the result of the task we started above, we'll add another route that takes the
+result id we returned before. We return whether the task is finished (ready), whether it
+finished successfully, and what the return value (or error) was if it is finished.
+
+.. code-block:: python
+
+ from celery.result import AsyncResult
+
+ @app.get("/result/")
+ def task_result(id: str) -> dict[str, object]:
+ result = AsyncResult(id)
+ return {
+ "ready": result.ready(),
+ "successful": result.successful(),
+ "value": result.result if result.ready() else None,
+ }
+
+Now you can start the task using the first route, then poll for the result using the
+second route. This keeps the Flask request workers from being blocked waiting for tasks
+to finish.
+
+The Flask repository contains `an example `_
+using JavaScript to submit tasks and poll for progress and results.
+
+
+Passing Data to Tasks
+---------------------
+
+The "add" task above took two integers as arguments. To pass arguments to tasks, Celery
+has to serialize them to a format that it can pass to other processes. Therefore,
+passing complex objects is not recommended. For example, it would be impossible to pass
+a SQLAlchemy model object, since that object is probably not serializable and is tied to
+the session that queried it.
+
+Pass the minimal amount of data necessary to fetch or recreate any complex data within
+the task. Consider a task that will run when the logged in user asks for an archive of
+their data. The Flask request knows the logged in user, and has the user object queried
+from the database. It got that by querying the database for a given id, so the task can
+do the same thing. Pass the user's id rather than the user object.
+
+.. code-block:: python
+
+ @shared_task
+ def generate_user_archive(user_id: str) -> None:
+ user = db.session.get(User, user_id)
+ ...
+
+ generate_user_archive.delay(current_user.id)
diff --git a/src/flask-main/docs/patterns/deferredcallbacks.rst b/src/flask-main/docs/patterns/deferredcallbacks.rst
new file mode 100644
index 0000000..4ff8814
--- /dev/null
+++ b/src/flask-main/docs/patterns/deferredcallbacks.rst
@@ -0,0 +1,44 @@
+Deferred Request Callbacks
+==========================
+
+One of the design principles of Flask is that response objects are created and
+passed down a chain of potential callbacks that can modify them or replace
+them. When the request handling starts, there is no response object yet. It is
+created as necessary either by a view function or by some other component in
+the system.
+
+What happens if you want to modify the response at a point where the response
+does not exist yet? A common example for that would be a
+:meth:`~flask.Flask.before_request` callback that wants to set a cookie on the
+response object.
+
+One way is to avoid the situation. Very often that is possible. For instance
+you can try to move that logic into a :meth:`~flask.Flask.after_request`
+callback instead. However, sometimes moving code there makes it
+more complicated or awkward to reason about.
+
+As an alternative, you can use :func:`~flask.after_this_request` to register
+callbacks that will execute after only the current request. This way you can
+defer code execution from anywhere in the application, based on the current
+request.
+
+At any time during a request, we can register a function to be called at the
+end of the request. For example you can remember the current language of the
+user in a cookie in a :meth:`~flask.Flask.before_request` callback::
+
+ from flask import request, after_this_request
+
+ @app.before_request
+ def detect_user_language():
+ language = request.cookies.get('user_lang')
+
+ if language is None:
+ language = guess_language_from_request()
+
+ # when the response exists, set a cookie with the language
+ @after_this_request
+ def remember_language(response):
+ response.set_cookie('user_lang', language)
+ return response
+
+ g.language = language
diff --git a/src/flask-main/docs/patterns/favicon.rst b/src/flask-main/docs/patterns/favicon.rst
new file mode 100644
index 0000000..b867854
--- /dev/null
+++ b/src/flask-main/docs/patterns/favicon.rst
@@ -0,0 +1,56 @@
+Adding a favicon
+================
+
+A "favicon" is an icon used by browsers for tabs and bookmarks. This helps
+to distinguish your website and to give it a unique brand.
+
+A common question is how to add a favicon to a Flask application. First, of
+course, you need an icon. It should be 16 × 16 pixels and in the ICO file
+format. This is not a requirement but a de-facto standard supported by all
+relevant browsers. Put the icon in your static directory as
+:file:`favicon.ico`.
+
+Now, to get browsers to find your icon, the correct way is to add a link
+tag in your HTML. So, for example:
+
+.. sourcecode:: html+jinja
+
+
+
+That's all you need for most browsers, however some really old ones do not
+support this standard. The old de-facto standard is to serve this file,
+with this name, at the website root. If your application is not mounted at
+the root path of the domain you either need to configure the web server to
+serve the icon at the root or if you can't do that you're out of luck. If
+however your application is the root you can simply route a redirect::
+
+ app.add_url_rule(
+ "/favicon.ico",
+ endpoint="favicon",
+ redirect_to=url_for("static", filename="favicon.ico"),
+ )
+
+If you want to save the extra redirect request you can also write a view
+using :func:`~flask.send_from_directory`::
+
+ import os
+ from flask import send_from_directory
+
+ @app.route('/favicon.ico')
+ def favicon():
+ return send_from_directory(os.path.join(app.root_path, 'static'),
+ 'favicon.ico', mimetype='image/vnd.microsoft.icon')
+
+We can leave out the explicit mimetype and it will be guessed, but we may
+as well specify it to avoid the extra guessing, as it will always be the
+same.
+
+The above will serve the icon via your application and if possible it's
+better to configure your dedicated web server to serve it; refer to the
+web server's documentation.
+
+See also
+--------
+
+* The `Favicon `_ article on
+ Wikipedia
diff --git a/src/flask-main/docs/patterns/fileuploads.rst b/src/flask-main/docs/patterns/fileuploads.rst
new file mode 100644
index 0000000..304f57d
--- /dev/null
+++ b/src/flask-main/docs/patterns/fileuploads.rst
@@ -0,0 +1,182 @@
+Uploading Files
+===============
+
+Ah yes, the good old problem of file uploads. The basic idea of file
+uploads is actually quite simple. It basically works like this:
+
+1. A ``
+ '''
+
+So what does that :func:`~werkzeug.utils.secure_filename` function actually do?
+Now the problem is that there is that principle called "never trust user
+input". This is also true for the filename of an uploaded file. All
+submitted form data can be forged, and filenames can be dangerous. For
+the moment just remember: always use that function to secure a filename
+before storing it directly on the filesystem.
+
+.. admonition:: Information for the Pros
+
+ So you're interested in what that :func:`~werkzeug.utils.secure_filename`
+ function does and what the problem is if you're not using it? So just
+ imagine someone would send the following information as `filename` to
+ your application::
+
+ filename = "../../../../home/username/.bashrc"
+
+ Assuming the number of ``../`` is correct and you would join this with
+ the ``UPLOAD_FOLDER`` the user might have the ability to modify a file on
+ the server's filesystem he or she should not modify. This does require some
+ knowledge about how the application looks like, but trust me, hackers
+ are patient :)
+
+ Now let's look how that function works:
+
+ >>> secure_filename('../../../../home/username/.bashrc')
+ 'home_username_.bashrc'
+
+We want to be able to serve the uploaded files so they can be downloaded
+by users. We'll define a ``download_file`` view to serve files in the
+upload folder by name. ``url_for("download_file", name=name)`` generates
+download URLs.
+
+.. code-block:: python
+
+ from flask import send_from_directory
+
+ @app.route('/uploads/')
+ def download_file(name):
+ return send_from_directory(app.config["UPLOAD_FOLDER"], name)
+
+If you're using middleware or the HTTP server to serve files, you can
+register the ``download_file`` endpoint as ``build_only`` so ``url_for``
+will work without a view function.
+
+.. code-block:: python
+
+ app.add_url_rule(
+ "/uploads/", endpoint="download_file", build_only=True
+ )
+
+
+Improving Uploads
+-----------------
+
+.. versionadded:: 0.6
+
+So how exactly does Flask handle uploads? Well it will store them in the
+webserver's memory if the files are reasonably small, otherwise in a
+temporary location (as returned by :func:`tempfile.gettempdir`). But how
+do you specify the maximum file size after which an upload is aborted? By
+default Flask will happily accept file uploads with an unlimited amount of
+memory, but you can limit that by setting the ``MAX_CONTENT_LENGTH``
+config key::
+
+ from flask import Flask, Request
+
+ app = Flask(__name__)
+ app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000
+
+The code above will limit the maximum allowed payload to 16 megabytes.
+If a larger file is transmitted, Flask will raise a
+:exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception.
+
+.. admonition:: Connection Reset Issue
+
+ When using the local development server, you may get a connection
+ reset error instead of a 413 response. You will get the correct
+ status response when running the app with a production WSGI server.
+
+This feature was added in Flask 0.6 but can be achieved in older versions
+as well by subclassing the request object. For more information on that
+consult the Werkzeug documentation on file handling.
+
+
+Upload Progress Bars
+--------------------
+
+A while ago many developers had the idea to read the incoming file in
+small chunks and store the upload progress in the database to be able to
+poll the progress with JavaScript from the client. The client asks the
+server every 5 seconds how much it has transmitted, but this is
+something it should already know.
+
+An Easier Solution
+------------------
+
+Now there are better solutions that work faster and are more reliable. There
+are JavaScript libraries like jQuery_ that have form plugins to ease the
+construction of progress bar.
+
+Because the common pattern for file uploads exists almost unchanged in all
+applications dealing with uploads, there are also some Flask extensions that
+implement a full fledged upload mechanism that allows controlling which
+file extensions are allowed to be uploaded.
+
+.. _jQuery: https://jquery.com/
diff --git a/src/flask-main/docs/patterns/flashing.rst b/src/flask-main/docs/patterns/flashing.rst
new file mode 100644
index 0000000..8eb6b3a
--- /dev/null
+++ b/src/flask-main/docs/patterns/flashing.rst
@@ -0,0 +1,148 @@
+Message Flashing
+================
+
+Good applications and user interfaces are all about feedback. If the user
+does not get enough feedback they will probably end up hating the
+application. Flask provides a really simple way to give feedback to a
+user with the flashing system. The flashing system basically makes it
+possible to record a message at the end of a request and access it next
+request and only next request. This is usually combined with a layout
+template that does this. Note that browsers and sometimes web servers enforce
+a limit on cookie sizes. This means that flashing messages that are too
+large for session cookies causes message flashing to fail silently.
+
+Simple Flashing
+---------------
+
+So here is a full example::
+
+ from flask import Flask, flash, redirect, render_template, \
+ request, url_for
+
+ app = Flask(__name__)
+ app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
+
+ @app.route('/')
+ def index():
+ return render_template('index.html')
+
+ @app.route('/login', methods=['GET', 'POST'])
+ def login():
+ error = None
+ if request.method == 'POST':
+ if request.form['username'] != 'admin' or \
+ request.form['password'] != 'secret':
+ error = 'Invalid credentials'
+ else:
+ flash('You were successfully logged in')
+ return redirect(url_for('index'))
+ return render_template('login.html', error=error)
+
+And here is the :file:`layout.html` template which does the magic:
+
+.. sourcecode:: html+jinja
+
+
+ My Application
+ {% with messages = get_flashed_messages() %}
+ {% if messages %}
+
+ {% for message in messages %}
+
{{ message }}
+ {% endfor %}
+
+ {% endif %}
+ {% endwith %}
+ {% block body %}{% endblock %}
+
+Here is the :file:`index.html` template which inherits from :file:`layout.html`:
+
+.. sourcecode:: html+jinja
+
+ {% extends "layout.html" %}
+ {% block body %}
+
Overview
+
Do you want to log in?
+ {% endblock %}
+
+And here is the :file:`login.html` template which also inherits from
+:file:`layout.html`:
+
+.. sourcecode:: html+jinja
+
+ {% extends "layout.html" %}
+ {% block body %}
+
Login
+ {% if error %}
+
Error: {{ error }}
+ {% endif %}
+
+ {% endblock %}
+
+Flashing With Categories
+------------------------
+
+.. versionadded:: 0.3
+
+It is also possible to provide categories when flashing a message. The
+default category if nothing is provided is ``'message'``. Alternative
+categories can be used to give the user better feedback. For example
+error messages could be displayed with a red background.
+
+To flash a message with a different category, just use the second argument
+to the :func:`~flask.flash` function::
+
+ flash('Invalid password provided', 'error')
+
+Inside the template you then have to tell the
+:func:`~flask.get_flashed_messages` function to also return the
+categories. The loop looks slightly different in that situation then:
+
+.. sourcecode:: html+jinja
+
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+
+ {% for category, message in messages %}
+
{{ message }}
+ {% endfor %}
+
+ {% endif %}
+ {% endwith %}
+
+This is just one example of how to render these flashed messages. One
+might also use the category to add a prefix such as
+``Error:`` to the message.
+
+Filtering Flash Messages
+------------------------
+
+.. versionadded:: 0.9
+
+Optionally you can pass a list of categories which filters the results of
+:func:`~flask.get_flashed_messages`. This is useful if you wish to
+render each category in a separate block.
+
+.. sourcecode:: html+jinja
+
+ {% with errors = get_flashed_messages(category_filter=["error"]) %}
+ {% if errors %}
+
+ {% endif %}
+ {% endwith %}
diff --git a/src/flask-main/docs/patterns/index.rst b/src/flask-main/docs/patterns/index.rst
new file mode 100644
index 0000000..1f2c07d
--- /dev/null
+++ b/src/flask-main/docs/patterns/index.rst
@@ -0,0 +1,40 @@
+Patterns for Flask
+==================
+
+Certain features and interactions are common enough that you will find
+them in most web applications. For example, many applications use a
+relational database and user authentication. They will open a database
+connection at the beginning of the request and get the information for
+the logged in user. At the end of the request, the database connection
+is closed.
+
+These types of patterns may be a bit outside the scope of Flask itself,
+but Flask makes it easy to implement them. Some common patterns are
+collected in the following pages.
+
+.. toctree::
+ :maxdepth: 2
+
+ packages
+ appfactories
+ appdispatch
+ urlprocessors
+ sqlite3
+ sqlalchemy
+ fileuploads
+ caching
+ viewdecorators
+ wtforms
+ templateinheritance
+ flashing
+ javascript
+ lazyloading
+ mongoengine
+ favicon
+ streaming
+ deferredcallbacks
+ methodoverrides
+ requestchecksum
+ celery
+ subclassing
+ singlepageapplications
diff --git a/src/flask-main/docs/patterns/javascript.rst b/src/flask-main/docs/patterns/javascript.rst
new file mode 100644
index 0000000..d58a3eb
--- /dev/null
+++ b/src/flask-main/docs/patterns/javascript.rst
@@ -0,0 +1,259 @@
+JavaScript, ``fetch``, and JSON
+===============================
+
+You may want to make your HTML page dynamic, by changing data without
+reloading the entire page. Instead of submitting an HTML ``