Format: text/x-python
⬇ Download File (60.3 KB)
   1  from __future__ import annotations
   2  
   3  import collections.abc as cabc
   4  import os
   5  import sys
   6  import typing as t
   7  import weakref
   8  from datetime import timedelta
   9  from inspect import iscoroutinefunction
  10  from itertools import chain
  11  from types import TracebackType
  12  from urllib.parse import quote as _url_quote
  13  
  14  import click
  15  from werkzeug.datastructures import Headers
  16  from werkzeug.datastructures import ImmutableDict
  17  from werkzeug.exceptions import BadRequestKeyError
  18  from werkzeug.exceptions import HTTPException
  19  from werkzeug.exceptions import InternalServerError
  20  from werkzeug.routing import BuildError
  21  from werkzeug.routing import MapAdapter
  22  from werkzeug.routing import RequestRedirect
  23  from werkzeug.routing import RoutingException
  24  from werkzeug.routing import Rule
  25  from werkzeug.serving import is_running_from_reloader
  26  from werkzeug.wrappers import Response as BaseResponse
  27  from werkzeug.wsgi import get_host
  28  
  29  from . import cli
  30  from . import typing as ft
  31  from .ctx import AppContext
  32  from .ctx import RequestContext
  33  from .globals import _cv_app
  34  from .globals import _cv_request
  35  from .globals import current_app
  36  from .globals import g
  37  from .globals import request
  38  from .globals import request_ctx
  39  from .globals import session
  40  from .helpers import get_debug_flag
  41  from .helpers import get_flashed_messages
  42  from .helpers import get_load_dotenv
  43  from .helpers import send_from_directory
  44  from .sansio.app import App
  45  from .sansio.scaffold import _sentinel
  46  from .sessions import SecureCookieSessionInterface
  47  from .sessions import SessionInterface
  48  from .signals import appcontext_tearing_down
  49  from .signals import got_request_exception
  50  from .signals import request_finished
  51  from .signals import request_started
  52  from .signals import request_tearing_down
  53  from .templating import Environment
  54  from .wrappers import Request
  55  from .wrappers import Response
  56  
  57  if t.TYPE_CHECKING:  # pragma: no cover
  58      from _typeshed.wsgi import StartResponse
  59      from _typeshed.wsgi import WSGIEnvironment
  60  
  61      from .testing import FlaskClient
  62      from .testing import FlaskCliRunner
  63      from .typing import HeadersValue
  64  
  65  T_shell_context_processor = t.TypeVar(
  66      "T_shell_context_processor", bound=ft.ShellContextProcessorCallable
  67  )
  68  T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
  69  T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
  70  T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
  71  T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
  72  
  73  
  74  def _make_timedelta(value: timedelta | int | None) -> timedelta | None:
  75      if value is None or isinstance(value, timedelta):
  76          return value
  77  
  78      return timedelta(seconds=value)
  79  
  80  
  81  class Flask(App):
  82      """The flask object implements a WSGI application and acts as the central
  83      object.  It is passed the name of the module or package of the
  84      application.  Once it is created it will act as a central registry for
  85      the view functions, the URL rules, template configuration and much more.
  86  
  87      The name of the package is used to resolve resources from inside the
  88      package or the folder the module is contained in depending on if the
  89      package parameter resolves to an actual python package (a folder with
  90      an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).
  91  
  92      For more information about resource loading, see :func:`open_resource`.
  93  
  94      Usually you create a :class:`Flask` instance in your main module or
  95      in the :file:`__init__.py` file of your package like this::
  96  
  97          from flask import Flask
  98          app = Flask(__name__)
  99  
 100      .. admonition:: About the First Parameter
 101  
 102          The idea of the first parameter is to give Flask an idea of what
 103          belongs to your application.  This name is used to find resources
 104          on the filesystem, can be used by extensions to improve debugging
 105          information and a lot more.
 106  
 107          So it's important what you provide there.  If you are using a single
 108          module, `__name__` is always the correct value.  If you however are
 109          using a package, it's usually recommended to hardcode the name of
 110          your package there.
 111  
 112          For example if your application is defined in :file:`yourapplication/app.py`
 113          you should create it with one of the two versions below::
 114  
 115              app = Flask('yourapplication')
 116              app = Flask(__name__.split('.')[0])
 117  
 118          Why is that?  The application will work even with `__name__`, thanks
 119          to how resources are looked up.  However it will make debugging more
 120          painful.  Certain extensions can make assumptions based on the
 121          import name of your application.  For example the Flask-SQLAlchemy
 122          extension will look for the code in your application that triggered
 123          an SQL query in debug mode.  If the import name is not properly set
 124          up, that debugging information is lost.  (For example it would only
 125          pick up SQL queries in `yourapplication.app` and not
 126          `yourapplication.views.frontend`)
 127  
 128      .. versionadded:: 0.7
 129         The `static_url_path`, `static_folder`, and `template_folder`
 130         parameters were added.
 131  
 132      .. versionadded:: 0.8
 133         The `instance_path` and `instance_relative_config` parameters were
 134         added.
 135  
 136      .. versionadded:: 0.11
 137         The `root_path` parameter was added.
 138  
 139      .. versionadded:: 1.0
 140         The ``host_matching`` and ``static_host`` parameters were added.
 141  
 142      .. versionadded:: 1.0
 143         The ``subdomain_matching`` parameter was added. Subdomain
 144         matching needs to be enabled manually now. Setting
 145         :data:`SERVER_NAME` does not implicitly enable it.
 146  
 147      :param import_name: the name of the application package
 148      :param static_url_path: can be used to specify a different path for the
 149                              static files on the web.  Defaults to the name
 150                              of the `static_folder` folder.
 151      :param static_folder: The folder with static files that is served at
 152          ``static_url_path``. Relative to the application ``root_path``
 153          or an absolute path. Defaults to ``'static'``.
 154      :param static_host: the host to use when adding the static route.
 155          Defaults to None. Required when using ``host_matching=True``
 156          with a ``static_folder`` configured.
 157      :param host_matching: set ``url_map.host_matching`` attribute.
 158          Defaults to False.
 159      :param subdomain_matching: consider the subdomain relative to
 160          :data:`SERVER_NAME` when matching routes. Defaults to False.
 161      :param template_folder: the folder that contains the templates that should
 162                              be used by the application.  Defaults to
 163                              ``'templates'`` folder in the root path of the
 164                              application.
 165      :param instance_path: An alternative instance path for the application.
 166                            By default the folder ``'instance'`` next to the
 167                            package or module is assumed to be the instance
 168                            path.
 169      :param instance_relative_config: if set to ``True`` relative filenames
 170                                       for loading the config are assumed to
 171                                       be relative to the instance path instead
 172                                       of the application root.
 173      :param root_path: The path to the root of the application files.
 174          This should only be set manually when it can't be detected
 175          automatically, such as for namespace packages.
 176      """
 177  
 178      default_config = ImmutableDict(
 179          {
 180              "DEBUG": None,
 181              "TESTING": False,
 182              "PROPAGATE_EXCEPTIONS": None,
 183              "SECRET_KEY": None,
 184              "SECRET_KEY_FALLBACKS": None,
 185              "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
 186              "USE_X_SENDFILE": False,
 187              "TRUSTED_HOSTS": None,
 188              "SERVER_NAME": None,
 189              "APPLICATION_ROOT": "/",
 190              "SESSION_COOKIE_NAME": "session",
 191              "SESSION_COOKIE_DOMAIN": None,
 192              "SESSION_COOKIE_PATH": None,
 193              "SESSION_COOKIE_HTTPONLY": True,
 194              "SESSION_COOKIE_SECURE": False,
 195              "SESSION_COOKIE_PARTITIONED": False,
 196              "SESSION_COOKIE_SAMESITE": None,
 197              "SESSION_REFRESH_EACH_REQUEST": True,
 198              "MAX_CONTENT_LENGTH": None,
 199              "MAX_FORM_MEMORY_SIZE": 500_000,
 200              "MAX_FORM_PARTS": 1_000,
 201              "SEND_FILE_MAX_AGE_DEFAULT": None,
 202              "TRAP_BAD_REQUEST_ERRORS": None,
 203              "TRAP_HTTP_EXCEPTIONS": False,
 204              "EXPLAIN_TEMPLATE_LOADING": False,
 205              "PREFERRED_URL_SCHEME": "http",
 206              "TEMPLATES_AUTO_RELOAD": None,
 207              "MAX_COOKIE_SIZE": 4093,
 208              "PROVIDE_AUTOMATIC_OPTIONS": True,
 209          }
 210      )
 211  
 212      #: The class that is used for request objects.  See :class:`~flask.Request`
 213      #: for more information.
 214      request_class: type[Request] = Request
 215  
 216      #: The class that is used for response objects.  See
 217      #: :class:`~flask.Response` for more information.
 218      response_class: type[Response] = Response
 219  
 220      #: the session interface to use.  By default an instance of
 221      #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
 222      #:
 223      #: .. versionadded:: 0.8
 224      session_interface: SessionInterface = SecureCookieSessionInterface()
 225  
 226      def __init__(
 227          self,
 228          import_name: str,
 229          static_url_path: str | None = None,
 230          static_folder: str | os.PathLike[str] | None = "static",
 231          static_host: str | None = None,
 232          host_matching: bool = False,
 233          subdomain_matching: bool = False,
 234          template_folder: str | os.PathLike[str] | None = "templates",
 235          instance_path: str | None = None,
 236          instance_relative_config: bool = False,
 237          root_path: str | None = None,
 238      ):
 239          super().__init__(
 240              import_name=import_name,
 241              static_url_path=static_url_path,
 242              static_folder=static_folder,
 243              static_host=static_host,
 244              host_matching=host_matching,
 245              subdomain_matching=subdomain_matching,
 246              template_folder=template_folder,
 247              instance_path=instance_path,
 248              instance_relative_config=instance_relative_config,
 249              root_path=root_path,
 250          )
 251  
 252          #: The Click command group for registering CLI commands for this
 253          #: object. The commands are available from the ``flask`` command
 254          #: once the application has been discovered and blueprints have
 255          #: been registered.
 256          self.cli = cli.AppGroup()
 257  
 258          # Set the name of the Click group in case someone wants to add
 259          # the app's commands to another CLI tool.
 260          self.cli.name = self.name
 261  
 262          # Add a static route using the provided static_url_path, static_host,
 263          # and static_folder if there is a configured static_folder.
 264          # Note we do this without checking if static_folder exists.
 265          # For one, it might be created while the server is running (e.g. during
 266          # development). Also, Google App Engine stores static files somewhere
 267          if self.has_static_folder:
 268              assert (
 269                  bool(static_host) == host_matching
 270              ), "Invalid static_host/host_matching combination"
 271              # Use a weakref to avoid creating a reference cycle between the app
 272              # and the view function (see #3761).
 273              self_ref = weakref.ref(self)
 274              self.add_url_rule(
 275                  f"{self.static_url_path}/<path:filename>",
 276                  endpoint="static",
 277                  host=static_host,
 278                  view_func=lambda **kw: self_ref().send_static_file(**kw),  # type: ignore # noqa: B950
 279              )
 280  
 281      def get_send_file_max_age(self, filename: str | None) -> int | None:
 282          """Used by :func:`send_file` to determine the ``max_age`` cache
 283          value for a given file path if it wasn't passed.
 284  
 285          By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from
 286          the configuration of :data:`~flask.current_app`. This defaults
 287          to ``None``, which tells the browser to use conditional requests
 288          instead of a timed cache, which is usually preferable.
 289  
 290          Note this is a duplicate of the same method in the Flask
 291          class.
 292  
 293          .. versionchanged:: 2.0
 294              The default configuration is ``None`` instead of 12 hours.
 295  
 296          .. versionadded:: 0.9
 297          """
 298          value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"]
 299  
 300          if value is None:
 301              return None
 302  
 303          if isinstance(value, timedelta):
 304              return int(value.total_seconds())
 305  
 306          return value  # type: ignore[no-any-return]
 307  
 308      def send_static_file(self, filename: str) -> Response:
 309          """The view function used to serve files from
 310          :attr:`static_folder`. A route is automatically registered for
 311          this view at :attr:`static_url_path` if :attr:`static_folder` is
 312          set.
 313  
 314          Note this is a duplicate of the same method in the Flask
 315          class.
 316  
 317          .. versionadded:: 0.5
 318  
 319          """
 320          if not self.has_static_folder:
 321              raise RuntimeError("'static_folder' must be set to serve static_files.")
 322  
 323          # send_file only knows to call get_send_file_max_age on the app,
 324          # call it here so it works for blueprints too.
 325          max_age = self.get_send_file_max_age(filename)
 326          return send_from_directory(
 327              t.cast(str, self.static_folder), filename, max_age=max_age
 328          )
 329  
 330      def open_resource(
 331          self, resource: str, mode: str = "rb", encoding: str | None = None
 332      ) -> t.IO[t.AnyStr]:
 333          """Open a resource file relative to :attr:`root_path` for reading.
 334  
 335          For example, if the file ``schema.sql`` is next to the file
 336          ``app.py`` where the ``Flask`` app is defined, it can be opened
 337          with:
 338  
 339          .. code-block:: python
 340  
 341              with app.open_resource("schema.sql") as f:
 342                  conn.executescript(f.read())
 343  
 344          :param resource: Path to the resource relative to :attr:`root_path`.
 345          :param mode: Open the file in this mode. Only reading is supported,
 346              valid values are ``"r"`` (or ``"rt"``) and ``"rb"``.
 347          :param encoding: Open the file with this encoding when opening in text
 348              mode. This is ignored when opening in binary mode.
 349  
 350          .. versionchanged:: 3.1
 351              Added the ``encoding`` parameter.
 352          """
 353          if mode not in {"r", "rt", "rb"}:
 354              raise ValueError("Resources can only be opened for reading.")
 355  
 356          path = os.path.join(self.root_path, resource)
 357  
 358          if mode == "rb":
 359              return open(path, mode)  # pyright: ignore
 360  
 361          return open(path, mode, encoding=encoding)
 362  
 363      def open_instance_resource(
 364          self, resource: str, mode: str = "rb", encoding: str | None = "utf-8"
 365      ) -> t.IO[t.AnyStr]:
 366          """Open a resource file relative to the application's instance folder
 367          :attr:`instance_path`. Unlike :meth:`open_resource`, files in the
 368          instance folder can be opened for writing.
 369  
 370          :param resource: Path to the resource relative to :attr:`instance_path`.
 371          :param mode: Open the file in this mode.
 372          :param encoding: Open the file with this encoding when opening in text
 373              mode. This is ignored when opening in binary mode.
 374  
 375          .. versionchanged:: 3.1
 376              Added the ``encoding`` parameter.
 377          """
 378          path = os.path.join(self.instance_path, resource)
 379  
 380          if "b" in mode:
 381              return open(path, mode)
 382  
 383          return open(path, mode, encoding=encoding)
 384  
 385      def create_jinja_environment(self) -> Environment:
 386          """Create the Jinja environment based on :attr:`jinja_options`
 387          and the various Jinja-related methods of the app. Changing
 388          :attr:`jinja_options` after this will have no effect. Also adds
 389          Flask-related globals and filters to the environment.
 390  
 391          .. versionchanged:: 0.11
 392             ``Environment.auto_reload`` set in accordance with
 393             ``TEMPLATES_AUTO_RELOAD`` configuration option.
 394  
 395          .. versionadded:: 0.5
 396          """
 397          options = dict(self.jinja_options)
 398  
 399          if "autoescape" not in options:
 400              options["autoescape"] = self.select_jinja_autoescape
 401  
 402          if "auto_reload" not in options:
 403              auto_reload = self.config["TEMPLATES_AUTO_RELOAD"]
 404  
 405              if auto_reload is None:
 406                  auto_reload = self.debug
 407  
 408              options["auto_reload"] = auto_reload
 409  
 410          rv = self.jinja_environment(self, **options)
 411          rv.globals.update(
 412              url_for=self.url_for,
 413              get_flashed_messages=get_flashed_messages,
 414              config=self.config,
 415              # request, session and g are normally added with the
 416              # context processor for efficiency reasons but for imported
 417              # templates we also want the proxies in there.
 418              request=request,
 419              session=session,
 420              g=g,
 421          )
 422          rv.policies["json.dumps_function"] = self.json.dumps
 423          return rv
 424  
 425      def create_url_adapter(self, request: Request | None) -> MapAdapter | None:
 426          """Creates a URL adapter for the given request. The URL adapter
 427          is created at a point where the request context is not yet set
 428          up so the request is passed explicitly.
 429  
 430          .. versionchanged:: 3.1
 431              If :data:`SERVER_NAME` is set, it does not restrict requests to
 432              only that domain, for both ``subdomain_matching`` and
 433              ``host_matching``.
 434  
 435          .. versionchanged:: 1.0
 436              :data:`SERVER_NAME` no longer implicitly enables subdomain
 437              matching. Use :attr:`subdomain_matching` instead.
 438  
 439          .. versionchanged:: 0.9
 440             This can be called outside a request when the URL adapter is created
 441             for an application context.
 442  
 443          .. versionadded:: 0.6
 444          """
 445          if request is not None:
 446              if (trusted_hosts := self.config["TRUSTED_HOSTS"]) is not None:
 447                  request.trusted_hosts = trusted_hosts
 448  
 449              # Check trusted_hosts here until bind_to_environ does.
 450              request.host = get_host(request.environ, request.trusted_hosts)  # pyright: ignore
 451              subdomain = None
 452              server_name = self.config["SERVER_NAME"]
 453  
 454              if self.url_map.host_matching:
 455                  # Don't pass SERVER_NAME, otherwise it's used and the actual
 456                  # host is ignored, which breaks host matching.
 457                  server_name = None
 458              elif not self.subdomain_matching:
 459                  # Werkzeug doesn't implement subdomain matching yet. Until then,
 460                  # disable it by forcing the current subdomain to the default, or
 461                  # the empty string.
 462                  subdomain = self.url_map.default_subdomain or ""
 463  
 464              return self.url_map.bind_to_environ(
 465                  request.environ, server_name=server_name, subdomain=subdomain
 466              )
 467  
 468          # Need at least SERVER_NAME to match/build outside a request.
 469          if self.config["SERVER_NAME"] is not None:
 470              return self.url_map.bind(
 471                  self.config["SERVER_NAME"],
 472                  script_name=self.config["APPLICATION_ROOT"],
 473                  url_scheme=self.config["PREFERRED_URL_SCHEME"],
 474              )
 475  
 476          return None
 477  
 478      def raise_routing_exception(self, request: Request) -> t.NoReturn:
 479          """Intercept routing exceptions and possibly do something else.
 480  
 481          In debug mode, intercept a routing redirect and replace it with
 482          an error if the body will be discarded.
 483  
 484          With modern Werkzeug this shouldn't occur, since it now uses a
 485          308 status which tells the browser to resend the method and
 486          body.
 487  
 488          .. versionchanged:: 2.1
 489              Don't intercept 307 and 308 redirects.
 490  
 491          :meta private:
 492          :internal:
 493          """
 494          if (
 495              not self.debug
 496              or not isinstance(request.routing_exception, RequestRedirect)
 497              or request.routing_exception.code in {307, 308}
 498              or request.method in {"GET", "HEAD", "OPTIONS"}
 499          ):
 500              raise request.routing_exception  # type: ignore[misc]
 501  
 502          from .debughelpers import FormDataRoutingRedirect
 503  
 504          raise FormDataRoutingRedirect(request)
 505  
 506      def update_template_context(self, context: dict[str, t.Any]) -> None:
 507          """Update the template context with some commonly used variables.
 508          This injects request, session, config and g into the template
 509          context as well as everything template context processors want
 510          to inject.  Note that the as of Flask 0.6, the original values
 511          in the context will not be overridden if a context processor
 512          decides to return a value with the same key.
 513  
 514          :param context: the context as a dictionary that is updated in place
 515                          to add extra variables.
 516          """
 517          names: t.Iterable[str | None] = (None,)
 518  
 519          # A template may be rendered outside a request context.
 520          if request:
 521              names = chain(names, reversed(request.blueprints))
 522  
 523          # The values passed to render_template take precedence. Keep a
 524          # copy to re-apply after all context functions.
 525          orig_ctx = context.copy()
 526  
 527          for name in names:
 528              if name in self.template_context_processors:
 529                  for func in self.template_context_processors[name]:
 530                      context.update(self.ensure_sync(func)())
 531  
 532          context.update(orig_ctx)
 533  
 534      def make_shell_context(self) -> dict[str, t.Any]:
 535          """Returns the shell context for an interactive shell for this
 536          application.  This runs all the registered shell context
 537          processors.
 538  
 539          .. versionadded:: 0.11
 540          """
 541          rv = {"app": self, "g": g}
 542          for processor in self.shell_context_processors:
 543              rv.update(processor())
 544          return rv
 545  
 546      def run(
 547          self,
 548          host: str | None = None,
 549          port: int | None = None,
 550          debug: bool | None = None,
 551          load_dotenv: bool = True,
 552          **options: t.Any,
 553      ) -> None:
 554          """Runs the application on a local development server.
 555  
 556          Do not use ``run()`` in a production setting. It is not intended to
 557          meet security and performance requirements for a production server.
 558          Instead, see :doc:`/deploying/index` for WSGI server recommendations.
 559  
 560          If the :attr:`debug` flag is set the server will automatically reload
 561          for code changes and show a debugger in case an exception happened.
 562  
 563          If you want to run the application in debug mode, but disable the
 564          code execution on the interactive debugger, you can pass
 565          ``use_evalex=False`` as parameter.  This will keep the debugger's
 566          traceback screen active, but disable code execution.
 567  
 568          It is not recommended to use this function for development with
 569          automatic reloading as this is badly supported.  Instead you should
 570          be using the :command:`flask` command line script's ``run`` support.
 571  
 572          .. admonition:: Keep in Mind
 573  
 574             Flask will suppress any server error with a generic error page
 575             unless it is in debug mode.  As such to enable just the
 576             interactive debugger without the code reloading, you have to
 577             invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
 578             Setting ``use_debugger`` to ``True`` without being in debug mode
 579             won't catch any exceptions because there won't be any to
 580             catch.
 581  
 582          :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
 583              have the server available externally as well. Defaults to
 584              ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
 585              if present.
 586          :param port: the port of the webserver. Defaults to ``5000`` or the
 587              port defined in the ``SERVER_NAME`` config variable if present.
 588          :param debug: if given, enable or disable debug mode. See
 589              :attr:`debug`.
 590          :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
 591              files to set environment variables. Will also change the working
 592              directory to the directory containing the first file found.
 593          :param options: the options to be forwarded to the underlying Werkzeug
 594              server. See :func:`werkzeug.serving.run_simple` for more
 595              information.
 596  
 597          .. versionchanged:: 1.0
 598              If installed, python-dotenv will be used to load environment
 599              variables from :file:`.env` and :file:`.flaskenv` files.
 600  
 601              The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`.
 602  
 603              Threaded mode is enabled by default.
 604  
 605          .. versionchanged:: 0.10
 606              The default port is now picked from the ``SERVER_NAME``
 607              variable.
 608          """
 609          # Ignore this call so that it doesn't start another server if
 610          # the 'flask run' command is used.
 611          if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
 612              if not is_running_from_reloader():
 613                  click.secho(
 614                      " * Ignoring a call to 'app.run()' that would block"
 615                      " the current 'flask' CLI command.\n"
 616                      "   Only call 'app.run()' in an 'if __name__ =="
 617                      ' "__main__"\' guard.',
 618                      fg="red",
 619                  )
 620  
 621              return
 622  
 623          if get_load_dotenv(load_dotenv):
 624              cli.load_dotenv()
 625  
 626              # if set, env var overrides existing value
 627              if "FLASK_DEBUG" in os.environ:
 628                  self.debug = get_debug_flag()
 629  
 630          # debug passed to method overrides all other sources
 631          if debug is not None:
 632              self.debug = bool(debug)
 633  
 634          server_name = self.config.get("SERVER_NAME")
 635          sn_host = sn_port = None
 636  
 637          if server_name:
 638              sn_host, _, sn_port = server_name.partition(":")
 639  
 640          if not host:
 641              if sn_host:
 642                  host = sn_host
 643              else:
 644                  host = "127.0.0.1"
 645  
 646          if port or port == 0:
 647              port = int(port)
 648          elif sn_port:
 649              port = int(sn_port)
 650          else:
 651              port = 5000
 652  
 653          options.setdefault("use_reloader", self.debug)
 654          options.setdefault("use_debugger", self.debug)
 655          options.setdefault("threaded", True)
 656  
 657          cli.show_server_banner(self.debug, self.name)
 658  
 659          from werkzeug.serving import run_simple
 660  
 661          try:
 662              run_simple(t.cast(str, host), port, self, **options)
 663          finally:
 664              # reset the first request information if the development server
 665              # reset normally.  This makes it possible to restart the server
 666              # without reloader and that stuff from an interactive shell.
 667              self._got_first_request = False
 668  
 669      def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient:
 670          """Creates a test client for this application.  For information
 671          about unit testing head over to :doc:`/testing`.
 672  
 673          Note that if you are testing for assertions or exceptions in your
 674          application code, you must set ``app.testing = True`` in order for the
 675          exceptions to propagate to the test client.  Otherwise, the exception
 676          will be handled by the application (not visible to the test client) and
 677          the only indication of an AssertionError or other exception will be a
 678          500 status code response to the test client.  See the :attr:`testing`
 679          attribute.  For example::
 680  
 681              app.testing = True
 682              client = app.test_client()
 683  
 684          The test client can be used in a ``with`` block to defer the closing down
 685          of the context until the end of the ``with`` block.  This is useful if
 686          you want to access the context locals for testing::
 687  
 688              with app.test_client() as c:
 689                  rv = c.get('/?vodka=42')
 690                  assert request.args['vodka'] == '42'
 691  
 692          Additionally, you may pass optional keyword arguments that will then
 693          be passed to the application's :attr:`test_client_class` constructor.
 694          For example::
 695  
 696              from flask.testing import FlaskClient
 697  
 698              class CustomClient(FlaskClient):
 699                  def __init__(self, *args, **kwargs):
 700                      self._authentication = kwargs.pop("authentication")
 701                      super(CustomClient,self).__init__( *args, **kwargs)
 702  
 703              app.test_client_class = CustomClient
 704              client = app.test_client(authentication='Basic ....')
 705  
 706          See :class:`~flask.testing.FlaskClient` for more information.
 707  
 708          .. versionchanged:: 0.4
 709             added support for ``with`` block usage for the client.
 710  
 711          .. versionadded:: 0.7
 712             The `use_cookies` parameter was added as well as the ability
 713             to override the client to be used by setting the
 714             :attr:`test_client_class` attribute.
 715  
 716          .. versionchanged:: 0.11
 717             Added `**kwargs` to support passing additional keyword arguments to
 718             the constructor of :attr:`test_client_class`.
 719          """
 720          cls = self.test_client_class
 721          if cls is None:
 722              from .testing import FlaskClient as cls
 723          return cls(  # type: ignore
 724              self, self.response_class, use_cookies=use_cookies, **kwargs
 725          )
 726  
 727      def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner:
 728          """Create a CLI runner for testing CLI commands.
 729          See :ref:`testing-cli`.
 730  
 731          Returns an instance of :attr:`test_cli_runner_class`, by default
 732          :class:`~flask.testing.FlaskCliRunner`. The Flask app object is
 733          passed as the first argument.
 734  
 735          .. versionadded:: 1.0
 736          """
 737          cls = self.test_cli_runner_class
 738  
 739          if cls is None:
 740              from .testing import FlaskCliRunner as cls
 741  
 742          return cls(self, **kwargs)  # type: ignore
 743  
 744      def handle_http_exception(
 745          self, e: HTTPException
 746      ) -> HTTPException | ft.ResponseReturnValue:
 747          """Handles an HTTP exception.  By default this will invoke the
 748          registered error handlers and fall back to returning the
 749          exception as response.
 750  
 751          .. versionchanged:: 1.0.3
 752              ``RoutingException``, used internally for actions such as
 753               slash redirects during routing, is not passed to error
 754               handlers.
 755  
 756          .. versionchanged:: 1.0
 757              Exceptions are looked up by code *and* by MRO, so
 758              ``HTTPException`` subclasses can be handled with a catch-all
 759              handler for the base ``HTTPException``.
 760  
 761          .. versionadded:: 0.3
 762          """
 763          # Proxy exceptions don't have error codes.  We want to always return
 764          # those unchanged as errors
 765          if e.code is None:
 766              return e
 767  
 768          # RoutingExceptions are used internally to trigger routing
 769          # actions, such as slash redirects raising RequestRedirect. They
 770          # are not raised or handled in user code.
 771          if isinstance(e, RoutingException):
 772              return e
 773  
 774          handler = self._find_error_handler(e, request.blueprints)
 775          if handler is None:
 776              return e
 777          return self.ensure_sync(handler)(e)  # type: ignore[no-any-return]
 778  
 779      def handle_user_exception(
 780          self, e: Exception
 781      ) -> HTTPException | ft.ResponseReturnValue:
 782          """This method is called whenever an exception occurs that
 783          should be handled. A special case is :class:`~werkzeug
 784          .exceptions.HTTPException` which is forwarded to the
 785          :meth:`handle_http_exception` method. This function will either
 786          return a response value or reraise the exception with the same
 787          traceback.
 788  
 789          .. versionchanged:: 1.0
 790              Key errors raised from request data like ``form`` show the
 791              bad key in debug mode rather than a generic bad request
 792              message.
 793  
 794          .. versionadded:: 0.7
 795          """
 796          if isinstance(e, BadRequestKeyError) and (
 797              self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
 798          ):
 799              e.show_exception = True
 800  
 801          if isinstance(e, HTTPException) and not self.trap_http_exception(e):
 802              return self.handle_http_exception(e)
 803  
 804          handler = self._find_error_handler(e, request.blueprints)
 805  
 806          if handler is None:
 807              raise
 808  
 809          return self.ensure_sync(handler)(e)  # type: ignore[no-any-return]
 810  
 811      def handle_exception(self, e: Exception) -> Response:
 812          """Handle an exception that did not have an error handler
 813          associated with it, or that was raised from an error handler.
 814          This always causes a 500 ``InternalServerError``.
 815  
 816          Always sends the :data:`got_request_exception` signal.
 817  
 818          If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug
 819          mode, the error will be re-raised so that the debugger can
 820          display it. Otherwise, the original exception is logged, and
 821          an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
 822  
 823          If an error handler is registered for ``InternalServerError`` or
 824          ``500``, it will be used. For consistency, the handler will
 825          always receive the ``InternalServerError``. The original
 826          unhandled exception is available as ``e.original_exception``.
 827  
 828          .. versionchanged:: 1.1.0
 829              Always passes the ``InternalServerError`` instance to the
 830              handler, setting ``original_exception`` to the unhandled
 831              error.
 832  
 833          .. versionchanged:: 1.1.0
 834              ``after_request`` functions and other finalization is done
 835              even for the default 500 response when there is no handler.
 836  
 837          .. versionadded:: 0.3
 838          """
 839          exc_info = sys.exc_info()
 840          got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e)
 841          propagate = self.config["PROPAGATE_EXCEPTIONS"]
 842  
 843          if propagate is None:
 844              propagate = self.testing or self.debug
 845  
 846          if propagate:
 847              # Re-raise if called with an active exception, otherwise
 848              # raise the passed in exception.
 849              if exc_info[1] is e:
 850                  raise
 851  
 852              raise e
 853  
 854          self.log_exception(exc_info)
 855          server_error: InternalServerError | ft.ResponseReturnValue
 856          server_error = InternalServerError(original_exception=e)
 857          handler = self._find_error_handler(server_error, request.blueprints)
 858  
 859          if handler is not None:
 860              server_error = self.ensure_sync(handler)(server_error)
 861  
 862          return self.finalize_request(server_error, from_error_handler=True)
 863  
 864      def log_exception(
 865          self,
 866          exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]),
 867      ) -> None:
 868          """Logs an exception.  This is called by :meth:`handle_exception`
 869          if debugging is disabled and right before the handler is called.
 870          The default implementation logs the exception as error on the
 871          :attr:`logger`.
 872  
 873          .. versionadded:: 0.8
 874          """
 875          self.logger.error(
 876              f"Exception on {request.path} [{request.method}]", exc_info=exc_info
 877          )
 878  
 879      def dispatch_request(self) -> ft.ResponseReturnValue:
 880          """Does the request dispatching.  Matches the URL and returns the
 881          return value of the view or error handler.  This does not have to
 882          be a response object.  In order to convert the return value to a
 883          proper response object, call :func:`make_response`.
 884  
 885          .. versionchanged:: 0.7
 886             This no longer does the exception handling, this code was
 887             moved to the new :meth:`full_dispatch_request`.
 888          """
 889          req = request_ctx.request
 890          if req.routing_exception is not None:
 891              self.raise_routing_exception(req)
 892          rule: Rule = req.url_rule  # type: ignore[assignment]
 893          # if we provide automatic options for this URL and the
 894          # request came with the OPTIONS method, reply automatically
 895          if (
 896              getattr(rule, "provide_automatic_options", False)
 897              and req.method == "OPTIONS"
 898          ):
 899              return self.make_default_options_response()
 900          # otherwise dispatch to the handler for that endpoint
 901          view_args: dict[str, t.Any] = req.view_args  # type: ignore[assignment]
 902          return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
 903  
 904      def full_dispatch_request(self) -> Response:
 905          """Dispatches the request and on top of that performs request
 906          pre and postprocessing as well as HTTP exception catching and
 907          error handling.
 908  
 909          .. versionadded:: 0.7
 910          """
 911          self._got_first_request = True
 912  
 913          try:
 914              request_started.send(self, _async_wrapper=self.ensure_sync)
 915              rv = self.preprocess_request()
 916              if rv is None:
 917                  rv = self.dispatch_request()
 918          except Exception as e:
 919              rv = self.handle_user_exception(e)
 920          return self.finalize_request(rv)
 921  
 922      def finalize_request(
 923          self,
 924          rv: ft.ResponseReturnValue | HTTPException,
 925          from_error_handler: bool = False,
 926      ) -> Response:
 927          """Given the return value from a view function this finalizes
 928          the request by converting it into a response and invoking the
 929          postprocessing functions.  This is invoked for both normal
 930          request dispatching as well as error handlers.
 931  
 932          Because this means that it might be called as a result of a
 933          failure a special safe mode is available which can be enabled
 934          with the `from_error_handler` flag.  If enabled, failures in
 935          response processing will be logged and otherwise ignored.
 936  
 937          :internal:
 938          """
 939          response = self.make_response(rv)
 940          try:
 941              response = self.process_response(response)
 942              request_finished.send(
 943                  self, _async_wrapper=self.ensure_sync, response=response
 944              )
 945          except Exception:
 946              if not from_error_handler:
 947                  raise
 948              self.logger.exception(
 949                  "Request finalizing failed with an error while handling an error"
 950              )
 951          return response
 952  
 953      def make_default_options_response(self) -> Response:
 954          """This method is called to create the default ``OPTIONS`` response.
 955          This can be changed through subclassing to change the default
 956          behavior of ``OPTIONS`` responses.
 957  
 958          .. versionadded:: 0.7
 959          """
 960          adapter = request_ctx.url_adapter
 961          methods = adapter.allowed_methods()  # type: ignore[union-attr]
 962          rv = self.response_class()
 963          rv.allow.update(methods)
 964          return rv
 965  
 966      def ensure_sync(self, func: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]:
 967          """Ensure that the function is synchronous for WSGI workers.
 968          Plain ``def`` functions are returned as-is. ``async def``
 969          functions are wrapped to run and wait for the response.
 970  
 971          Override this method to change how the app runs async views.
 972  
 973          .. versionadded:: 2.0
 974          """
 975          if iscoroutinefunction(func):
 976              return self.async_to_sync(func)
 977  
 978          return func
 979  
 980      def async_to_sync(
 981          self, func: t.Callable[..., t.Coroutine[t.Any, t.Any, t.Any]]
 982      ) -> t.Callable[..., t.Any]:
 983          """Return a sync function that will run the coroutine function.
 984  
 985          .. code-block:: python
 986  
 987              result = app.async_to_sync(func)(*args, **kwargs)
 988  
 989          Override this method to change how the app converts async code
 990          to be synchronously callable.
 991  
 992          .. versionadded:: 2.0
 993          """
 994          try:
 995              from asgiref.sync import async_to_sync as asgiref_async_to_sync
 996          except ImportError:
 997              raise RuntimeError(
 998                  "Install Flask with the 'async' extra in order to use async views."
 999              ) from None
