+
+
+
diff --git a/docs/_static/debugger.png b/flask-docs/_images/debugger.png
similarity index 100%
rename from docs/_static/debugger.png
rename to flask-docs/_images/debugger.png
diff --git a/docs/_static/flask-horizontal.png b/flask-docs/_images/flask-horizontal.png
similarity index 100%
rename from docs/_static/flask-horizontal.png
rename to flask-docs/_images/flask-horizontal.png
diff --git a/flask-docs/_images/flaskr_edit.png b/flask-docs/_images/flaskr_edit.png
new file mode 100644
index 00000000..6cd6e398
Binary files /dev/null and b/flask-docs/_images/flaskr_edit.png differ
diff --git a/flask-docs/_images/flaskr_index.png b/flask-docs/_images/flaskr_index.png
new file mode 100644
index 00000000..aa2b50f5
Binary files /dev/null and b/flask-docs/_images/flaskr_index.png differ
diff --git a/flask-docs/_images/flaskr_login.png b/flask-docs/_images/flaskr_login.png
new file mode 100644
index 00000000..d482c645
Binary files /dev/null and b/flask-docs/_images/flaskr_login.png differ
diff --git a/docs/_static/pycharm-run-config.png b/flask-docs/_images/pycharm-run-config.png
similarity index 100%
rename from docs/_static/pycharm-run-config.png
rename to flask-docs/_images/pycharm-run-config.png
diff --git a/flask-docs/_sources/api.rst.txt b/flask-docs/_sources/api.rst.txt
new file mode 100644
index 00000000..1aa8048f
--- /dev/null
+++ b/flask-docs/_sources/api.rst.txt
@@ -0,0 +1,717 @@
+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
+
+.. attribute:: request
+
+ To access incoming request data, you can use the global `request`
+ object. Flask parses incoming request data for you and gives you
+ access to it through that global object. Internally Flask makes
+ sure that you always get the correct data for the active thread if you
+ are in a multithreaded environment.
+
+ This is a proxy. See :ref:`notes-on-proxies` for more information.
+
+ The request object is an instance of a :class:`~flask.Request`.
+
+
+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 :class:`session` object:
+
+.. class:: session
+
+ The session object works pretty much like an ordinary dict, with the
+ difference that it keeps track of modifications.
+
+ This is a proxy. See :ref:`notes-on-proxies` for more information.
+
+ The following attributes are interesting:
+
+ .. attribute:: new
+
+ ``True`` if the session is new, ``False`` otherwise.
+
+ .. attribute:: modified
+
+ ``True`` if the session object detected a modification. Be advised
+ that modifications on mutable structures are not picked up
+ automatically, in that situation you have to explicitly set the
+ attribute to ``True`` yourself. Here an example::
+
+ # this change is not picked up because a mutable object (here
+ # a list) is changed.
+ session['objects'].append(42)
+ # so mark it as modified yourself
+ session.modified = True
+
+ .. attribute:: permanent
+
+ If set to ``True`` the session lives for
+ :attr:`~flask.Flask.permanent_session_lifetime` seconds. The
+ default is 31 days. If set to ``False`` (which is the default) the
+ session will be deleted when the user closes the browser.
+
+
+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 :class:`request` and :class:`session`.
+
+.. data:: g
+
+ A namespace object that can store data during an
+ :doc:`application context `. This is an instance of
+ :attr:`Flask.app_ctx_globals_class`, which defaults to
+ :class:`ctx._AppCtxGlobals`.
+
+ This is a good place to store resources during a request. For
+ example, a ``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 a proxy. See :ref:`notes-on-proxies` 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 application handling the current request. 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:`application context ` is pushed. This happens
+ automatically during requests and CLI commands. It can be controlled
+ manually with :meth:`~flask.Flask.app_context`.
+
+ This is a proxy. See :ref:`notes-on-proxies` 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.RequestContext
+ :members:
+
+.. data:: flask.globals.request_ctx
+
+ The current :class:`~flask.ctx.RequestContext`. If a request context
+ is not active, accessing attributes on this proxy will raise a
+ ``RuntimeError``.
+
+ 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:`request` and :data:`session` instead.
+
+.. autoclass:: flask.ctx.AppContext
+ :members:
+
+.. data:: flask.globals.app_ctx
+
+ The current :class:`~flask.ctx.AppContext`. If an app context is not
+ active, accessing attributes on this proxy will raise a
+ ``RuntimeError``.
+
+ 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` and :data:`g` instead.
+
+.. 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/flask-docs/_sources/appcontext.rst.txt b/flask-docs/_sources/appcontext.rst.txt
new file mode 100644
index 00000000..5509a9a7
--- /dev/null
+++ b/flask-docs/_sources/appcontext.rst.txt
@@ -0,0 +1,147 @@
+.. currentmodule:: flask
+
+The Application Context
+=======================
+
+The application context keeps track of the application-level data during
+a request, CLI command, or other activity. Rather than passing the
+application around to each function, the :data:`current_app` and
+:data:`g` proxies are accessed instead.
+
+This is similar to :doc:`/reqcontext`, which keeps track of
+request-level data during a request. A corresponding application context
+is pushed when a request context is pushed.
+
+Purpose of the Context
+----------------------
+
+The :class:`Flask` application object has attributes, such as
+:attr:`~Flask.config`, that are useful to access within views and
+:doc:`CLI commands `. 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.
+
+Flask solves this issue with the *application context*. Rather than
+referring to an ``app`` directly, you use the :data:`current_app`
+proxy, which points to the application handling the current activity.
+
+Flask automatically *pushes* an application context when handling a
+request. View functions, error handlers, and other functions that run
+during a request will have access to :data:`current_app`.
+
+Flask will also automatically push an app context when running CLI
+commands registered with :attr:`Flask.cli` using ``@app.cli.command()``.
+
+
+Lifetime of the Context
+-----------------------
+
+The application context is created and destroyed as necessary. When a
+Flask application begins handling a request, it pushes an application
+context and a :doc:`request context `. When the request
+ends it pops the request context then the application context.
+Typically, an application context will have the same lifetime as a
+request.
+
+See :doc:`/reqcontext` for more information about how the contexts work
+and the full life cycle of a request.
+
+
+Manually Push a Context
+-----------------------
+
+If you try to access :data:`current_app`, or anything that uses it,
+outside an application context, you'll get this error message:
+
+.. code-block:: pytb
+
+ RuntimeError: Working outside of application context.
+
+ This typically means that you attempted to use functionality that
+ needed to interface with the current application object in some way.
+ To solve this, set up an application context with app.app_context().
+
+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, and everything that runs in the block will have access
+to :data:`current_app`. ::
+
+ 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
+configuring the application, it most likely indicates that you should
+move that code into a view function or CLI command.
+
+
+Storing Data
+------------
+
+The application context is a good place to store common data during a
+request or CLI command. Flask provides the :data:`g object ` for this
+purpose. It is a simple namespace object that has the same lifetime as
+an application context.
+
+.. note::
+ The ``g`` name stands for "global", but that is referring to the
+ data being global *within a context*. The data on ``g`` is lost
+ after the context ends, and it is not an appropriate place to store
+ data between requests. Use the :data:`session` or a database to
+ store data across requests.
+
+A common use for :data:`g` is to manage resources during a request.
+
+1. ``get_X()`` creates resource ``X`` if it does not exist, caching it
+ as ``g.X``.
+2. ``teardown_X()`` closes or otherwise deallocates the resource if it
+ exists. It is registered as a :meth:`~Flask.teardown_appcontext`
+ handler.
+
+For example, you can manage a database connection using this pattern::
+
+ from flask import g
+
+ def get_db():
+ if 'db' not in g:
+ g.db = connect_to_database()
+
+ return g.db
+
+ @app.teardown_appcontext
+ def teardown_db(exception):
+ db = g.pop('db', None)
+
+ if db is not None:
+ db.close()
+
+During a request, every call to ``get_db()`` will return the same
+connection, and it will be closed automatically at the end of the
+request.
+
+You can use :class:`~werkzeug.local.LocalProxy` to make a new context
+local from ``get_db()``::
+
+ from werkzeug.local import LocalProxy
+ db = LocalProxy(get_db)
+
+Accessing ``db`` will call ``get_db`` internally, in the same way that
+:data:`current_app` works.
+
+
+Events and Signals
+------------------
+
+The application will call functions registered with :meth:`~Flask.teardown_appcontext`
+when the application context is popped.
+
+The following signals are sent: :data:`appcontext_pushed`,
+:data:`appcontext_tearing_down`, and :data:`appcontext_popped`.
diff --git a/flask-docs/_sources/async-await.rst.txt b/flask-docs/_sources/async-await.rst.txt
new file mode 100644
index 00000000..16b61945
--- /dev/null
+++ b/flask-docs/_sources/async-await.rst.txt
@@ -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/flask-docs/_sources/blueprints.rst.txt b/flask-docs/_sources/blueprints.rst.txt
new file mode 100644
index 00000000..d5cf3d82
--- /dev/null
+++ b/flask-docs/_sources/blueprints.rst.txt
@@ -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/flask-docs/_sources/changes.rst.txt b/flask-docs/_sources/changes.rst.txt
new file mode 100644
index 00000000..955deaf2
--- /dev/null
+++ b/flask-docs/_sources/changes.rst.txt
@@ -0,0 +1,4 @@
+Changes
+=======
+
+.. include:: ../CHANGES.rst
diff --git a/flask-docs/_sources/cli.rst.txt b/flask-docs/_sources/cli.rst.txt
new file mode 100644
index 00000000..a72e6d51
--- /dev/null
+++ b/flask-docs/_sources/cli.rst.txt
@@ -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/flask-docs/_sources/config.rst.txt b/flask-docs/_sources/config.rst.txt
new file mode 100644
index 00000000..5695bbd0
--- /dev/null
+++ b/flask-docs/_sources/config.rst.txt
@@ -0,0 +1,836 @@
+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, most recent
+ first. 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.
+
+ 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/flask-docs/_sources/contributing.rst.txt b/flask-docs/_sources/contributing.rst.txt
new file mode 100644
index 00000000..d44f865f
--- /dev/null
+++ b/flask-docs/_sources/contributing.rst.txt
@@ -0,0 +1,8 @@
+Contributing
+============
+
+See the Pallets `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/flask-docs/_sources/debugging.rst.txt b/flask-docs/_sources/debugging.rst.txt
new file mode 100644
index 00000000..f6b56cab
--- /dev/null
+++ b/flask-docs/_sources/debugging.rst.txt
@@ -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/flask-docs/_sources/deploying/apache-httpd.rst.txt b/flask-docs/_sources/deploying/apache-httpd.rst.txt
new file mode 100644
index 00000000..bdeaf626
--- /dev/null
+++ b/flask-docs/_sources/deploying/apache-httpd.rst.txt
@@ -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/flask-docs/_sources/deploying/asgi.rst.txt b/flask-docs/_sources/deploying/asgi.rst.txt
new file mode 100644
index 00000000..1dc0aa24
--- /dev/null
+++ b/flask-docs/_sources/deploying/asgi.rst.txt
@@ -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/flask-docs/_sources/deploying/eventlet.rst.txt b/flask-docs/_sources/deploying/eventlet.rst.txt
new file mode 100644
index 00000000..8a718b22
--- /dev/null
+++ b/flask-docs/_sources/deploying/eventlet.rst.txt
@@ -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/flask-docs/_sources/deploying/gevent.rst.txt b/flask-docs/_sources/deploying/gevent.rst.txt
new file mode 100644
index 00000000..448b93e7
--- /dev/null
+++ b/flask-docs/_sources/deploying/gevent.rst.txt
@@ -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/flask-docs/_sources/deploying/gunicorn.rst.txt b/flask-docs/_sources/deploying/gunicorn.rst.txt
new file mode 100644
index 00000000..c50edc23
--- /dev/null
+++ b/flask-docs/_sources/deploying/gunicorn.rst.txt
@@ -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/flask-docs/_sources/deploying/index.rst.txt b/flask-docs/_sources/deploying/index.rst.txt
new file mode 100644
index 00000000..4135596a
--- /dev/null
+++ b/flask-docs/_sources/deploying/index.rst.txt
@@ -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/flask-docs/_sources/deploying/mod_wsgi.rst.txt b/flask-docs/_sources/deploying/mod_wsgi.rst.txt
new file mode 100644
index 00000000..23e82279
--- /dev/null
+++ b/flask-docs/_sources/deploying/mod_wsgi.rst.txt
@@ -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/flask-docs/_sources/deploying/nginx.rst.txt b/flask-docs/_sources/deploying/nginx.rst.txt
new file mode 100644
index 00000000..6b25c073
--- /dev/null
+++ b/flask-docs/_sources/deploying/nginx.rst.txt
@@ -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/flask-docs/_sources/deploying/proxy_fix.rst.txt b/flask-docs/_sources/deploying/proxy_fix.rst.txt
new file mode 100644
index 00000000..e2c42e82
--- /dev/null
+++ b/flask-docs/_sources/deploying/proxy_fix.rst.txt
@@ -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/flask-docs/_sources/deploying/uwsgi.rst.txt b/flask-docs/_sources/deploying/uwsgi.rst.txt
new file mode 100644
index 00000000..1f9d5eca
--- /dev/null
+++ b/flask-docs/_sources/deploying/uwsgi.rst.txt
@@ -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/flask-docs/_sources/deploying/waitress.rst.txt b/flask-docs/_sources/deploying/waitress.rst.txt
new file mode 100644
index 00000000..7bdd695b
--- /dev/null
+++ b/flask-docs/_sources/deploying/waitress.rst.txt
@@ -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/flask-docs/_sources/design.rst.txt b/flask-docs/_sources/design.rst.txt
new file mode 100644
index 00000000..066cf107
--- /dev/null
+++ b/flask-docs/_sources/design.rst.txt
@@ -0,0 +1,228 @@
+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: Jinja2. Why doesn't Flask have a
+pluggable template engine interface? You can obviously use a different
+template engine, but Flask will still configure Jinja2 for you. While
+that limitation that Jinja2 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. Jinja2 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 Jinja2's extensive autoescaping support. Also it provides
+ways to access macros from Jinja2 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 Jinja2). 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.
+
+
+Thread Locals
+-------------
+
+Flask uses thread local objects (context local objects in fact, they
+support greenlet contexts as well) for request, session and an extra
+object you can put your own things on (:data:`~flask.g`). Why is that and
+isn't that a bad idea?
+
+Yes it is usually not such a bright idea to use thread locals. They cause
+troubles for servers that are not based on the concept of threads and make
+large applications harder to maintain. However Flask is just not designed
+for large applications or asynchronous servers. Flask wants to make it
+quick and easy to write a traditional web application.
+
+
+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 Jinja2 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/flask-docs/_sources/errorhandling.rst.txt b/flask-docs/_sources/errorhandling.rst.txt
new file mode 100644
index 00000000..faca58c2
--- /dev/null
+++ b/flask-docs/_sources/errorhandling.rst.txt
@@ -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/flask-docs/_sources/extensiondev.rst.txt b/flask-docs/_sources/extensiondev.rst.txt
new file mode 100644
index 00000000..0c74ad92
--- /dev/null
+++ b/flask-docs/_sources/extensiondev.rst.txt
@@ -0,0 +1,304 @@
+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 when a request context is, or when a CLI command is
+run. If you're storing something that should be closed, use
+:meth:`~flask.Flask.teardown_appcontext` to ensure that it gets closed
+when the application 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 itself supports Python >=3.9 as of October 2024, and this will update
+ over time.
+
+.. _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
diff --git a/flask-docs/_sources/extensions.rst.txt b/flask-docs/_sources/extensions.rst.txt
new file mode 100644
index 00000000..4713ec8e
--- /dev/null
+++ b/flask-docs/_sources/extensions.rst.txt
@@ -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/docs/index.rst b/flask-docs/_sources/index.rst.txt
similarity index 100%
rename from docs/index.rst
rename to flask-docs/_sources/index.rst.txt
diff --git a/flask-docs/_sources/installation.rst.txt b/flask-docs/_sources/installation.rst.txt
new file mode 100644
index 00000000..90a314bf
--- /dev/null
+++ b/flask-docs/_sources/installation.rst.txt
@@ -0,0 +1,144 @@
+Installation
+============
+
+
+Python Version
+--------------
+
+We recommend using the latest version of Python. Flask supports Python 3.9 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/flask-docs/_sources/license.rst.txt b/flask-docs/_sources/license.rst.txt
new file mode 100644
index 00000000..2a445f9c
--- /dev/null
+++ b/flask-docs/_sources/license.rst.txt
@@ -0,0 +1,5 @@
+BSD-3-Clause License
+====================
+
+.. literalinclude:: ../LICENSE.txt
+ :language: text
diff --git a/flask-docs/_sources/lifecycle.rst.txt b/flask-docs/_sources/lifecycle.rst.txt
new file mode 100644
index 00000000..2344d98a
--- /dev/null
+++ b/flask-docs/_sources/lifecycle.rst.txt
@@ -0,0 +1,168 @@
+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`.
+#. A :class:`.RequestContext` object is created. This converts the WSGI ``environ``
+ dict into a :class:`.Request` object. It also creates an :class:`AppContext` object.
+#. The :doc:`app context ` is pushed, which makes :data:`.current_app` and
+ :data:`.g` available.
+#. The :data:`.appcontext_pushed` signal is sent.
+#. The :doc:`request context ` is pushed, which makes :attr:`.request` and
+ :class:`.session` available.
+#. The session is opened, loading any existing session data using the app's
+ :attr:`~.Flask.session_interface`, an instance of :class:`.SessionInterface`.
+#. 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, 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.
+#. The request context is popped, :attr:`.request` and :class:`.session` are no longer
+ available.
+#. 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` and :data:`.g` are no longer
+ available.
+#. The :data:`.appcontext_popped` signal is sent.
+
+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/flask-docs/_sources/logging.rst.txt b/flask-docs/_sources/logging.rst.txt
new file mode 100644
index 00000000..39588242
--- /dev/null
+++ b/flask-docs/_sources/logging.rst.txt
@@ -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/flask-docs/_sources/patterns/appdispatch.rst.txt b/flask-docs/_sources/patterns/appdispatch.rst.txt
new file mode 100644
index 00000000..f22c8060
--- /dev/null
+++ b/flask-docs/_sources/patterns/appdispatch.rst.txt
@@ -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/flask-docs/_sources/patterns/appfactories.rst.txt b/flask-docs/_sources/patterns/appfactories.rst.txt
new file mode 100644
index 00000000..0f248783
--- /dev/null
+++ b/flask-docs/_sources/patterns/appfactories.rst.txt
@@ -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/flask-docs/_sources/patterns/caching.rst.txt b/flask-docs/_sources/patterns/caching.rst.txt
new file mode 100644
index 00000000..9bf7b72a
--- /dev/null
+++ b/flask-docs/_sources/patterns/caching.rst.txt
@@ -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/flask-docs/_sources/patterns/celery.rst.txt b/flask-docs/_sources/patterns/celery.rst.txt
new file mode 100644
index 00000000..2e9a43a7
--- /dev/null
+++ b/flask-docs/_sources/patterns/celery.rst.txt
@@ -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/flask-docs/_sources/patterns/deferredcallbacks.rst.txt b/flask-docs/_sources/patterns/deferredcallbacks.rst.txt
new file mode 100644
index 00000000..4ff8814b
--- /dev/null
+++ b/flask-docs/_sources/patterns/deferredcallbacks.rst.txt
@@ -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/flask-docs/_sources/patterns/favicon.rst.txt b/flask-docs/_sources/patterns/favicon.rst.txt
new file mode 100644
index 00000000..b867854f
--- /dev/null
+++ b/flask-docs/_sources/patterns/favicon.rst.txt
@@ -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/flask-docs/_sources/patterns/fileuploads.rst.txt b/flask-docs/_sources/patterns/fileuploads.rst.txt
new file mode 100644
index 00000000..304f57dc
--- /dev/null
+++ b/flask-docs/_sources/patterns/fileuploads.rst.txt
@@ -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/flask-docs/_sources/patterns/flashing.rst.txt b/flask-docs/_sources/patterns/flashing.rst.txt
new file mode 100644
index 00000000..8eb6b3ac
--- /dev/null
+++ b/flask-docs/_sources/patterns/flashing.rst.txt
@@ -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/flask-docs/_sources/patterns/index.rst.txt b/flask-docs/_sources/patterns/index.rst.txt
new file mode 100644
index 00000000..1f2c07dd
--- /dev/null
+++ b/flask-docs/_sources/patterns/index.rst.txt
@@ -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/flask-docs/_sources/patterns/javascript.rst.txt b/flask-docs/_sources/patterns/javascript.rst.txt
new file mode 100644
index 00000000..d58a3eb6
--- /dev/null
+++ b/flask-docs/_sources/patterns/javascript.rst.txt
@@ -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 ``