Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/flask/app.py: 30%
694 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
1import functools
2import inspect
3import json
4import logging
5import os
6import sys
7import typing as t
8import weakref
9from collections.abc import Iterator as _abc_Iterator
10from datetime import timedelta
11from itertools import chain
12from threading import Lock
13from types import TracebackType
15import click
16from werkzeug.datastructures import Headers
17from werkzeug.datastructures import ImmutableDict
18from werkzeug.exceptions import Aborter
19from werkzeug.exceptions import BadRequest
20from werkzeug.exceptions import BadRequestKeyError
21from werkzeug.exceptions import HTTPException
22from werkzeug.exceptions import InternalServerError
23from werkzeug.routing import BuildError
24from werkzeug.routing import Map
25from werkzeug.routing import MapAdapter
26from werkzeug.routing import RequestRedirect
27from werkzeug.routing import RoutingException
28from werkzeug.routing import Rule
29from werkzeug.serving import is_running_from_reloader
30from werkzeug.urls import url_quote
31from werkzeug.utils import redirect as _wz_redirect
32from werkzeug.wrappers import Response as BaseResponse
34from . import cli
35from . import typing as ft
36from .config import Config
37from .config import ConfigAttribute
38from .ctx import _AppCtxGlobals
39from .ctx import AppContext
40from .ctx import RequestContext
41from .globals import _cv_app
42from .globals import _cv_request
43from .globals import g
44from .globals import request
45from .globals import request_ctx
46from .globals import session
47from .helpers import _split_blueprint_path
48from .helpers import get_debug_flag
49from .helpers import get_flashed_messages
50from .helpers import get_load_dotenv
51from .helpers import locked_cached_property
52from .json.provider import DefaultJSONProvider
53from .json.provider import JSONProvider
54from .logging import create_logger
55from .scaffold import _endpoint_from_view_func
56from .scaffold import _sentinel
57from .scaffold import find_package
58from .scaffold import Scaffold
59from .scaffold import setupmethod
60from .sessions import SecureCookieSessionInterface
61from .sessions import SessionInterface
62from .signals import appcontext_tearing_down
63from .signals import got_request_exception
64from .signals import request_finished
65from .signals import request_started
66from .signals import request_tearing_down
67from .templating import DispatchingJinjaLoader
68from .templating import Environment
69from .wrappers import Request
70from .wrappers import Response
72if t.TYPE_CHECKING: # pragma: no cover
73 import typing_extensions as te
74 from .blueprints import Blueprint
75 from .testing import FlaskClient
76 from .testing import FlaskCliRunner
78T_before_first_request = t.TypeVar(
79 "T_before_first_request", bound=ft.BeforeFirstRequestCallable
80)
81T_shell_context_processor = t.TypeVar(
82 "T_shell_context_processor", bound=ft.ShellContextProcessorCallable
83)
84T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
85T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
86T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
87T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
89if sys.version_info >= (3, 8):
90 iscoroutinefunction = inspect.iscoroutinefunction
91else:
93 def iscoroutinefunction(func: t.Any) -> bool:
94 while inspect.ismethod(func):
95 func = func.__func__
97 while isinstance(func, functools.partial):
98 func = func.func
100 return inspect.iscoroutinefunction(func)
103def _make_timedelta(value: t.Union[timedelta, int, None]) -> t.Optional[timedelta]:
104 if value is None or isinstance(value, timedelta):
105 return value
107 return timedelta(seconds=value)
110class Flask(Scaffold):
111 """The flask object implements a WSGI application and acts as the central
112 object. It is passed the name of the module or package of the
113 application. Once it is created it will act as a central registry for
114 the view functions, the URL rules, template configuration and much more.
116 The name of the package is used to resolve resources from inside the
117 package or the folder the module is contained in depending on if the
118 package parameter resolves to an actual python package (a folder with
119 an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).
121 For more information about resource loading, see :func:`open_resource`.
123 Usually you create a :class:`Flask` instance in your main module or
124 in the :file:`__init__.py` file of your package like this::
126 from flask import Flask
127 app = Flask(__name__)
129 .. admonition:: About the First Parameter
131 The idea of the first parameter is to give Flask an idea of what
132 belongs to your application. This name is used to find resources
133 on the filesystem, can be used by extensions to improve debugging
134 information and a lot more.
136 So it's important what you provide there. If you are using a single
137 module, `__name__` is always the correct value. If you however are
138 using a package, it's usually recommended to hardcode the name of
139 your package there.
141 For example if your application is defined in :file:`yourapplication/app.py`
142 you should create it with one of the two versions below::
144 app = Flask('yourapplication')
145 app = Flask(__name__.split('.')[0])
147 Why is that? The application will work even with `__name__`, thanks
148 to how resources are looked up. However it will make debugging more
149 painful. Certain extensions can make assumptions based on the
150 import name of your application. For example the Flask-SQLAlchemy
151 extension will look for the code in your application that triggered
152 an SQL query in debug mode. If the import name is not properly set
153 up, that debugging information is lost. (For example it would only
154 pick up SQL queries in `yourapplication.app` and not
155 `yourapplication.views.frontend`)
157 .. versionadded:: 0.7
158 The `static_url_path`, `static_folder`, and `template_folder`
159 parameters were added.
161 .. versionadded:: 0.8
162 The `instance_path` and `instance_relative_config` parameters were
163 added.
165 .. versionadded:: 0.11
166 The `root_path` parameter was added.
168 .. versionadded:: 1.0
169 The ``host_matching`` and ``static_host`` parameters were added.
171 .. versionadded:: 1.0
172 The ``subdomain_matching`` parameter was added. Subdomain
173 matching needs to be enabled manually now. Setting
174 :data:`SERVER_NAME` does not implicitly enable it.
176 :param import_name: the name of the application package
177 :param static_url_path: can be used to specify a different path for the
178 static files on the web. Defaults to the name
179 of the `static_folder` folder.
180 :param static_folder: The folder with static files that is served at
181 ``static_url_path``. Relative to the application ``root_path``
182 or an absolute path. Defaults to ``'static'``.
183 :param static_host: the host to use when adding the static route.
184 Defaults to None. Required when using ``host_matching=True``
185 with a ``static_folder`` configured.
186 :param host_matching: set ``url_map.host_matching`` attribute.
187 Defaults to False.
188 :param subdomain_matching: consider the subdomain relative to
189 :data:`SERVER_NAME` when matching routes. Defaults to False.
190 :param template_folder: the folder that contains the templates that should
191 be used by the application. Defaults to
192 ``'templates'`` folder in the root path of the
193 application.
194 :param instance_path: An alternative instance path for the application.
195 By default the folder ``'instance'`` next to the
196 package or module is assumed to be the instance
197 path.
198 :param instance_relative_config: if set to ``True`` relative filenames
199 for loading the config are assumed to
200 be relative to the instance path instead
201 of the application root.
202 :param root_path: The path to the root of the application files.
203 This should only be set manually when it can't be detected
204 automatically, such as for namespace packages.
205 """
207 #: The class that is used for request objects. See :class:`~flask.Request`
208 #: for more information.
209 request_class = Request
211 #: The class that is used for response objects. See
212 #: :class:`~flask.Response` for more information.
213 response_class = Response
215 #: The class of the object assigned to :attr:`aborter`, created by
216 #: :meth:`create_aborter`. That object is called by
217 #: :func:`flask.abort` to raise HTTP errors, and can be
218 #: called directly as well.
219 #:
220 #: Defaults to :class:`werkzeug.exceptions.Aborter`.
221 #:
222 #: .. versionadded:: 2.2
223 aborter_class = Aborter
225 #: The class that is used for the Jinja environment.
226 #:
227 #: .. versionadded:: 0.11
228 jinja_environment = Environment
230 #: The class that is used for the :data:`~flask.g` instance.
231 #:
232 #: Example use cases for a custom class:
233 #:
234 #: 1. Store arbitrary attributes on flask.g.
235 #: 2. Add a property for lazy per-request database connectors.
236 #: 3. Return None instead of AttributeError on unexpected attributes.
237 #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g.
238 #:
239 #: In Flask 0.9 this property was called `request_globals_class` but it
240 #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the
241 #: flask.g object is now application context scoped.
242 #:
243 #: .. versionadded:: 0.10
244 app_ctx_globals_class = _AppCtxGlobals
246 #: The class that is used for the ``config`` attribute of this app.
247 #: Defaults to :class:`~flask.Config`.
248 #:
249 #: Example use cases for a custom class:
250 #:
251 #: 1. Default values for certain config options.
252 #: 2. Access to config values through attributes in addition to keys.
253 #:
254 #: .. versionadded:: 0.11
255 config_class = Config
257 #: The testing flag. Set this to ``True`` to enable the test mode of
258 #: Flask extensions (and in the future probably also Flask itself).
259 #: For example this might activate test helpers that have an
260 #: additional runtime cost which should not be enabled by default.
261 #:
262 #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the
263 #: default it's implicitly enabled.
264 #:
265 #: This attribute can also be configured from the config with the
266 #: ``TESTING`` configuration key. Defaults to ``False``.
267 testing = ConfigAttribute("TESTING")
269 #: If a secret key is set, cryptographic components can use this to
270 #: sign cookies and other things. Set this to a complex random value
271 #: when you want to use the secure cookie for instance.
272 #:
273 #: This attribute can also be configured from the config with the
274 #: :data:`SECRET_KEY` configuration key. Defaults to ``None``.
275 secret_key = ConfigAttribute("SECRET_KEY")
277 @property
278 def session_cookie_name(self) -> str:
279 """The name of the cookie set by the session interface.
281 .. deprecated:: 2.2
282 Will be removed in Flask 2.3. Use ``app.config["SESSION_COOKIE_NAME"]``
283 instead.
284 """
285 import warnings
287 warnings.warn(
288 "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
289 " 'SESSION_COOKIE_NAME' in 'app.config' instead.",
290 DeprecationWarning,
291 stacklevel=2,
292 )
293 return self.config["SESSION_COOKIE_NAME"]
295 @session_cookie_name.setter
296 def session_cookie_name(self, value: str) -> None:
297 import warnings
299 warnings.warn(
300 "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
301 " 'SESSION_COOKIE_NAME' in 'app.config' instead.",
302 DeprecationWarning,
303 stacklevel=2,
304 )
305 self.config["SESSION_COOKIE_NAME"] = value
307 #: A :class:`~datetime.timedelta` which is used to set the expiration
308 #: date of a permanent session. The default is 31 days which makes a
309 #: permanent session survive for roughly one month.
310 #:
311 #: This attribute can also be configured from the config with the
312 #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to
313 #: ``timedelta(days=31)``
314 permanent_session_lifetime = ConfigAttribute(
315 "PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
316 )
318 @property
319 def send_file_max_age_default(self) -> t.Optional[timedelta]:
320 """The default value for ``max_age`` for :func:`~flask.send_file`. The default
321 is ``None``, which tells the browser to use conditional requests instead of a
322 timed cache.
324 .. deprecated:: 2.2
325 Will be removed in Flask 2.3. Use
326 ``app.config["SEND_FILE_MAX_AGE_DEFAULT"]`` instead.
328 .. versionchanged:: 2.0
329 Defaults to ``None`` instead of 12 hours.
330 """
331 import warnings
333 warnings.warn(
334 "'send_file_max_age_default' is deprecated and will be removed in Flask"
335 " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
336 DeprecationWarning,
337 stacklevel=2,
338 )
339 return _make_timedelta(self.config["SEND_FILE_MAX_AGE_DEFAULT"])
341 @send_file_max_age_default.setter
342 def send_file_max_age_default(self, value: t.Union[int, timedelta, None]) -> None:
343 import warnings
345 warnings.warn(
346 "'send_file_max_age_default' is deprecated and will be removed in Flask"
347 " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
348 DeprecationWarning,
349 stacklevel=2,
350 )
351 self.config["SEND_FILE_MAX_AGE_DEFAULT"] = _make_timedelta(value)
353 @property
354 def use_x_sendfile(self) -> bool:
355 """Enable this to use the ``X-Sendfile`` feature, assuming the server supports
356 it, from :func:`~flask.send_file`.
358 .. deprecated:: 2.2
359 Will be removed in Flask 2.3. Use ``app.config["USE_X_SENDFILE"]`` instead.
360 """
361 import warnings
363 warnings.warn(
364 "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
365 " 'USE_X_SENDFILE' in 'app.config' instead.",
366 DeprecationWarning,
367 stacklevel=2,
368 )
369 return self.config["USE_X_SENDFILE"]
371 @use_x_sendfile.setter
372 def use_x_sendfile(self, value: bool) -> None:
373 import warnings
375 warnings.warn(
376 "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
377 " 'USE_X_SENDFILE' in 'app.config' instead.",
378 DeprecationWarning,
379 stacklevel=2,
380 )
381 self.config["USE_X_SENDFILE"] = value
383 _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
384 _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
386 @property # type: ignore[override]
387 def json_encoder(self) -> t.Type[json.JSONEncoder]: # type: ignore[override]
388 """The JSON encoder class to use. Defaults to
389 :class:`~flask.json.JSONEncoder`.
391 .. deprecated:: 2.2
392 Will be removed in Flask 2.3. Customize
393 :attr:`json_provider_class` instead.
395 .. versionadded:: 0.10
396 """
397 import warnings
399 warnings.warn(
400 "'app.json_encoder' is deprecated and will be removed in Flask 2.3."
401 " Customize 'app.json_provider_class' or 'app.json' instead.",
402 DeprecationWarning,
403 stacklevel=2,
404 )
406 if self._json_encoder is None:
407 from . import json
409 return json.JSONEncoder
411 return self._json_encoder
413 @json_encoder.setter
414 def json_encoder(self, value: t.Type[json.JSONEncoder]) -> None:
415 import warnings
417 warnings.warn(
418 "'app.json_encoder' is deprecated and will be removed in Flask 2.3."
419 " Customize 'app.json_provider_class' or 'app.json' instead.",
420 DeprecationWarning,
421 stacklevel=2,
422 )
423 self._json_encoder = value
425 @property # type: ignore[override]
426 def json_decoder(self) -> t.Type[json.JSONDecoder]: # type: ignore[override]
427 """The JSON decoder class to use. Defaults to
428 :class:`~flask.json.JSONDecoder`.
430 .. deprecated:: 2.2
431 Will be removed in Flask 2.3. Customize
432 :attr:`json_provider_class` instead.
434 .. versionadded:: 0.10
435 """
436 import warnings
438 warnings.warn(
439 "'app.json_decoder' is deprecated and will be removed in Flask 2.3."
440 " Customize 'app.json_provider_class' or 'app.json' instead.",
441 DeprecationWarning,
442 stacklevel=2,
443 )
445 if self._json_decoder is None:
446 from . import json
448 return json.JSONDecoder
450 return self._json_decoder
452 @json_decoder.setter
453 def json_decoder(self, value: t.Type[json.JSONDecoder]) -> None:
454 import warnings
456 warnings.warn(
457 "'app.json_decoder' is deprecated and will be removed in Flask 2.3."
458 " Customize 'app.json_provider_class' or 'app.json' instead.",
459 DeprecationWarning,
460 stacklevel=2,
461 )
462 self._json_decoder = value
464 json_provider_class: t.Type[JSONProvider] = DefaultJSONProvider
465 """A subclass of :class:`~flask.json.provider.JSONProvider`. An
466 instance is created and assigned to :attr:`app.json` when creating
467 the app.
469 The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses
470 Python's built-in :mod:`json` library. A different provider can use
471 a different JSON library.
473 .. versionadded:: 2.2
474 """
476 #: Options that are passed to the Jinja environment in
477 #: :meth:`create_jinja_environment`. Changing these options after
478 #: the environment is created (accessing :attr:`jinja_env`) will
479 #: have no effect.
480 #:
481 #: .. versionchanged:: 1.1.0
482 #: This is a ``dict`` instead of an ``ImmutableDict`` to allow
483 #: easier configuration.
484 #:
485 jinja_options: dict = {}
487 #: Default configuration parameters.
488 default_config = ImmutableDict(
489 {
490 "ENV": None,
491 "DEBUG": None,
492 "TESTING": False,
493 "PROPAGATE_EXCEPTIONS": None,
494 "SECRET_KEY": None,
495 "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
496 "USE_X_SENDFILE": False,
497 "SERVER_NAME": None,
498 "APPLICATION_ROOT": "/",
499 "SESSION_COOKIE_NAME": "session",
500 "SESSION_COOKIE_DOMAIN": None,
501 "SESSION_COOKIE_PATH": None,
502 "SESSION_COOKIE_HTTPONLY": True,
503 "SESSION_COOKIE_SECURE": False,
504 "SESSION_COOKIE_SAMESITE": None,
505 "SESSION_REFRESH_EACH_REQUEST": True,
506 "MAX_CONTENT_LENGTH": None,
507 "SEND_FILE_MAX_AGE_DEFAULT": None,
508 "TRAP_BAD_REQUEST_ERRORS": None,
509 "TRAP_HTTP_EXCEPTIONS": False,
510 "EXPLAIN_TEMPLATE_LOADING": False,
511 "PREFERRED_URL_SCHEME": "http",
512 "JSON_AS_ASCII": None,
513 "JSON_SORT_KEYS": None,
514 "JSONIFY_PRETTYPRINT_REGULAR": None,
515 "JSONIFY_MIMETYPE": None,
516 "TEMPLATES_AUTO_RELOAD": None,
517 "MAX_COOKIE_SIZE": 4093,
518 }
519 )
521 #: The rule object to use for URL rules created. This is used by
522 #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`.
523 #:
524 #: .. versionadded:: 0.7
525 url_rule_class = Rule
527 #: The map object to use for storing the URL rules and routing
528 #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`.
529 #:
530 #: .. versionadded:: 1.1.0
531 url_map_class = Map
533 #: The :meth:`test_client` method creates an instance of this test
534 #: client class. Defaults to :class:`~flask.testing.FlaskClient`.
535 #:
536 #: .. versionadded:: 0.7
537 test_client_class: t.Optional[t.Type["FlaskClient"]] = None
539 #: The :class:`~click.testing.CliRunner` subclass, by default
540 #: :class:`~flask.testing.FlaskCliRunner` that is used by
541 #: :meth:`test_cli_runner`. Its ``__init__`` method should take a
542 #: Flask app object as the first argument.
543 #:
544 #: .. versionadded:: 1.0
545 test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None
547 #: the session interface to use. By default an instance of
548 #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
549 #:
550 #: .. versionadded:: 0.8
551 session_interface: SessionInterface = SecureCookieSessionInterface()
553 def __init__(
554 self,
555 import_name: str,
556 static_url_path: t.Optional[str] = None,
557 static_folder: t.Optional[t.Union[str, os.PathLike]] = "static",
558 static_host: t.Optional[str] = None,
559 host_matching: bool = False,
560 subdomain_matching: bool = False,
561 template_folder: t.Optional[str] = "templates",
562 instance_path: t.Optional[str] = None,
563 instance_relative_config: bool = False,
564 root_path: t.Optional[str] = None,
565 ):
566 super().__init__(
567 import_name=import_name,
568 static_folder=static_folder,
569 static_url_path=static_url_path,
570 template_folder=template_folder,
571 root_path=root_path,
572 )
574 if instance_path is None:
575 instance_path = self.auto_find_instance_path()
576 elif not os.path.isabs(instance_path):
577 raise ValueError(
578 "If an instance path is provided it must be absolute."
579 " A relative path was given instead."
580 )
582 #: Holds the path to the instance folder.
583 #:
584 #: .. versionadded:: 0.8
585 self.instance_path = instance_path
587 #: The configuration dictionary as :class:`Config`. This behaves
588 #: exactly like a regular dictionary but supports additional methods
589 #: to load a config from files.
590 self.config = self.make_config(instance_relative_config)
592 #: An instance of :attr:`aborter_class` created by
593 #: :meth:`make_aborter`. This is called by :func:`flask.abort`
594 #: to raise HTTP errors, and can be called directly as well.
595 #:
596 #: .. versionadded:: 2.2
597 #: Moved from ``flask.abort``, which calls this object.
598 self.aborter = self.make_aborter()
600 self.json: JSONProvider = self.json_provider_class(self)
601 """Provides access to JSON methods. Functions in ``flask.json``
602 will call methods on this provider when the application context
603 is active. Used for handling JSON requests and responses.
605 An instance of :attr:`json_provider_class`. Can be customized by
606 changing that attribute on a subclass, or by assigning to this
607 attribute afterwards.
609 The default, :class:`~flask.json.provider.DefaultJSONProvider`,
610 uses Python's built-in :mod:`json` library. A different provider
611 can use a different JSON library.
613 .. versionadded:: 2.2
614 """
616 #: A list of functions that are called by
617 #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a
618 #: :exc:`~werkzeug.routing.BuildError`. Each function is called
619 #: with ``error``, ``endpoint`` and ``values``. If a function
620 #: returns ``None`` or raises a ``BuildError``, it is skipped.
621 #: Otherwise, its return value is returned by ``url_for``.
622 #:
623 #: .. versionadded:: 0.9
624 self.url_build_error_handlers: t.List[
625 t.Callable[[Exception, str, t.Dict[str, t.Any]], str]
626 ] = []
628 #: A list of functions that will be called at the beginning of the
629 #: first request to this instance. To register a function, use the
630 #: :meth:`before_first_request` decorator.
631 #:
632 #: .. deprecated:: 2.2
633 #: Will be removed in Flask 2.3. Run setup code when
634 #: creating the application instead.
635 #:
636 #: .. versionadded:: 0.8
637 self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = []
639 #: A list of functions that are called when the application context
640 #: is destroyed. Since the application context is also torn down
641 #: if the request ends this is the place to store code that disconnects
642 #: from databases.
643 #:
644 #: .. versionadded:: 0.9
645 self.teardown_appcontext_funcs: t.List[ft.TeardownCallable] = []
647 #: A list of shell context processor functions that should be run
648 #: when a shell context is created.
649 #:
650 #: .. versionadded:: 0.11
651 self.shell_context_processors: t.List[ft.ShellContextProcessorCallable] = []
653 #: Maps registered blueprint names to blueprint objects. The
654 #: dict retains the order the blueprints were registered in.
655 #: Blueprints can be registered multiple times, this dict does
656 #: not track how often they were attached.
657 #:
658 #: .. versionadded:: 0.7
659 self.blueprints: t.Dict[str, "Blueprint"] = {}
661 #: a place where extensions can store application specific state. For
662 #: example this is where an extension could store database engines and
663 #: similar things.
664 #:
665 #: The key must match the name of the extension module. For example in
666 #: case of a "Flask-Foo" extension in `flask_foo`, the key would be
667 #: ``'foo'``.
668 #:
669 #: .. versionadded:: 0.7
670 self.extensions: dict = {}
672 #: The :class:`~werkzeug.routing.Map` for this instance. You can use
673 #: this to change the routing converters after the class was created
674 #: but before any routes are connected. Example::
675 #:
676 #: from werkzeug.routing import BaseConverter
677 #:
678 #: class ListConverter(BaseConverter):
679 #: def to_python(self, value):
680 #: return value.split(',')
681 #: def to_url(self, values):
682 #: return ','.join(super(ListConverter, self).to_url(value)
683 #: for value in values)
684 #:
685 #: app = Flask(__name__)
686 #: app.url_map.converters['list'] = ListConverter
687 self.url_map = self.url_map_class()
689 self.url_map.host_matching = host_matching
690 self.subdomain_matching = subdomain_matching
692 # tracks internally if the application already handled at least one
693 # request.
694 self._got_first_request = False
695 self._before_request_lock = Lock()
697 # Add a static route using the provided static_url_path, static_host,
698 # and static_folder if there is a configured static_folder.
699 # Note we do this without checking if static_folder exists.
700 # For one, it might be created while the server is running (e.g. during
701 # development). Also, Google App Engine stores static files somewhere
702 if self.has_static_folder:
703 assert (
704 bool(static_host) == host_matching
705 ), "Invalid static_host/host_matching combination"
706 # Use a weakref to avoid creating a reference cycle between the app
707 # and the view function (see #3761).
708 self_ref = weakref.ref(self)
709 self.add_url_rule(
710 f"{self.static_url_path}/<path:filename>",
711 endpoint="static",
712 host=static_host,
713 view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950
714 )
716 # Set the name of the Click group in case someone wants to add
717 # the app's commands to another CLI tool.
718 self.cli.name = self.name
720 def _check_setup_finished(self, f_name: str) -> None:
721 if self._got_first_request:
722 raise AssertionError(
723 f"The setup method '{f_name}' can no longer be called"
724 " on the application. It has already handled its first"
725 " request, any changes will not be applied"
726 " consistently.\n"
727 "Make sure all imports, decorators, functions, etc."
728 " needed to set up the application are done before"
729 " running it."
730 )
732 @locked_cached_property
733 def name(self) -> str: # type: ignore
734 """The name of the application. This is usually the import name
735 with the difference that it's guessed from the run file if the
736 import name is main. This name is used as a display name when
737 Flask needs the name of the application. It can be set and overridden
738 to change the value.
740 .. versionadded:: 0.8
741 """
742 if self.import_name == "__main__":
743 fn = getattr(sys.modules["__main__"], "__file__", None)
744 if fn is None:
745 return "__main__"
746 return os.path.splitext(os.path.basename(fn))[0]
747 return self.import_name
749 @property
750 def propagate_exceptions(self) -> bool:
751 """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration
752 value in case it's set, otherwise a sensible default is returned.
754 .. deprecated:: 2.2
755 Will be removed in Flask 2.3.
757 .. versionadded:: 0.7
758 """
759 import warnings
761 warnings.warn(
762 "'propagate_exceptions' is deprecated and will be removed in Flask 2.3.",
763 DeprecationWarning,
764 stacklevel=2,
765 )
766 rv = self.config["PROPAGATE_EXCEPTIONS"]
767 if rv is not None:
768 return rv
769 return self.testing or self.debug
771 @locked_cached_property
772 def logger(self) -> logging.Logger:
773 """A standard Python :class:`~logging.Logger` for the app, with
774 the same name as :attr:`name`.
776 In debug mode, the logger's :attr:`~logging.Logger.level` will
777 be set to :data:`~logging.DEBUG`.
779 If there are no handlers configured, a default handler will be
780 added. See :doc:`/logging` for more information.
782 .. versionchanged:: 1.1.0
783 The logger takes the same name as :attr:`name` rather than
784 hard-coding ``"flask.app"``.
786 .. versionchanged:: 1.0.0
787 Behavior was simplified. The logger is always named
788 ``"flask.app"``. The level is only set during configuration,
789 it doesn't check ``app.debug`` each time. Only one format is
790 used, not different ones depending on ``app.debug``. No
791 handlers are removed, and a handler is only added if no
792 handlers are already configured.
794 .. versionadded:: 0.3
795 """
796 return create_logger(self)
798 @locked_cached_property
799 def jinja_env(self) -> Environment:
800 """The Jinja environment used to load templates.
802 The environment is created the first time this property is
803 accessed. Changing :attr:`jinja_options` after that will have no
804 effect.
805 """
806 return self.create_jinja_environment()
808 @property
809 def got_first_request(self) -> bool:
810 """This attribute is set to ``True`` if the application started
811 handling the first request.
813 .. versionadded:: 0.8
814 """
815 return self._got_first_request
817 def make_config(self, instance_relative: bool = False) -> Config:
818 """Used to create the config attribute by the Flask constructor.
819 The `instance_relative` parameter is passed in from the constructor
820 of Flask (there named `instance_relative_config`) and indicates if
821 the config should be relative to the instance path or the root path
822 of the application.
824 .. versionadded:: 0.8
825 """
826 root_path = self.root_path
827 if instance_relative:
828 root_path = self.instance_path
829 defaults = dict(self.default_config)
830 defaults["ENV"] = os.environ.get("FLASK_ENV") or "production"
831 defaults["DEBUG"] = get_debug_flag()
832 return self.config_class(root_path, defaults)
834 def make_aborter(self) -> Aborter:
835 """Create the object to assign to :attr:`aborter`. That object
836 is called by :func:`flask.abort` to raise HTTP errors, and can
837 be called directly as well.
839 By default, this creates an instance of :attr:`aborter_class`,
840 which defaults to :class:`werkzeug.exceptions.Aborter`.
842 .. versionadded:: 2.2
843 """
844 return self.aborter_class()
846 def auto_find_instance_path(self) -> str:
847 """Tries to locate the instance path if it was not provided to the
848 constructor of the application class. It will basically calculate
849 the path to a folder named ``instance`` next to your main file or
850 the package.
852 .. versionadded:: 0.8
853 """
854 prefix, package_path = find_package(self.import_name)
855 if prefix is None:
856 return os.path.join(package_path, "instance")
857 return os.path.join(prefix, "var", f"{self.name}-instance")
859 def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
860 """Opens a resource from the application's instance folder
861 (:attr:`instance_path`). Otherwise works like
862 :meth:`open_resource`. Instance resources can also be opened for
863 writing.
865 :param resource: the name of the resource. To access resources within
866 subfolders use forward slashes as separator.
867 :param mode: resource file opening mode, default is 'rb'.
868 """
869 return open(os.path.join(self.instance_path, resource), mode)
871 @property
872 def templates_auto_reload(self) -> bool:
873 """Reload templates when they are changed. Used by
874 :meth:`create_jinja_environment`. It is enabled by default in debug mode.
876 .. deprecated:: 2.2
877 Will be removed in Flask 2.3. Use ``app.config["TEMPLATES_AUTO_RELOAD"]``
878 instead.
880 .. versionadded:: 1.0
881 This property was added but the underlying config and behavior
882 already existed.
883 """
884 import warnings
886 warnings.warn(
887 "'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
888 " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
889 DeprecationWarning,
890 stacklevel=2,
891 )
892 rv = self.config["TEMPLATES_AUTO_RELOAD"]
893 return rv if rv is not None else self.debug
895 @templates_auto_reload.setter
896 def templates_auto_reload(self, value: bool) -> None:
897 import warnings
899 warnings.warn(
900 "'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
901 " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
902 DeprecationWarning,
903 stacklevel=2,
904 )
905 self.config["TEMPLATES_AUTO_RELOAD"] = value
907 def create_jinja_environment(self) -> Environment:
908 """Create the Jinja environment based on :attr:`jinja_options`
909 and the various Jinja-related methods of the app. Changing
910 :attr:`jinja_options` after this will have no effect. Also adds
911 Flask-related globals and filters to the environment.
913 .. versionchanged:: 0.11
914 ``Environment.auto_reload`` set in accordance with
915 ``TEMPLATES_AUTO_RELOAD`` configuration option.
917 .. versionadded:: 0.5
918 """
919 options = dict(self.jinja_options)
921 if "autoescape" not in options:
922 options["autoescape"] = self.select_jinja_autoescape
924 if "auto_reload" not in options:
925 auto_reload = self.config["TEMPLATES_AUTO_RELOAD"]
927 if auto_reload is None:
928 auto_reload = self.debug
930 options["auto_reload"] = auto_reload
932 rv = self.jinja_environment(self, **options)
933 rv.globals.update(
934 url_for=self.url_for,
935 get_flashed_messages=get_flashed_messages,
936 config=self.config,
937 # request, session and g are normally added with the
938 # context processor for efficiency reasons but for imported
939 # templates we also want the proxies in there.
940 request=request,
941 session=session,
942 g=g,
943 )
944 rv.policies["json.dumps_function"] = self.json.dumps
945 return rv
947 def create_global_jinja_loader(self) -> DispatchingJinjaLoader:
948 """Creates the loader for the Jinja2 environment. Can be used to
949 override just the loader and keeping the rest unchanged. It's
950 discouraged to override this function. Instead one should override
951 the :meth:`jinja_loader` function instead.
953 The global loader dispatches between the loaders of the application
954 and the individual blueprints.
956 .. versionadded:: 0.7
957 """
958 return DispatchingJinjaLoader(self)
960 def select_jinja_autoescape(self, filename: str) -> bool:
961 """Returns ``True`` if autoescaping should be active for the given
962 template name. If no template name is given, returns `True`.
964 .. versionadded:: 0.5
965 """
966 if filename is None:
967 return True
968 return filename.endswith((".html", ".htm", ".xml", ".xhtml"))
970 def update_template_context(self, context: dict) -> None:
971 """Update the template context with some commonly used variables.
972 This injects request, session, config and g into the template
973 context as well as everything template context processors want
974 to inject. Note that the as of Flask 0.6, the original values
975 in the context will not be overridden if a context processor
976 decides to return a value with the same key.
978 :param context: the context as a dictionary that is updated in place
979 to add extra variables.
980 """
981 names: t.Iterable[t.Optional[str]] = (None,)
983 # A template may be rendered outside a request context.
984 if request:
985 names = chain(names, reversed(request.blueprints))
987 # The values passed to render_template take precedence. Keep a
988 # copy to re-apply after all context functions.
989 orig_ctx = context.copy()
991 for name in names:
992 if name in self.template_context_processors:
993 for func in self.template_context_processors[name]:
994 context.update(func())
996 context.update(orig_ctx)
998 def make_shell_context(self) -> dict:
999 """Returns the shell context for an interactive shell for this
1000 application. This runs all the registered shell context
1001 processors.
1003 .. versionadded:: 0.11
1004 """
1005 rv = {"app": self, "g": g}
1006 for processor in self.shell_context_processors:
1007 rv.update(processor())
1008 return rv
1010 @property
1011 def env(self) -> str:
1012 """What environment the app is running in. This maps to the :data:`ENV` config
1013 key.
1015 **Do not enable development when deploying in production.**
1017 Default: ``'production'``
1019 .. deprecated:: 2.2
1020 Will be removed in Flask 2.3.
1021 """
1022 import warnings
1024 warnings.warn(
1025 "'app.env' is deprecated and will be removed in Flask 2.3."
1026 " Use 'app.debug' instead.",
1027 DeprecationWarning,
1028 stacklevel=2,
1029 )
1030 return self.config["ENV"]
1032 @env.setter
1033 def env(self, value: str) -> None:
1034 import warnings
1036 warnings.warn(
1037 "'app.env' is deprecated and will be removed in Flask 2.3."
1038 " Use 'app.debug' instead.",
1039 DeprecationWarning,
1040 stacklevel=2,
1041 )
1042 self.config["ENV"] = value
1044 @property
1045 def debug(self) -> bool:
1046 """Whether debug mode is enabled. When using ``flask run`` to start the
1047 development server, an interactive debugger will be shown for unhandled
1048 exceptions, and the server will be reloaded when code changes. This maps to the
1049 :data:`DEBUG` config key. It may not behave as expected if set late.
1051 **Do not enable debug mode when deploying in production.**
1053 Default: ``False``
1054 """
1055 return self.config["DEBUG"]
1057 @debug.setter
1058 def debug(self, value: bool) -> None:
1059 self.config["DEBUG"] = value
1061 if self.config["TEMPLATES_AUTO_RELOAD"] is None:
1062 self.jinja_env.auto_reload = value
1064 def run(
1065 self,
1066 host: t.Optional[str] = None,
1067 port: t.Optional[int] = None,
1068 debug: t.Optional[bool] = None,
1069 load_dotenv: bool = True,
1070 **options: t.Any,
1071 ) -> None:
1072 """Runs the application on a local development server.
1074 Do not use ``run()`` in a production setting. It is not intended to
1075 meet security and performance requirements for a production server.
1076 Instead, see :doc:`/deploying/index` for WSGI server recommendations.
1078 If the :attr:`debug` flag is set the server will automatically reload
1079 for code changes and show a debugger in case an exception happened.
1081 If you want to run the application in debug mode, but disable the
1082 code execution on the interactive debugger, you can pass
1083 ``use_evalex=False`` as parameter. This will keep the debugger's
1084 traceback screen active, but disable code execution.
1086 It is not recommended to use this function for development with
1087 automatic reloading as this is badly supported. Instead you should
1088 be using the :command:`flask` command line script's ``run`` support.
1090 .. admonition:: Keep in Mind
1092 Flask will suppress any server error with a generic error page
1093 unless it is in debug mode. As such to enable just the
1094 interactive debugger without the code reloading, you have to
1095 invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
1096 Setting ``use_debugger`` to ``True`` without being in debug mode
1097 won't catch any exceptions because there won't be any to
1098 catch.
1100 :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
1101 have the server available externally as well. Defaults to
1102 ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
1103 if present.
1104 :param port: the port of the webserver. Defaults to ``5000`` or the
1105 port defined in the ``SERVER_NAME`` config variable if present.
1106 :param debug: if given, enable or disable debug mode. See
1107 :attr:`debug`.
1108 :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
1109 files to set environment variables. Will also change the working
1110 directory to the directory containing the first file found.
1111 :param options: the options to be forwarded to the underlying Werkzeug
1112 server. See :func:`werkzeug.serving.run_simple` for more
1113 information.
1115 .. versionchanged:: 1.0
1116 If installed, python-dotenv will be used to load environment
1117 variables from :file:`.env` and :file:`.flaskenv` files.
1119 The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`.
1121 Threaded mode is enabled by default.
1123 .. versionchanged:: 0.10
1124 The default port is now picked from the ``SERVER_NAME``
1125 variable.
1126 """
1127 # Ignore this call so that it doesn't start another server if
1128 # the 'flask run' command is used.
1129 if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
1130 if not is_running_from_reloader():
1131 click.secho(
1132 " * Ignoring a call to 'app.run()' that would block"
1133 " the current 'flask' CLI command.\n"
1134 " Only call 'app.run()' in an 'if __name__ =="
1135 ' "__main__"\' guard.',
1136 fg="red",
1137 )
1139 return
1141 if get_load_dotenv(load_dotenv):
1142 cli.load_dotenv()
1144 # if set, let env vars override previous values
1145 if "FLASK_ENV" in os.environ:
1146 print(
1147 "'FLASK_ENV' is deprecated and will not be used in"
1148 " Flask 2.3. Use 'FLASK_DEBUG' instead.",
1149 file=sys.stderr,
1150 )
1151 self.config["ENV"] = os.environ.get("FLASK_ENV") or "production"
1152 self.debug = get_debug_flag()
1153 elif "FLASK_DEBUG" in os.environ:
1154 self.debug = get_debug_flag()
1156 # debug passed to method overrides all other sources
1157 if debug is not None:
1158 self.debug = bool(debug)
1160 server_name = self.config.get("SERVER_NAME")
1161 sn_host = sn_port = None
1163 if server_name:
1164 sn_host, _, sn_port = server_name.partition(":")
1166 if not host:
1167 if sn_host:
1168 host = sn_host
1169 else:
1170 host = "127.0.0.1"
1172 if port or port == 0:
1173 port = int(port)
1174 elif sn_port:
1175 port = int(sn_port)
1176 else:
1177 port = 5000
1179 options.setdefault("use_reloader", self.debug)
1180 options.setdefault("use_debugger", self.debug)
1181 options.setdefault("threaded", True)
1183 cli.show_server_banner(self.debug, self.name)
1185 from werkzeug.serving import run_simple
1187 try:
1188 run_simple(t.cast(str, host), port, self, **options)
1189 finally:
1190 # reset the first request information if the development server
1191 # reset normally. This makes it possible to restart the server
1192 # without reloader and that stuff from an interactive shell.
1193 self._got_first_request = False
1195 def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient":
1196 """Creates a test client for this application. For information
1197 about unit testing head over to :doc:`/testing`.
1199 Note that if you are testing for assertions or exceptions in your
1200 application code, you must set ``app.testing = True`` in order for the
1201 exceptions to propagate to the test client. Otherwise, the exception
1202 will be handled by the application (not visible to the test client) and
1203 the only indication of an AssertionError or other exception will be a
1204 500 status code response to the test client. See the :attr:`testing`
1205 attribute. For example::
1207 app.testing = True
1208 client = app.test_client()
1210 The test client can be used in a ``with`` block to defer the closing down
1211 of the context until the end of the ``with`` block. This is useful if
1212 you want to access the context locals for testing::
1214 with app.test_client() as c:
1215 rv = c.get('/?vodka=42')
1216 assert request.args['vodka'] == '42'
1218 Additionally, you may pass optional keyword arguments that will then
1219 be passed to the application's :attr:`test_client_class` constructor.
1220 For example::
1222 from flask.testing import FlaskClient
1224 class CustomClient(FlaskClient):
1225 def __init__(self, *args, **kwargs):
1226 self._authentication = kwargs.pop("authentication")
1227 super(CustomClient,self).__init__( *args, **kwargs)
1229 app.test_client_class = CustomClient
1230 client = app.test_client(authentication='Basic ....')
1232 See :class:`~flask.testing.FlaskClient` for more information.
1234 .. versionchanged:: 0.4
1235 added support for ``with`` block usage for the client.
1237 .. versionadded:: 0.7
1238 The `use_cookies` parameter was added as well as the ability
1239 to override the client to be used by setting the
1240 :attr:`test_client_class` attribute.
1242 .. versionchanged:: 0.11
1243 Added `**kwargs` to support passing additional keyword arguments to
1244 the constructor of :attr:`test_client_class`.
1245 """
1246 cls = self.test_client_class
1247 if cls is None:
1248 from .testing import FlaskClient as cls # type: ignore
1249 return cls( # type: ignore
1250 self, self.response_class, use_cookies=use_cookies, **kwargs
1251 )
1253 def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner":
1254 """Create a CLI runner for testing CLI commands.
1255 See :ref:`testing-cli`.
1257 Returns an instance of :attr:`test_cli_runner_class`, by default
1258 :class:`~flask.testing.FlaskCliRunner`. The Flask app object is
1259 passed as the first argument.
1261 .. versionadded:: 1.0
1262 """
1263 cls = self.test_cli_runner_class
1265 if cls is None:
1266 from .testing import FlaskCliRunner as cls # type: ignore
1268 return cls(self, **kwargs) # type: ignore
1270 @setupmethod
1271 def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
1272 """Register a :class:`~flask.Blueprint` on the application. Keyword
1273 arguments passed to this method will override the defaults set on the
1274 blueprint.
1276 Calls the blueprint's :meth:`~flask.Blueprint.register` method after
1277 recording the blueprint in the application's :attr:`blueprints`.
1279 :param blueprint: The blueprint to register.
1280 :param url_prefix: Blueprint routes will be prefixed with this.
1281 :param subdomain: Blueprint routes will match on this subdomain.
1282 :param url_defaults: Blueprint routes will use these default values for
1283 view arguments.
1284 :param options: Additional keyword arguments are passed to
1285 :class:`~flask.blueprints.BlueprintSetupState`. They can be
1286 accessed in :meth:`~flask.Blueprint.record` callbacks.
1288 .. versionchanged:: 2.0.1
1289 The ``name`` option can be used to change the (pre-dotted)
1290 name the blueprint is registered with. This allows the same
1291 blueprint to be registered multiple times with unique names
1292 for ``url_for``.
1294 .. versionadded:: 0.7
1295 """
1296 blueprint.register(self, options)
1298 def iter_blueprints(self) -> t.ValuesView["Blueprint"]:
1299 """Iterates over all blueprints by the order they were registered.
1301 .. versionadded:: 0.11
1302 """
1303 return self.blueprints.values()
1305 @setupmethod
1306 def add_url_rule(
1307 self,
1308 rule: str,
1309 endpoint: t.Optional[str] = None,
1310 view_func: t.Optional[ft.RouteCallable] = None,
1311 provide_automatic_options: t.Optional[bool] = None,
1312 **options: t.Any,
1313 ) -> None:
1314 if endpoint is None:
1315 endpoint = _endpoint_from_view_func(view_func) # type: ignore
1316 options["endpoint"] = endpoint
1317 methods = options.pop("methods", None)
1319 # if the methods are not given and the view_func object knows its
1320 # methods we can use that instead. If neither exists, we go with
1321 # a tuple of only ``GET`` as default.
1322 if methods is None:
1323 methods = getattr(view_func, "methods", None) or ("GET",)
1324 if isinstance(methods, str):
1325 raise TypeError(
1326 "Allowed methods must be a list of strings, for"
1327 ' example: @app.route(..., methods=["POST"])'
1328 )
1329 methods = {item.upper() for item in methods}
1331 # Methods that should always be added
1332 required_methods = set(getattr(view_func, "required_methods", ()))
1334 # starting with Flask 0.8 the view_func object can disable and
1335 # force-enable the automatic options handling.
1336 if provide_automatic_options is None:
1337 provide_automatic_options = getattr(
1338 view_func, "provide_automatic_options", None
1339 )
1341 if provide_automatic_options is None:
1342 if "OPTIONS" not in methods:
1343 provide_automatic_options = True
1344 required_methods.add("OPTIONS")
1345 else:
1346 provide_automatic_options = False
1348 # Add the required methods now.
1349 methods |= required_methods
1351 rule = self.url_rule_class(rule, methods=methods, **options)
1352 rule.provide_automatic_options = provide_automatic_options # type: ignore
1354 self.url_map.add(rule)
1355 if view_func is not None:
1356 old_func = self.view_functions.get(endpoint)
1357 if old_func is not None and old_func != view_func:
1358 raise AssertionError(
1359 "View function mapping is overwriting an existing"
1360 f" endpoint function: {endpoint}"
1361 )
1362 self.view_functions[endpoint] = view_func
1364 @setupmethod
1365 def template_filter(
1366 self, name: t.Optional[str] = None
1367 ) -> t.Callable[[T_template_filter], T_template_filter]:
1368 """A decorator that is used to register custom template filter.
1369 You can specify a name for the filter, otherwise the function
1370 name will be used. Example::
1372 @app.template_filter()
1373 def reverse(s):
1374 return s[::-1]
1376 :param name: the optional name of the filter, otherwise the
1377 function name will be used.
1378 """
1380 def decorator(f: T_template_filter) -> T_template_filter:
1381 self.add_template_filter(f, name=name)
1382 return f
1384 return decorator
1386 @setupmethod
1387 def add_template_filter(
1388 self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
1389 ) -> None:
1390 """Register a custom template filter. Works exactly like the
1391 :meth:`template_filter` decorator.
1393 :param name: the optional name of the filter, otherwise the
1394 function name will be used.
1395 """
1396 self.jinja_env.filters[name or f.__name__] = f
1398 @setupmethod
1399 def template_test(
1400 self, name: t.Optional[str] = None
1401 ) -> t.Callable[[T_template_test], T_template_test]:
1402 """A decorator that is used to register custom template test.
1403 You can specify a name for the test, otherwise the function
1404 name will be used. Example::
1406 @app.template_test()
1407 def is_prime(n):
1408 if n == 2:
1409 return True
1410 for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
1411 if n % i == 0:
1412 return False
1413 return True
1415 .. versionadded:: 0.10
1417 :param name: the optional name of the test, otherwise the
1418 function name will be used.
1419 """
1421 def decorator(f: T_template_test) -> T_template_test:
1422 self.add_template_test(f, name=name)
1423 return f
1425 return decorator
1427 @setupmethod
1428 def add_template_test(
1429 self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
1430 ) -> None:
1431 """Register a custom template test. Works exactly like the
1432 :meth:`template_test` decorator.
1434 .. versionadded:: 0.10
1436 :param name: the optional name of the test, otherwise the
1437 function name will be used.
1438 """
1439 self.jinja_env.tests[name or f.__name__] = f
1441 @setupmethod
1442 def template_global(
1443 self, name: t.Optional[str] = None
1444 ) -> t.Callable[[T_template_global], T_template_global]:
1445 """A decorator that is used to register a custom template global function.
1446 You can specify a name for the global function, otherwise the function
1447 name will be used. Example::
1449 @app.template_global()
1450 def double(n):
1451 return 2 * n
1453 .. versionadded:: 0.10
1455 :param name: the optional name of the global function, otherwise the
1456 function name will be used.
1457 """
1459 def decorator(f: T_template_global) -> T_template_global:
1460 self.add_template_global(f, name=name)
1461 return f
1463 return decorator
1465 @setupmethod
1466 def add_template_global(
1467 self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
1468 ) -> None:
1469 """Register a custom template global function. Works exactly like the
1470 :meth:`template_global` decorator.
1472 .. versionadded:: 0.10
1474 :param name: the optional name of the global function, otherwise the
1475 function name will be used.
1476 """
1477 self.jinja_env.globals[name or f.__name__] = f
1479 @setupmethod
1480 def before_first_request(self, f: T_before_first_request) -> T_before_first_request:
1481 """Registers a function to be run before the first request to this
1482 instance of the application.
1484 The function will be called without any arguments and its return
1485 value is ignored.
1487 .. deprecated:: 2.2
1488 Will be removed in Flask 2.3. Run setup code when creating
1489 the application instead.
1491 .. versionadded:: 0.8
1492 """
1493 import warnings
1495 warnings.warn(
1496 "'before_first_request' is deprecated and will be removed"
1497 " in Flask 2.3. Run setup code while creating the"
1498 " application instead.",
1499 DeprecationWarning,
1500 stacklevel=2,
1501 )
1502 self.before_first_request_funcs.append(f)
1503 return f
1505 @setupmethod
1506 def teardown_appcontext(self, f: T_teardown) -> T_teardown:
1507 """Registers a function to be called when the application
1508 context is popped. The application context is typically popped
1509 after the request context for each request, at the end of CLI
1510 commands, or after a manually pushed context ends.
1512 .. code-block:: python
1514 with app.app_context():
1515 ...
1517 When the ``with`` block exits (or ``ctx.pop()`` is called), the
1518 teardown functions are called just before the app context is
1519 made inactive. Since a request context typically also manages an
1520 application context it would also be called when you pop a
1521 request context.
1523 When a teardown function was called because of an unhandled
1524 exception it will be passed an error object. If an
1525 :meth:`errorhandler` is registered, it will handle the exception
1526 and the teardown will not receive it.
1528 Teardown functions must avoid raising exceptions. If they
1529 execute code that might fail they must surround that code with a
1530 ``try``/``except`` block and log any errors.
1532 The return values of teardown functions are ignored.
1534 .. versionadded:: 0.9
1535 """
1536 self.teardown_appcontext_funcs.append(f)
1537 return f
1539 @setupmethod
1540 def shell_context_processor(
1541 self, f: T_shell_context_processor
1542 ) -> T_shell_context_processor:
1543 """Registers a shell context processor function.
1545 .. versionadded:: 0.11
1546 """
1547 self.shell_context_processors.append(f)
1548 return f
1550 def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]:
1551 """Return a registered error handler for an exception in this order:
1552 blueprint handler for a specific code, app handler for a specific code,
1553 blueprint handler for an exception class, app handler for an exception
1554 class, or ``None`` if a suitable handler is not found.
1555 """
1556 exc_class, code = self._get_exc_class_and_code(type(e))
1557 names = (*request.blueprints, None)
1559 for c in (code, None) if code is not None else (None,):
1560 for name in names:
1561 handler_map = self.error_handler_spec[name][c]
1563 if not handler_map:
1564 continue
1566 for cls in exc_class.__mro__:
1567 handler = handler_map.get(cls)
1569 if handler is not None:
1570 return handler
1571 return None
1573 def handle_http_exception(
1574 self, e: HTTPException
1575 ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
1576 """Handles an HTTP exception. By default this will invoke the
1577 registered error handlers and fall back to returning the
1578 exception as response.
1580 .. versionchanged:: 1.0.3
1581 ``RoutingException``, used internally for actions such as
1582 slash redirects during routing, is not passed to error
1583 handlers.
1585 .. versionchanged:: 1.0
1586 Exceptions are looked up by code *and* by MRO, so
1587 ``HTTPException`` subclasses can be handled with a catch-all
1588 handler for the base ``HTTPException``.
1590 .. versionadded:: 0.3
1591 """
1592 # Proxy exceptions don't have error codes. We want to always return
1593 # those unchanged as errors
1594 if e.code is None:
1595 return e
1597 # RoutingExceptions are used internally to trigger routing
1598 # actions, such as slash redirects raising RequestRedirect. They
1599 # are not raised or handled in user code.
1600 if isinstance(e, RoutingException):
1601 return e
1603 handler = self._find_error_handler(e)
1604 if handler is None:
1605 return e
1606 return self.ensure_sync(handler)(e)
1608 def trap_http_exception(self, e: Exception) -> bool:
1609 """Checks if an HTTP exception should be trapped or not. By default
1610 this will return ``False`` for all exceptions except for a bad request
1611 key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It
1612 also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``.
1614 This is called for all HTTP exceptions raised by a view function.
1615 If it returns ``True`` for any exception the error handler for this
1616 exception is not called and it shows up as regular exception in the
1617 traceback. This is helpful for debugging implicitly raised HTTP
1618 exceptions.
1620 .. versionchanged:: 1.0
1621 Bad request errors are not trapped by default in debug mode.
1623 .. versionadded:: 0.8
1624 """
1625 if self.config["TRAP_HTTP_EXCEPTIONS"]:
1626 return True
1628 trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"]
1630 # if unset, trap key errors in debug mode
1631 if (
1632 trap_bad_request is None
1633 and self.debug
1634 and isinstance(e, BadRequestKeyError)
1635 ):
1636 return True
1638 if trap_bad_request:
1639 return isinstance(e, BadRequest)
1641 return False
1643 def handle_user_exception(
1644 self, e: Exception
1645 ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
1646 """This method is called whenever an exception occurs that
1647 should be handled. A special case is :class:`~werkzeug
1648 .exceptions.HTTPException` which is forwarded to the
1649 :meth:`handle_http_exception` method. This function will either
1650 return a response value or reraise the exception with the same
1651 traceback.
1653 .. versionchanged:: 1.0
1654 Key errors raised from request data like ``form`` show the
1655 bad key in debug mode rather than a generic bad request
1656 message.
1658 .. versionadded:: 0.7
1659 """
1660 if isinstance(e, BadRequestKeyError) and (
1661 self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
1662 ):
1663 e.show_exception = True
1665 if isinstance(e, HTTPException) and not self.trap_http_exception(e):
1666 return self.handle_http_exception(e)
1668 handler = self._find_error_handler(e)
1670 if handler is None:
1671 raise
1673 return self.ensure_sync(handler)(e)
1675 def handle_exception(self, e: Exception) -> Response:
1676 """Handle an exception that did not have an error handler
1677 associated with it, or that was raised from an error handler.
1678 This always causes a 500 ``InternalServerError``.
1680 Always sends the :data:`got_request_exception` signal.
1682 If :attr:`propagate_exceptions` is ``True``, such as in debug
1683 mode, the error will be re-raised so that the debugger can
1684 display it. Otherwise, the original exception is logged, and
1685 an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
1687 If an error handler is registered for ``InternalServerError`` or
1688 ``500``, it will be used. For consistency, the handler will
1689 always receive the ``InternalServerError``. The original
1690 unhandled exception is available as ``e.original_exception``.
1692 .. versionchanged:: 1.1.0
1693 Always passes the ``InternalServerError`` instance to the
1694 handler, setting ``original_exception`` to the unhandled
1695 error.
1697 .. versionchanged:: 1.1.0
1698 ``after_request`` functions and other finalization is done
1699 even for the default 500 response when there is no handler.
1701 .. versionadded:: 0.3
1702 """
1703 exc_info = sys.exc_info()
1704 got_request_exception.send(self, exception=e)
1705 propagate = self.config["PROPAGATE_EXCEPTIONS"]
1707 if propagate is None:
1708 propagate = self.testing or self.debug
1710 if propagate:
1711 # Re-raise if called with an active exception, otherwise
1712 # raise the passed in exception.
1713 if exc_info[1] is e:
1714 raise
1716 raise e
1718 self.log_exception(exc_info)
1719 server_error: t.Union[InternalServerError, ft.ResponseReturnValue]
1720 server_error = InternalServerError(original_exception=e)
1721 handler = self._find_error_handler(server_error)
1723 if handler is not None:
1724 server_error = self.ensure_sync(handler)(server_error)
1726 return self.finalize_request(server_error, from_error_handler=True)
1728 def log_exception(
1729 self,
1730 exc_info: t.Union[
1731 t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None]
1732 ],
1733 ) -> None:
1734 """Logs an exception. This is called by :meth:`handle_exception`
1735 if debugging is disabled and right before the handler is called.
1736 The default implementation logs the exception as error on the
1737 :attr:`logger`.
1739 .. versionadded:: 0.8
1740 """
1741 self.logger.error(
1742 f"Exception on {request.path} [{request.method}]", exc_info=exc_info
1743 )
1745 def raise_routing_exception(self, request: Request) -> "te.NoReturn":
1746 """Intercept routing exceptions and possibly do something else.
1748 In debug mode, intercept a routing redirect and replace it with
1749 an error if the body will be discarded.
1751 With modern Werkzeug this shouldn't occur, since it now uses a
1752 308 status which tells the browser to resend the method and
1753 body.
1755 .. versionchanged:: 2.1
1756 Don't intercept 307 and 308 redirects.
1758 :meta private:
1759 :internal:
1760 """
1761 if (
1762 not self.debug
1763 or not isinstance(request.routing_exception, RequestRedirect)
1764 or request.routing_exception.code in {307, 308}
1765 or request.method in {"GET", "HEAD", "OPTIONS"}
1766 ):
1767 raise request.routing_exception # type: ignore
1769 from .debughelpers import FormDataRoutingRedirect
1771 raise FormDataRoutingRedirect(request)
1773 def dispatch_request(self) -> ft.ResponseReturnValue:
1774 """Does the request dispatching. Matches the URL and returns the
1775 return value of the view or error handler. This does not have to
1776 be a response object. In order to convert the return value to a
1777 proper response object, call :func:`make_response`.
1779 .. versionchanged:: 0.7
1780 This no longer does the exception handling, this code was
1781 moved to the new :meth:`full_dispatch_request`.
1782 """
1783 req = request_ctx.request
1784 if req.routing_exception is not None:
1785 self.raise_routing_exception(req)
1786 rule: Rule = req.url_rule # type: ignore[assignment]
1787 # if we provide automatic options for this URL and the
1788 # request came with the OPTIONS method, reply automatically
1789 if (
1790 getattr(rule, "provide_automatic_options", False)
1791 and req.method == "OPTIONS"
1792 ):
1793 return self.make_default_options_response()
1794 # otherwise dispatch to the handler for that endpoint
1795 view_args: t.Dict[str, t.Any] = req.view_args # type: ignore[assignment]
1796 return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
1798 def full_dispatch_request(self) -> Response:
1799 """Dispatches the request and on top of that performs request
1800 pre and postprocessing as well as HTTP exception catching and
1801 error handling.
1803 .. versionadded:: 0.7
1804 """
1805 # Run before_first_request functions if this is the thread's first request.
1806 # Inlined to avoid a method call on subsequent requests.
1807 # This is deprecated, will be removed in Flask 2.3.
1808 if not self._got_first_request:
1809 with self._before_request_lock:
1810 if not self._got_first_request:
1811 for func in self.before_first_request_funcs:
1812 self.ensure_sync(func)()
1814 self._got_first_request = True
1816 try:
1817 request_started.send(self)
1818 rv = self.preprocess_request()
1819 if rv is None:
1820 rv = self.dispatch_request()
1821 except Exception as e:
1822 rv = self.handle_user_exception(e)
1823 return self.finalize_request(rv)
1825 def finalize_request(
1826 self,
1827 rv: t.Union[ft.ResponseReturnValue, HTTPException],
1828 from_error_handler: bool = False,
1829 ) -> Response:
1830 """Given the return value from a view function this finalizes
1831 the request by converting it into a response and invoking the
1832 postprocessing functions. This is invoked for both normal
1833 request dispatching as well as error handlers.
1835 Because this means that it might be called as a result of a
1836 failure a special safe mode is available which can be enabled
1837 with the `from_error_handler` flag. If enabled, failures in
1838 response processing will be logged and otherwise ignored.
1840 :internal:
1841 """
1842 response = self.make_response(rv)
1843 try:
1844 response = self.process_response(response)
1845 request_finished.send(self, response=response)
1846 except Exception:
1847 if not from_error_handler:
1848 raise
1849 self.logger.exception(
1850 "Request finalizing failed with an error while handling an error"
1851 )
1852 return response
1854 def make_default_options_response(self) -> Response:
1855 """This method is called to create the default ``OPTIONS`` response.
1856 This can be changed through subclassing to change the default
1857 behavior of ``OPTIONS`` responses.
1859 .. versionadded:: 0.7
1860 """
1861 adapter = request_ctx.url_adapter
1862 methods = adapter.allowed_methods() # type: ignore[union-attr]
1863 rv = self.response_class()
1864 rv.allow.update(methods)
1865 return rv
1867 def should_ignore_error(self, error: t.Optional[BaseException]) -> bool:
1868 """This is called to figure out if an error should be ignored
1869 or not as far as the teardown system is concerned. If this
1870 function returns ``True`` then the teardown handlers will not be
1871 passed the error.
1873 .. versionadded:: 0.10
1874 """
1875 return False
1877 def ensure_sync(self, func: t.Callable) -> t.Callable:
1878 """Ensure that the function is synchronous for WSGI workers.
1879 Plain ``def`` functions are returned as-is. ``async def``
1880 functions are wrapped to run and wait for the response.
1882 Override this method to change how the app runs async views.
1884 .. versionadded:: 2.0
1885 """
1886 if iscoroutinefunction(func):
1887 return self.async_to_sync(func)
1889 return func
1891 def async_to_sync(
1892 self, func: t.Callable[..., t.Coroutine]
1893 ) -> t.Callable[..., t.Any]:
1894 """Return a sync function that will run the coroutine function.
1896 .. code-block:: python
1898 result = app.async_to_sync(func)(*args, **kwargs)
1900 Override this method to change how the app converts async code
1901 to be synchronously callable.
1903 .. versionadded:: 2.0
1904 """
1905 try:
1906 from asgiref.sync import async_to_sync as asgiref_async_to_sync
1907 except ImportError:
1908 raise RuntimeError(
1909 "Install Flask with the 'async' extra in order to use async views."
1910 ) from None
1912 return asgiref_async_to_sync(func)
1914 def url_for(
1915 self,
1916 endpoint: str,
1917 *,
1918 _anchor: t.Optional[str] = None,
1919 _method: t.Optional[str] = None,
1920 _scheme: t.Optional[str] = None,
1921 _external: t.Optional[bool] = None,
1922 **values: t.Any,
1923 ) -> str:
1924 """Generate a URL to the given endpoint with the given values.
1926 This is called by :func:`flask.url_for`, and can be called
1927 directly as well.
1929 An *endpoint* is the name of a URL rule, usually added with
1930 :meth:`@app.route() <route>`, and usually the same name as the
1931 view function. A route defined in a :class:`~flask.Blueprint`
1932 will prepend the blueprint's name separated by a ``.`` to the
1933 endpoint.
1935 In some cases, such as email messages, you want URLs to include
1936 the scheme and domain, like ``https://example.com/hello``. When
1937 not in an active request, URLs will be external by default, but
1938 this requires setting :data:`SERVER_NAME` so Flask knows what
1939 domain to use. :data:`APPLICATION_ROOT` and
1940 :data:`PREFERRED_URL_SCHEME` should also be configured as
1941 needed. This config is only used when not in an active request.
1943 Functions can be decorated with :meth:`url_defaults` to modify
1944 keyword arguments before the URL is built.
1946 If building fails for some reason, such as an unknown endpoint
1947 or incorrect values, the app's :meth:`handle_url_build_error`
1948 method is called. If that returns a string, that is returned,
1949 otherwise a :exc:`~werkzeug.routing.BuildError` is raised.
1951 :param endpoint: The endpoint name associated with the URL to
1952 generate. If this starts with a ``.``, the current blueprint
1953 name (if any) will be used.
1954 :param _anchor: If given, append this as ``#anchor`` to the URL.
1955 :param _method: If given, generate the URL associated with this
1956 method for the endpoint.
1957 :param _scheme: If given, the URL will have this scheme if it
1958 is external.
1959 :param _external: If given, prefer the URL to be internal
1960 (False) or require it to be external (True). External URLs
1961 include the scheme and domain. When not in an active
1962 request, URLs are external by default.
1963 :param values: Values to use for the variable parts of the URL
1964 rule. Unknown keys are appended as query string arguments,
1965 like ``?a=b&c=d``.
1967 .. versionadded:: 2.2
1968 Moved from ``flask.url_for``, which calls this method.
1969 """
1970 req_ctx = _cv_request.get(None)
1972 if req_ctx is not None:
1973 url_adapter = req_ctx.url_adapter
1974 blueprint_name = req_ctx.request.blueprint
1976 # If the endpoint starts with "." and the request matches a
1977 # blueprint, the endpoint is relative to the blueprint.
1978 if endpoint[:1] == ".":
1979 if blueprint_name is not None:
1980 endpoint = f"{blueprint_name}{endpoint}"
1981 else:
1982 endpoint = endpoint[1:]
1984 # When in a request, generate a URL without scheme and
1985 # domain by default, unless a scheme is given.
1986 if _external is None:
1987 _external = _scheme is not None
1988 else:
1989 app_ctx = _cv_app.get(None)
1991 # If called by helpers.url_for, an app context is active,
1992 # use its url_adapter. Otherwise, app.url_for was called
1993 # directly, build an adapter.
1994 if app_ctx is not None:
1995 url_adapter = app_ctx.url_adapter
1996 else:
1997 url_adapter = self.create_url_adapter(None)
1999 if url_adapter is None:
2000 raise RuntimeError(
2001 "Unable to build URLs outside an active request"
2002 " without 'SERVER_NAME' configured. Also configure"
2003 " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
2004 " needed."
2005 )
2007 # When outside a request, generate a URL with scheme and
2008 # domain by default.
2009 if _external is None:
2010 _external = True
2012 # It is an error to set _scheme when _external=False, in order
2013 # to avoid accidental insecure URLs.
2014 if _scheme is not None and not _external:
2015 raise ValueError("When specifying '_scheme', '_external' must be True.")
2017 self.inject_url_defaults(endpoint, values)
2019 try:
2020 rv = url_adapter.build( # type: ignore[union-attr]
2021 endpoint,
2022 values,
2023 method=_method,
2024 url_scheme=_scheme,
2025 force_external=_external,
2026 )
2027 except BuildError as error:
2028 values.update(
2029 _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
2030 )
2031 return self.handle_url_build_error(error, endpoint, values)
2033 if _anchor is not None:
2034 rv = f"{rv}#{url_quote(_anchor)}"
2036 return rv
2038 def redirect(self, location: str, code: int = 302) -> BaseResponse:
2039 """Create a redirect response object.
2041 This is called by :func:`flask.redirect`, and can be called
2042 directly as well.
2044 :param location: The URL to redirect to.
2045 :param code: The status code for the redirect.
2047 .. versionadded:: 2.2
2048 Moved from ``flask.redirect``, which calls this method.
2049 """
2050 return _wz_redirect(location, code=code, Response=self.response_class)
2052 def make_response(self, rv: ft.ResponseReturnValue) -> Response:
2053 """Convert the return value from a view function to an instance of
2054 :attr:`response_class`.
2056 :param rv: the return value from the view function. The view function
2057 must return a response. Returning ``None``, or the view ending
2058 without returning, is not allowed. The following types are allowed
2059 for ``view_rv``:
2061 ``str``
2062 A response object is created with the string encoded to UTF-8
2063 as the body.
2065 ``bytes``
2066 A response object is created with the bytes as the body.
2068 ``dict``
2069 A dictionary that will be jsonify'd before being returned.
2071 ``list``
2072 A list that will be jsonify'd before being returned.
2074 ``generator`` or ``iterator``
2075 A generator that returns ``str`` or ``bytes`` to be
2076 streamed as the response.
2078 ``tuple``
2079 Either ``(body, status, headers)``, ``(body, status)``, or
2080 ``(body, headers)``, where ``body`` is any of the other types
2081 allowed here, ``status`` is a string or an integer, and
2082 ``headers`` is a dictionary or a list of ``(key, value)``
2083 tuples. If ``body`` is a :attr:`response_class` instance,
2084 ``status`` overwrites the exiting value and ``headers`` are
2085 extended.
2087 :attr:`response_class`
2088 The object is returned unchanged.
2090 other :class:`~werkzeug.wrappers.Response` class
2091 The object is coerced to :attr:`response_class`.
2093 :func:`callable`
2094 The function is called as a WSGI application. The result is
2095 used to create a response object.
2097 .. versionchanged:: 2.2
2098 A generator will be converted to a streaming response.
2099 A list will be converted to a JSON response.
2101 .. versionchanged:: 1.1
2102 A dict will be converted to a JSON response.
2104 .. versionchanged:: 0.9
2105 Previously a tuple was interpreted as the arguments for the
2106 response object.
2107 """
2109 status = headers = None
2111 # unpack tuple returns
2112 if isinstance(rv, tuple):
2113 len_rv = len(rv)
2115 # a 3-tuple is unpacked directly
2116 if len_rv == 3:
2117 rv, status, headers = rv # type: ignore[misc]
2118 # decide if a 2-tuple has status or headers
2119 elif len_rv == 2:
2120 if isinstance(rv[1], (Headers, dict, tuple, list)):
2121 rv, headers = rv
2122 else:
2123 rv, status = rv # type: ignore[assignment,misc]
2124 # other sized tuples are not allowed
2125 else:
2126 raise TypeError(
2127 "The view function did not return a valid response tuple."
2128 " The tuple must have the form (body, status, headers),"
2129 " (body, status), or (body, headers)."
2130 )
2132 # the body must not be None
2133 if rv is None:
2134 raise TypeError(
2135 f"The view function for {request.endpoint!r} did not"
2136 " return a valid response. The function either returned"
2137 " None or ended without a return statement."
2138 )
2140 # make sure the body is an instance of the response class
2141 if not isinstance(rv, self.response_class):
2142 if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, _abc_Iterator):
2143 # let the response class set the status and headers instead of
2144 # waiting to do it manually, so that the class can handle any
2145 # special logic
2146 rv = self.response_class(
2147 rv,
2148 status=status,
2149 headers=headers, # type: ignore[arg-type]
2150 )
2151 status = headers = None
2152 elif isinstance(rv, (dict, list)):
2153 rv = self.json.response(rv)
2154 elif isinstance(rv, BaseResponse) or callable(rv):
2155 # evaluate a WSGI callable, or coerce a different response
2156 # class to the correct type
2157 try:
2158 rv = self.response_class.force_type(
2159 rv, request.environ # type: ignore[arg-type]
2160 )
2161 except TypeError as e:
2162 raise TypeError(
2163 f"{e}\nThe view function did not return a valid"
2164 " response. The return type must be a string,"
2165 " dict, list, tuple with headers or status,"
2166 " Response instance, or WSGI callable, but it"
2167 f" was a {type(rv).__name__}."
2168 ).with_traceback(sys.exc_info()[2]) from None
2169 else:
2170 raise TypeError(
2171 "The view function did not return a valid"
2172 " response. The return type must be a string,"
2173 " dict, list, tuple with headers or status,"
2174 " Response instance, or WSGI callable, but it was a"
2175 f" {type(rv).__name__}."
2176 )
2178 rv = t.cast(Response, rv)
2179 # prefer the status if it was provided
2180 if status is not None:
2181 if isinstance(status, (str, bytes, bytearray)):
2182 rv.status = status
2183 else:
2184 rv.status_code = status
2186 # extend existing headers with provided headers
2187 if headers:
2188 rv.headers.update(headers) # type: ignore[arg-type]
2190 return rv
2192 def create_url_adapter(
2193 self, request: t.Optional[Request]
2194 ) -> t.Optional[MapAdapter]:
2195 """Creates a URL adapter for the given request. The URL adapter
2196 is created at a point where the request context is not yet set
2197 up so the request is passed explicitly.
2199 .. versionadded:: 0.6
2201 .. versionchanged:: 0.9
2202 This can now also be called without a request object when the
2203 URL adapter is created for the application context.
2205 .. versionchanged:: 1.0
2206 :data:`SERVER_NAME` no longer implicitly enables subdomain
2207 matching. Use :attr:`subdomain_matching` instead.
2208 """
2209 if request is not None:
2210 # If subdomain matching is disabled (the default), use the
2211 # default subdomain in all cases. This should be the default
2212 # in Werkzeug but it currently does not have that feature.
2213 if not self.subdomain_matching:
2214 subdomain = self.url_map.default_subdomain or None
2215 else:
2216 subdomain = None
2218 return self.url_map.bind_to_environ(
2219 request.environ,
2220 server_name=self.config["SERVER_NAME"],
2221 subdomain=subdomain,
2222 )
2223 # We need at the very least the server name to be set for this
2224 # to work.
2225 if self.config["SERVER_NAME"] is not None:
2226 return self.url_map.bind(
2227 self.config["SERVER_NAME"],
2228 script_name=self.config["APPLICATION_ROOT"],
2229 url_scheme=self.config["PREFERRED_URL_SCHEME"],
2230 )
2232 return None
2234 def inject_url_defaults(self, endpoint: str, values: dict) -> None:
2235 """Injects the URL defaults for the given endpoint directly into
2236 the values dictionary passed. This is used internally and
2237 automatically called on URL building.
2239 .. versionadded:: 0.7
2240 """
2241 names: t.Iterable[t.Optional[str]] = (None,)
2243 # url_for may be called outside a request context, parse the
2244 # passed endpoint instead of using request.blueprints.
2245 if "." in endpoint:
2246 names = chain(
2247 names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0]))
2248 )
2250 for name in names:
2251 if name in self.url_default_functions:
2252 for func in self.url_default_functions[name]:
2253 func(endpoint, values)
2255 def handle_url_build_error(
2256 self, error: BuildError, endpoint: str, values: t.Dict[str, t.Any]
2257 ) -> str:
2258 """Called by :meth:`.url_for` if a
2259 :exc:`~werkzeug.routing.BuildError` was raised. If this returns
2260 a value, it will be returned by ``url_for``, otherwise the error
2261 will be re-raised.
2263 Each function in :attr:`url_build_error_handlers` is called with
2264 ``error``, ``endpoint`` and ``values``. If a function returns
2265 ``None`` or raises a ``BuildError``, it is skipped. Otherwise,
2266 its return value is returned by ``url_for``.
2268 :param error: The active ``BuildError`` being handled.
2269 :param endpoint: The endpoint being built.
2270 :param values: The keyword arguments passed to ``url_for``.
2271 """
2272 for handler in self.url_build_error_handlers:
2273 try:
2274 rv = handler(error, endpoint, values)
2275 except BuildError as e:
2276 # make error available outside except block
2277 error = e
2278 else:
2279 if rv is not None:
2280 return rv
2282 # Re-raise if called with an active exception, otherwise raise
2283 # the passed in exception.
2284 if error is sys.exc_info()[1]:
2285 raise
2287 raise error
2289 def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]:
2290 """Called before the request is dispatched. Calls
2291 :attr:`url_value_preprocessors` registered with the app and the
2292 current blueprint (if any). Then calls :attr:`before_request_funcs`
2293 registered with the app and the blueprint.
2295 If any :meth:`before_request` handler returns a non-None value, the
2296 value is handled as if it was the return value from the view, and
2297 further request handling is stopped.
2298 """
2299 names = (None, *reversed(request.blueprints))
2301 for name in names:
2302 if name in self.url_value_preprocessors:
2303 for url_func in self.url_value_preprocessors[name]:
2304 url_func(request.endpoint, request.view_args)
2306 for name in names:
2307 if name in self.before_request_funcs:
2308 for before_func in self.before_request_funcs[name]:
2309 rv = self.ensure_sync(before_func)()
2311 if rv is not None:
2312 return rv
2314 return None
2316 def process_response(self, response: Response) -> Response:
2317 """Can be overridden in order to modify the response object
2318 before it's sent to the WSGI server. By default this will
2319 call all the :meth:`after_request` decorated functions.
2321 .. versionchanged:: 0.5
2322 As of Flask 0.5 the functions registered for after request
2323 execution are called in reverse order of registration.
2325 :param response: a :attr:`response_class` object.
2326 :return: a new response object or the same, has to be an
2327 instance of :attr:`response_class`.
2328 """
2329 ctx = request_ctx._get_current_object() # type: ignore[attr-defined]
2331 for func in ctx._after_request_functions:
2332 response = self.ensure_sync(func)(response)
2334 for name in chain(request.blueprints, (None,)):
2335 if name in self.after_request_funcs:
2336 for func in reversed(self.after_request_funcs[name]):
2337 response = self.ensure_sync(func)(response)
2339 if not self.session_interface.is_null_session(ctx.session):
2340 self.session_interface.save_session(self, ctx.session, response)
2342 return response
2344 def do_teardown_request(
2345 self, exc: t.Optional[BaseException] = _sentinel # type: ignore
2346 ) -> None:
2347 """Called after the request is dispatched and the response is
2348 returned, right before the request context is popped.
2350 This calls all functions decorated with
2351 :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`
2352 if a blueprint handled the request. Finally, the
2353 :data:`request_tearing_down` signal is sent.
2355 This is called by
2356 :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,
2357 which may be delayed during testing to maintain access to
2358 resources.
2360 :param exc: An unhandled exception raised while dispatching the
2361 request. Detected from the current exception information if
2362 not passed. Passed to each teardown function.
2364 .. versionchanged:: 0.9
2365 Added the ``exc`` argument.
2366 """
2367 if exc is _sentinel:
2368 exc = sys.exc_info()[1]
2370 for name in chain(request.blueprints, (None,)):
2371 if name in self.teardown_request_funcs:
2372 for func in reversed(self.teardown_request_funcs[name]):
2373 self.ensure_sync(func)(exc)
2375 request_tearing_down.send(self, exc=exc)
2377 def do_teardown_appcontext(
2378 self, exc: t.Optional[BaseException] = _sentinel # type: ignore
2379 ) -> None:
2380 """Called right before the application context is popped.
2382 When handling a request, the application context is popped
2383 after the request context. See :meth:`do_teardown_request`.
2385 This calls all functions decorated with
2386 :meth:`teardown_appcontext`. Then the
2387 :data:`appcontext_tearing_down` signal is sent.
2389 This is called by
2390 :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.
2392 .. versionadded:: 0.9
2393 """
2394 if exc is _sentinel:
2395 exc = sys.exc_info()[1]
2397 for func in reversed(self.teardown_appcontext_funcs):
2398 self.ensure_sync(func)(exc)
2400 appcontext_tearing_down.send(self, exc=exc)
2402 def app_context(self) -> AppContext:
2403 """Create an :class:`~flask.ctx.AppContext`. Use as a ``with``
2404 block to push the context, which will make :data:`current_app`
2405 point at this application.
2407 An application context is automatically pushed by
2408 :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`
2409 when handling a request, and when running a CLI command. Use
2410 this to manually create a context outside of these situations.
2412 ::
2414 with app.app_context():
2415 init_db()
2417 See :doc:`/appcontext`.
2419 .. versionadded:: 0.9
2420 """
2421 return AppContext(self)
2423 def request_context(self, environ: dict) -> RequestContext:
2424 """Create a :class:`~flask.ctx.RequestContext` representing a
2425 WSGI environment. Use a ``with`` block to push the context,
2426 which will make :data:`request` point at this request.
2428 See :doc:`/reqcontext`.
2430 Typically you should not call this from your own code. A request
2431 context is automatically pushed by the :meth:`wsgi_app` when
2432 handling a request. Use :meth:`test_request_context` to create
2433 an environment and context instead of this method.
2435 :param environ: a WSGI environment
2436 """
2437 return RequestContext(self, environ)
2439 def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext:
2440 """Create a :class:`~flask.ctx.RequestContext` for a WSGI
2441 environment created from the given values. This is mostly useful
2442 during testing, where you may want to run a function that uses
2443 request data without dispatching a full request.
2445 See :doc:`/reqcontext`.
2447 Use a ``with`` block to push the context, which will make
2448 :data:`request` point at the request for the created
2449 environment. ::
2451 with test_request_context(...):
2452 generate_report()
2454 When using the shell, it may be easier to push and pop the
2455 context manually to avoid indentation. ::
2457 ctx = app.test_request_context(...)
2458 ctx.push()
2459 ...
2460 ctx.pop()
2462 Takes the same arguments as Werkzeug's
2463 :class:`~werkzeug.test.EnvironBuilder`, with some defaults from
2464 the application. See the linked Werkzeug docs for most of the
2465 available arguments. Flask-specific behavior is listed here.
2467 :param path: URL path being requested.
2468 :param base_url: Base URL where the app is being served, which
2469 ``path`` is relative to. If not given, built from
2470 :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
2471 :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
2472 :param subdomain: Subdomain name to append to
2473 :data:`SERVER_NAME`.
2474 :param url_scheme: Scheme to use instead of
2475 :data:`PREFERRED_URL_SCHEME`.
2476 :param data: The request body, either as a string or a dict of
2477 form keys and values.
2478 :param json: If given, this is serialized as JSON and passed as
2479 ``data``. Also defaults ``content_type`` to
2480 ``application/json``.
2481 :param args: other positional arguments passed to
2482 :class:`~werkzeug.test.EnvironBuilder`.
2483 :param kwargs: other keyword arguments passed to
2484 :class:`~werkzeug.test.EnvironBuilder`.
2485 """
2486 from .testing import EnvironBuilder
2488 builder = EnvironBuilder(self, *args, **kwargs)
2490 try:
2491 return self.request_context(builder.get_environ())
2492 finally:
2493 builder.close()
2495 def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any:
2496 """The actual WSGI application. This is not implemented in
2497 :meth:`__call__` so that middlewares can be applied without
2498 losing a reference to the app object. Instead of doing this::
2500 app = MyMiddleware(app)
2502 It's a better idea to do this instead::
2504 app.wsgi_app = MyMiddleware(app.wsgi_app)
2506 Then you still have the original application object around and
2507 can continue to call methods on it.
2509 .. versionchanged:: 0.7
2510 Teardown events for the request and app contexts are called
2511 even if an unhandled error occurs. Other events may not be
2512 called depending on when an error occurs during dispatch.
2513 See :ref:`callbacks-and-errors`.
2515 :param environ: A WSGI environment.
2516 :param start_response: A callable accepting a status code,
2517 a list of headers, and an optional exception context to
2518 start the response.
2519 """
2520 ctx = self.request_context(environ)
2521 error: t.Optional[BaseException] = None
2522 try:
2523 try:
2524 ctx.push()
2525 response = self.full_dispatch_request()
2526 except Exception as e:
2527 error = e
2528 response = self.handle_exception(e)
2529 except: # noqa: B001
2530 error = sys.exc_info()[1]
2531 raise
2532 return response(environ, start_response)
2533 finally:
2534 if "werkzeug.debug.preserve_context" in environ:
2535 environ["werkzeug.debug.preserve_context"](_cv_app.get())
2536 environ["werkzeug.debug.preserve_context"](_cv_request.get())
2538 if error is not None and self.should_ignore_error(error):
2539 error = None
2541 ctx.pop(error)
2543 def __call__(self, environ: dict, start_response: t.Callable) -> t.Any:
2544 """The WSGI server calls the Flask application object as the
2545 WSGI application. This calls :meth:`wsgi_app`, which can be
2546 wrapped to apply middleware.
2547 """
2548 return self.wsgi_app(environ, start_response)