1000  
1001          return asgiref_async_to_sync(func)
1002  
1003      def url_for(
1004          self,
1005          /,
1006          endpoint: str,
1007          *,
1008          _anchor: str | None = None,
1009          _method: str | None = None,
1010          _scheme: str | None = None,
1011          _external: bool | None = None,
1012          **values: t.Any,
1013      ) -> str:
1014          """Generate a URL to the given endpoint with the given values.
1015  
1016          This is called by :func:`flask.url_for`, and can be called
1017          directly as well.
1018  
1019          An *endpoint* is the name of a URL rule, usually added with
1020          :meth:`@app.route() <route>`, and usually the same name as the
1021          view function. A route defined in a :class:`~flask.Blueprint`
1022          will prepend the blueprint's name separated by a ``.`` to the
1023          endpoint.
1024  
1025          In some cases, such as email messages, you want URLs to include
1026          the scheme and domain, like ``https://example.com/hello``. When
1027          not in an active request, URLs will be external by default, but
1028          this requires setting :data:`SERVER_NAME` so Flask knows what
1029          domain to use. :data:`APPLICATION_ROOT` and
1030          :data:`PREFERRED_URL_SCHEME` should also be configured as
1031          needed. This config is only used when not in an active request.
1032  
1033          Functions can be decorated with :meth:`url_defaults` to modify
1034          keyword arguments before the URL is built.
1035  
1036          If building fails for some reason, such as an unknown endpoint
1037          or incorrect values, the app's :meth:`handle_url_build_error`
1038          method is called. If that returns a string, that is returned,
1039          otherwise a :exc:`~werkzeug.routing.BuildError` is raised.
1040  
1041          :param endpoint: The endpoint name associated with the URL to
1042              generate. If this starts with a ``.``, the current blueprint
1043              name (if any) will be used.
1044          :param _anchor: If given, append this as ``#anchor`` to the URL.
1045          :param _method: If given, generate the URL associated with this
1046              method for the endpoint.
1047          :param _scheme: If given, the URL will have this scheme if it
1048              is external.
1049          :param _external: If given, prefer the URL to be internal
1050              (False) or require it to be external (True). External URLs
1051              include the scheme and domain. When not in an active
1052              request, URLs are external by default.
1053          :param values: Values to use for the variable parts of the URL
1054              rule. Unknown keys are appended as query string arguments,
1055              like ``?a=b&c=d``.
1056  
1057          .. versionadded:: 2.2
1058              Moved from ``flask.url_for``, which calls this method.
1059          """
1060          req_ctx = _cv_request.get(None)
1061  
1062          if req_ctx is not None:
1063              url_adapter = req_ctx.url_adapter
1064              blueprint_name = req_ctx.request.blueprint
1065  
1066              # If the endpoint starts with "." and the request matches a
1067              # blueprint, the endpoint is relative to the blueprint.
1068              if endpoint[:1] == ".":
1069                  if blueprint_name is not None:
1070                      endpoint = f"{blueprint_name}{endpoint}"
1071                  else:
1072                      endpoint = endpoint[1:]
1073  
1074              # When in a request, generate a URL without scheme and
1075              # domain by default, unless a scheme is given.
1076              if _external is None:
1077                  _external = _scheme is not None
1078          else:
1079              app_ctx = _cv_app.get(None)
1080  
1081              # If called by helpers.url_for, an app context is active,
1082              # use its url_adapter. Otherwise, app.url_for was called
1083              # directly, build an adapter.
1084              if app_ctx is not None:
1085                  url_adapter = app_ctx.url_adapter
1086              else:
1087                  url_adapter = self.create_url_adapter(None)
1088  
1089              if url_adapter is None:
1090                  raise RuntimeError(
1091                      "Unable to build URLs outside an active request"
1092                      " without 'SERVER_NAME' configured. Also configure"
1093                      " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
1094                      " needed."
1095                  )
1096  
1097              # When outside a request, generate a URL with scheme and
1098              # domain by default.
1099              if _external is None:
1100                  _external = True
1101  
1102          # It is an error to set _scheme when _external=False, in order
1103          # to avoid accidental insecure URLs.
1104          if _scheme is not None and not _external:
1105              raise ValueError("When specifying '_scheme', '_external' must be True.")
1106  
1107          self.inject_url_defaults(endpoint, values)
1108  
1109          try:
1110              rv = url_adapter.build(  # type: ignore[union-attr]
1111                  endpoint,
1112                  values,
1113                  method=_method,
1114                  url_scheme=_scheme,
1115                  force_external=_external,
1116              )
1117          except BuildError as error:
1118              values.update(
1119                  _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
1120              )
1121              return self.handle_url_build_error(error, endpoint, values)
1122  
1123          if _anchor is not None:
1124              _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@")
1125              rv = f"{rv}#{_anchor}"
1126  
1127          return rv
1128  
1129      def make_response(self, rv: ft.ResponseReturnValue) -> Response:
1130          """Convert the return value from a view function to an instance of
1131          :attr:`response_class`.
1132  
1133          :param rv: the return value from the view function. The view function
1134              must return a response. Returning ``None``, or the view ending
1135              without returning, is not allowed. The following types are allowed
1136              for ``view_rv``:
1137  
1138              ``str``
1139                  A response object is created with the string encoded to UTF-8
1140                  as the body.
1141  
1142              ``bytes``
1143                  A response object is created with the bytes as the body.
1144  
1145              ``dict``
1146                  A dictionary that will be jsonify'd before being returned.
1147  
1148              ``list``
1149                  A list that will be jsonify'd before being returned.
1150  
1151              ``generator`` or ``iterator``
1152                  A generator that returns ``str`` or ``bytes`` to be
1153                  streamed as the response.
1154  
1155              ``tuple``
1156                  Either ``(body, status, headers)``, ``(body, status)``, or
1157                  ``(body, headers)``, where ``body`` is any of the other types
1158                  allowed here, ``status`` is a string or an integer, and
1159                  ``headers`` is a dictionary or a list of ``(key, value)``
1160                  tuples. If ``body`` is a :attr:`response_class` instance,
1161                  ``status`` overwrites the exiting value and ``headers`` are
1162                  extended.
1163  
1164              :attr:`response_class`
1165                  The object is returned unchanged.
1166  
1167              other :class:`~werkzeug.wrappers.Response` class
1168                  The object is coerced to :attr:`response_class`.
1169  
1170              :func:`callable`
1171                  The function is called as a WSGI application. The result is
1172                  used to create a response object.
1173  
1174          .. versionchanged:: 2.2
1175              A generator will be converted to a streaming response.
1176              A list will be converted to a JSON response.
1177  
1178          .. versionchanged:: 1.1
1179              A dict will be converted to a JSON response.
1180  
1181          .. versionchanged:: 0.9
1182             Previously a tuple was interpreted as the arguments for the
1183             response object.
1184          """
1185  
1186          status: int | None = None
1187          headers: HeadersValue | None = None
1188  
1189          # unpack tuple returns
1190          if isinstance(rv, tuple):
1191              len_rv = len(rv)
1192  
1193              # a 3-tuple is unpacked directly
1194              if len_rv == 3:
1195                  rv, status, headers = rv  # type: ignore[misc]
1196              # decide if a 2-tuple has status or headers
1197              elif len_rv == 2:
1198                  if isinstance(rv[1], (Headers, dict, tuple, list)):
1199                      rv, headers = rv  # pyright: ignore
1200                  else:
1201                      rv, status = rv  # type: ignore[assignment,misc]
1202              # other sized tuples are not allowed
1203              else:
1204                  raise TypeError(
1205                      "The view function did not return a valid response tuple."
1206                      " The tuple must have the form (body, status, headers),"
1207                      " (body, status), or (body, headers)."
1208                  )
1209  
1210          # the body must not be None
1211          if rv is None:
1212              raise TypeError(
1213                  f"The view function for {request.endpoint!r} did not"
1214                  " return a valid response. The function either returned"
1215                  " None or ended without a return statement."
1216              )
1217  
1218          # make sure the body is an instance of the response class
1219          if not isinstance(rv, self.response_class):
1220              if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, cabc.Iterator):
1221                  # let the response class set the status and headers instead of
1222                  # waiting to do it manually, so that the class can handle any
1223                  # special logic
1224                  rv = self.response_class(
1225                      rv,
1226                      status=status,
1227                      headers=headers,  # type: ignore[arg-type]
1228                  )
1229                  status = headers = None
1230              elif isinstance(rv, (dict, list)):
1231                  rv = self.json.response(rv)
1232              elif isinstance(rv, BaseResponse) or callable(rv):
1233                  # evaluate a WSGI callable, or coerce a different response
1234                  # class to the correct type
1235                  try:
1236                      rv = self.response_class.force_type(
1237                          rv,  # type: ignore[arg-type]
1238                          request.environ,
1239                      )
1240                  except TypeError as e:
1241                      raise TypeError(
1242                          f"{e}\nThe view function did not return a valid"
1243                          " response. The return type must be a string,"
1244                          " dict, list, tuple with headers or status,"
1245                          " Response instance, or WSGI callable, but it"
1246                          f" was a {type(rv).__name__}."
1247                      ).with_traceback(sys.exc_info()[2]) from None
1248              else:
1249                  raise TypeError(
1250                      "The view function did not return a valid"
1251                      " response. The return type must be a string,"
1252                      " dict, list, tuple with headers or status,"
1253                      " Response instance, or WSGI callable, but it was a"
1254                      f" {type(rv).__name__}."
1255                  )
1256  
1257          rv = t.cast(Response, rv)
1258          # prefer the status if it was provided
1259          if status is not None:
1260              if isinstance(status, (str, bytes, bytearray)):
1261                  rv.status = status
1262              else:
1263                  rv.status_code = status
1264  
1265          # extend existing headers with provided headers
1266          if headers:
1267              rv.headers.update(headers)
1268  
1269          return rv
1270  
1271      def preprocess_request(self) -> ft.ResponseReturnValue | None:
1272          """Called before the request is dispatched. Calls
1273          :attr:`url_value_preprocessors` registered with the app and the
1274          current blueprint (if any). Then calls :attr:`before_request_funcs`
1275          registered with the app and the blueprint.
1276  
1277          If any :meth:`before_request` handler returns a non-None value, the
1278          value is handled as if it was the return value from the view, and
1279          further request handling is stopped.
1280          """
1281          names = (None, *reversed(request.blueprints))
1282  
1283          for name in names:
1284              if name in self.url_value_preprocessors:
1285                  for url_func in self.url_value_preprocessors[name]:
1286                      url_func(request.endpoint, request.view_args)
1287  
1288          for name in names:
1289              if name in self.before_request_funcs:
1290                  for before_func in self.before_request_funcs[name]:
1291                      rv = self.ensure_sync(before_func)()
1292  
1293                      if rv is not None:
1294                          return rv  # type: ignore[no-any-return]
1295  
1296          return None
1297  
1298      def process_response(self, response: Response) -> Response:
1299          """Can be overridden in order to modify the response object
1300          before it's sent to the WSGI server.  By default this will
1301          call all the :meth:`after_request` decorated functions.
1302  
1303          .. versionchanged:: 0.5
1304             As of Flask 0.5 the functions registered for after request
1305             execution are called in reverse order of registration.
1306  
1307          :param response: a :attr:`response_class` object.
1308          :return: a new response object or the same, has to be an
1309                   instance of :attr:`response_class`.
1310          """
1311          ctx = request_ctx._get_current_object()  # type: ignore[attr-defined]
1312  
1313          for func in ctx._after_request_functions:
1314              response = self.ensure_sync(func)(response)
1315  
1316          for name in chain(request.blueprints, (None,)):
1317              if name in self.after_request_funcs:
1318                  for func in reversed(self.after_request_funcs[name]):
1319                      response = self.ensure_sync(func)(response)
1320  
1321          if not self.session_interface.is_null_session(ctx.session):
1322              self.session_interface.save_session(self, ctx.session, response)
1323  
1324          return response
1325  
1326      def do_teardown_request(
1327          self,
1328          exc: BaseException | None = _sentinel,  # type: ignore[assignment]
1329      ) -> None:
1330          """Called after the request is dispatched and the response is
1331          returned, right before the request context is popped.
1332  
1333          This calls all functions decorated with
1334          :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`
1335          if a blueprint handled the request. Finally, the
1336          :data:`request_tearing_down` signal is sent.
1337  
1338          This is called by
1339          :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,
1340          which may be delayed during testing to maintain access to
1341          resources.
1342  
1343          :param exc: An unhandled exception raised while dispatching the
1344              request. Detected from the current exception information if
1345              not passed. Passed to each teardown function.
1346  
1347          .. versionchanged:: 0.9
1348              Added the ``exc`` argument.
1349          """
1350          if exc is _sentinel:
1351              exc = sys.exc_info()[1]
1352  
1353          for name in chain(request.blueprints, (None,)):
1354              if name in self.teardown_request_funcs:
1355                  for func in reversed(self.teardown_request_funcs[name]):
1356                      self.ensure_sync(func)(exc)
1357  
1358          request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
1359  
1360      def do_teardown_appcontext(
1361          self,
1362          exc: BaseException | None = _sentinel,  # type: ignore[assignment]
1363      ) -> None:
1364          """Called right before the application context is popped.
1365  
1366          When handling a request, the application context is popped
1367          after the request context. See :meth:`do_teardown_request`.
1368  
1369          This calls all functions decorated with
1370          :meth:`teardown_appcontext`. Then the
1371          :data:`appcontext_tearing_down` signal is sent.
1372  
1373          This is called by
1374          :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.
1375  
1376          .. versionadded:: 0.9
1377          """
1378          if exc is _sentinel:
1379              exc = sys.exc_info()[1]
1380  
1381          for func in reversed(self.teardown_appcontext_funcs):
1382              self.ensure_sync(func)(exc)
1383  
1384          appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
1385  
1386      def app_context(self) -> AppContext:
1387          """Create an :class:`~flask.ctx.AppContext`. Use as a ``with``
1388          block to push the context, which will make :data:`current_app`
1389          point at this application.
1390  
1391          An application context is automatically pushed by
1392          :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`
1393          when handling a request, and when running a CLI command. Use
1394          this to manually create a context outside of these situations.
1395  
1396          ::
1397  
1398              with app.app_context():
1399                  init_db()
1400  
1401          See :doc:`/appcontext`.
1402  
1403          .. versionadded:: 0.9
1404          """
1405          return AppContext(self)
1406  
1407      def request_context(self, environ: WSGIEnvironment) -> RequestContext:
1408          """Create a :class:`~flask.ctx.RequestContext` representing a
1409          WSGI environment. Use a ``with`` block to push the context,
1410          which will make :data:`request` point at this request.
1411  
1412          See :doc:`/reqcontext`.
1413  
1414          Typically you should not call this from your own code. A request
1415          context is automatically pushed by the :meth:`wsgi_app` when
1416          handling a request. Use :meth:`test_request_context` to create
1417          an environment and context instead of this method.
1418  
1419          :param environ: a WSGI environment
1420          """
1421          return RequestContext(self, environ)
1422  
1423      def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext:
1424          """Create a :class:`~flask.ctx.RequestContext` for a WSGI
1425          environment created from the given values. This is mostly useful
1426          during testing, where you may want to run a function that uses
1427          request data without dispatching a full request.
1428  
1429          See :doc:`/reqcontext`.
1430  
1431          Use a ``with`` block to push the context, which will make
1432          :data:`request` point at the request for the created
1433          environment. ::
1434  
1435              with app.test_request_context(...):
1436                  generate_report()
1437  
1438          When using the shell, it may be easier to push and pop the
1439          context manually to avoid indentation. ::
1440  
1441              ctx = app.test_request_context(...)
1442              ctx.push()
1443              ...
1444              ctx.pop()
1445  
1446          Takes the same arguments as Werkzeug's
1447          :class:`~werkzeug.test.EnvironBuilder`, with some defaults from
1448          the application. See the linked Werkzeug docs for most of the
1449          available arguments. Flask-specific behavior is listed here.
1450  
1451          :param path: URL path being requested.
1452          :param base_url: Base URL where the app is being served, which
1453              ``path`` is relative to. If not given, built from
1454              :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
1455              :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
1456          :param subdomain: Subdomain name to append to
1457              :data:`SERVER_NAME`.
1458          :param url_scheme: Scheme to use instead of
1459              :data:`PREFERRED_URL_SCHEME`.
1460          :param data: The request body, either as a string or a dict of
1461              form keys and values.
1462          :param json: If given, this is serialized as JSON and passed as
1463              ``data``. Also defaults ``content_type`` to
1464              ``application/json``.
1465          :param args: other positional arguments passed to
1466              :class:`~werkzeug.test.EnvironBuilder`.
1467          :param kwargs: other keyword arguments passed to
1468              :class:`~werkzeug.test.EnvironBuilder`.
1469          """
1470          from .testing import EnvironBuilder
1471  
1472          builder = EnvironBuilder(self, *args, **kwargs)
1473  
1474          try:
1475              return self.request_context(builder.get_environ())
1476          finally:
1477              builder.close()
1478  
1479      def wsgi_app(
1480          self, environ: WSGIEnvironment, start_response: StartResponse
1481      ) -> cabc.Iterable[bytes]:
1482          """The actual WSGI application. This is not implemented in
1483          :meth:`__call__` so that middlewares can be applied without
1484          losing a reference to the app object. Instead of doing this::
1485  
1486              app = MyMiddleware(app)
1487  
1488          It's a better idea to do this instead::
1489  
1490              app.wsgi_app = MyMiddleware(app.wsgi_app)
1491  
1492          Then you still have the original application object around and
1493          can continue to call methods on it.
1494  
1495          .. versionchanged:: 0.7
1496              Teardown events for the request and app contexts are called
1497              even if an unhandled error occurs. Other events may not be
1498              called depending on when an error occurs during dispatch.
1499              See :ref:`callbacks-and-errors`.
1500  
1501          :param environ: A WSGI environment.
1502          :param start_response: A callable accepting a status code,
1503              a list of headers, and an optional exception context to
1504              start the response.
1505          """
1506          ctx = self.request_context(environ)
1507          error: BaseException | None = None
1508          try:
1509              try:
1510                  ctx.push()
1511                  response = self.full_dispatch_request()
1512              except Exception as e:
1513                  error = e
1514                  response = self.handle_exception(e)
1515              except:  # noqa: B001
1516                  error = sys.exc_info()[1]
1517                  raise
1518              return response(environ, start_response)
1519          finally:
1520              if "werkzeug.debug.preserve_context" in environ:
1521                  environ["werkzeug.debug.preserve_context"](_cv_app.get())
1522                  environ["werkzeug.debug.preserve_context"](_cv_request.get())
1523  
1524              if error is not None and self.should_ignore_error(error):
1525                  error = None
1526  
1527              ctx.pop(error)
1528  
1529      def __call__(
1530          self, environ: WSGIEnvironment, start_response: StartResponse
1531      ) -> cabc.Iterable[bytes]:
1532          """The WSGI server calls the Flask application object as the
1533          WSGI application. This calls :meth:`wsgi_app`, which can be
1534          wrapped to apply middleware.
1535          """
1536          return self.wsgi_app(environ, start_response)
1537