Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/flask/app.py: 29%
695 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +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
14from urllib.parse import quote as _url_quote
16import click
17from werkzeug.datastructures import Headers
18from werkzeug.datastructures import ImmutableDict
19from werkzeug.exceptions import Aborter
20from werkzeug.exceptions import BadRequest
21from werkzeug.exceptions import BadRequestKeyError
22from werkzeug.exceptions import HTTPException
23from werkzeug.exceptions import InternalServerError
24from werkzeug.routing import BuildError
25from werkzeug.routing import Map
26from werkzeug.routing import MapAdapter
27from werkzeug.routing import RequestRedirect
28from werkzeug.routing import RoutingException
29from werkzeug.routing import Rule
30from werkzeug.serving import is_running_from_reloader
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]:
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]:
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[t.Union[str, os.PathLike]] = "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 .. versionchanged:: 2.2
965 Autoescaping is now enabled by default for ``.svg`` files.
967 .. versionadded:: 0.5
968 """
969 if filename is None:
970 return True
971 return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg"))
973 def update_template_context(self, context: dict) -> None:
974 """Update the template context with some commonly used variables.
975 This injects request, session, config and g into the template
976 context as well as everything template context processors want
977 to inject. Note that the as of Flask 0.6, the original values
978 in the context will not be overridden if a context processor
979 decides to return a value with the same key.
981 :param context: the context as a dictionary that is updated in place
982 to add extra variables.
983 """
984 names: t.Iterable[t.Optional[str]] = (None,)
986 # A template may be rendered outside a request context.
987 if request:
988 names = chain(names, reversed(request.blueprints))
990 # The values passed to render_template take precedence. Keep a
991 # copy to re-apply after all context functions.
992 orig_ctx = context.copy()
994 for name in names:
995 if name in self.template_context_processors:
996 for func in self.template_context_processors[name]:
997 context.update(func())
999 context.update(orig_ctx)
1001 def make_shell_context(self) -> dict:
1002 """Returns the shell context for an interactive shell for this
1003 application. This runs all the registered shell context
1004 processors.
1006 .. versionadded:: 0.11
1007 """
1008 rv = {"app": self, "g": g}
1009 for processor in self.shell_context_processors:
1010 rv.update(processor())
1011 return rv
1013 @property
1014 def env(self) -> str:
1015 """What environment the app is running in. This maps to the :data:`ENV` config
1016 key.
1018 **Do not enable development when deploying in production.**
1020 Default: ``'production'``
1022 .. deprecated:: 2.2
1023 Will be removed in Flask 2.3.
1024 """
1025 import warnings
1027 warnings.warn(
1028 "'app.env' is deprecated and will be removed in Flask 2.3."
1029 " Use 'app.debug' instead.",
1030 DeprecationWarning,
1031 stacklevel=2,
1032 )
1033 return self.config["ENV"]
1035 @env.setter
1036 def env(self, value: str) -> None:
1037 import warnings
1039 warnings.warn(
1040 "'app.env' is deprecated and will be removed in Flask 2.3."
1041 " Use 'app.debug' instead.",
1042 DeprecationWarning,
1043 stacklevel=2,
1044 )
1045 self.config["ENV"] = value
1047 @property
1048 def debug(self) -> bool:
1049 """Whether debug mode is enabled. When using ``flask run`` to start the
1050 development server, an interactive debugger will be shown for unhandled
1051 exceptions, and the server will be reloaded when code changes. This maps to the
1052 :data:`DEBUG` config key. It may not behave as expected if set late.
1054 **Do not enable debug mode when deploying in production.**
1056 Default: ``False``
1057 """
1058 return self.config["DEBUG"]
1060 @debug.setter
1061 def debug(self, value: bool) -> None:
1062 self.config["DEBUG"] = value
1064 if self.config["TEMPLATES_AUTO_RELOAD"] is None:
1065 self.jinja_env.auto_reload = value
1067 def run(
1068 self,
1069 host: t.Optional[str] = None,
1070 port: t.Optional[int] = None,
1071 debug: t.Optional[bool] = None,
1072 load_dotenv: bool = True,
1073 **options: t.Any,
1074 ) -> None:
1075 """Runs the application on a local development server.
1077 Do not use ``run()`` in a production setting. It is not intended to
1078 meet security and performance requirements for a production server.
1079 Instead, see :doc:`/deploying/index` for WSGI server recommendations.
1081 If the :attr:`debug` flag is set the server will automatically reload
1082 for code changes and show a debugger in case an exception happened.
1084 If you want to run the application in debug mode, but disable the
1085 code execution on the interactive debugger, you can pass
1086 ``use_evalex=False`` as parameter. This will keep the debugger's
1087 traceback screen active, but disable code execution.
1089 It is not recommended to use this function for development with
1090 automatic reloading as this is badly supported. Instead you should
1091 be using the :command:`flask` command line script's ``run`` support.
1093 .. admonition:: Keep in Mind
1095 Flask will suppress any server error with a generic error page
1096 unless it is in debug mode. As such to enable just the
1097 interactive debugger without the code reloading, you have to
1098 invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
1099 Setting ``use_debugger`` to ``True`` without being in debug mode
1100 won't catch any exceptions because there won't be any to
1101 catch.
1103 :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
1104 have the server available externally as well. Defaults to
1105 ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
1106 if present.
1107 :param port: the port of the webserver. Defaults to ``5000`` or the
1108 port defined in the ``SERVER_NAME`` config variable if present.
1109 :param debug: if given, enable or disable debug mode. See
1110 :attr:`debug`.
1111 :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
1112 files to set environment variables. Will also change the working
1113 directory to the directory containing the first file found.
1114 :param options: the options to be forwarded to the underlying Werkzeug
1115 server. See :func:`werkzeug.serving.run_simple` for more
1116 information.
1118 .. versionchanged:: 1.0
1119 If installed, python-dotenv will be used to load environment
1120 variables from :file:`.env` and :file:`.flaskenv` files.
1122 The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`.
1124 Threaded mode is enabled by default.
1126 .. versionchanged:: 0.10
1127 The default port is now picked from the ``SERVER_NAME``
1128 variable.
1129 """
1130 # Ignore this call so that it doesn't start another server if
1131 # the 'flask run' command is used.
1132 if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
1133 if not is_running_from_reloader():
1134 click.secho(
1135 " * Ignoring a call to 'app.run()' that would block"
1136 " the current 'flask' CLI command.\n"
1137 " Only call 'app.run()' in an 'if __name__ =="
1138 ' "__main__"\' guard.',
1139 fg="red",
1140 )
1142 return
1144 if get_load_dotenv(load_dotenv):
1145 cli.load_dotenv()
1147 # if set, let env vars override previous values
1148 if "FLASK_ENV" in os.environ:
1149 print(
1150 "'FLASK_ENV' is deprecated and will not be used in"
1151 " Flask 2.3. Use 'FLASK_DEBUG' instead.",
1152 file=sys.stderr,
1153 )
1154 self.config["ENV"] = os.environ.get("FLASK_ENV") or "production"
1155 self.debug = get_debug_flag()
1156 elif "FLASK_DEBUG" in os.environ:
1157 self.debug = get_debug_flag()
1159 # debug passed to method overrides all other sources
1160 if debug is not None:
1161 self.debug = bool(debug)
1163 server_name = self.config.get("SERVER_NAME")
1164 sn_host = sn_port = None
1166 if server_name:
1167 sn_host, _, sn_port = server_name.partition(":")
1169 if not host:
1170 if sn_host:
1171 host = sn_host
1172 else:
1173 host = "127.0.0.1"
1175 if port or port == 0:
1176 port = int(port)
1177 elif sn_port:
1178 port = int(sn_port)
1179 else:
1180 port = 5000
1182 options.setdefault("use_reloader", self.debug)
1183 options.setdefault("use_debugger", self.debug)
1184 options.setdefault("threaded", True)
1186 cli.show_server_banner(self.debug, self.name)
1188 from werkzeug.serving import run_simple
1190 try:
1191 run_simple(t.cast(str, host), port, self, **options)
1192 finally:
1193 # reset the first request information if the development server
1194 # reset normally. This makes it possible to restart the server
1195 # without reloader and that stuff from an interactive shell.
1196 self._got_first_request = False
1198 def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient":
1199 """Creates a test client for this application. For information
1200 about unit testing head over to :doc:`/testing`.
1202 Note that if you are testing for assertions or exceptions in your
1203 application code, you must set ``app.testing = True`` in order for the
1204 exceptions to propagate to the test client. Otherwise, the exception
1205 will be handled by the application (not visible to the test client) and
1206 the only indication of an AssertionError or other exception will be a
1207 500 status code response to the test client. See the :attr:`testing`
1208 attribute. For example::
1210 app.testing = True
1211 client = app.test_client()
1213 The test client can be used in a ``with`` block to defer the closing down
1214 of the context until the end of the ``with`` block. This is useful if
1215 you want to access the context locals for testing::
1217 with app.test_client() as c:
1218 rv = c.get('/?vodka=42')
1219 assert request.args['vodka'] == '42'
1221 Additionally, you may pass optional keyword arguments that will then
1222 be passed to the application's :attr:`test_client_class` constructor.
1223 For example::
1225 from flask.testing import FlaskClient
1227 class CustomClient(FlaskClient):
1228 def __init__(self, *args, **kwargs):
1229 self._authentication = kwargs.pop("authentication")
1230 super(CustomClient,self).__init__( *args, **kwargs)
1232 app.test_client_class = CustomClient
1233 client = app.test_client(authentication='Basic ....')
1235 See :class:`~flask.testing.FlaskClient` for more information.
1237 .. versionchanged:: 0.4
1238 added support for ``with`` block usage for the client.
1240 .. versionadded:: 0.7
1241 The `use_cookies` parameter was added as well as the ability
1242 to override the client to be used by setting the
1243 :attr:`test_client_class` attribute.
1245 .. versionchanged:: 0.11
1246 Added `**kwargs` to support passing additional keyword arguments to
1247 the constructor of :attr:`test_client_class`.
1248 """
1249 cls = self.test_client_class
1250 if cls is None:
1251 from .testing import FlaskClient as cls
1252 return cls( # type: ignore
1253 self, self.response_class, use_cookies=use_cookies, **kwargs
1254 )
1256 def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner":
1257 """Create a CLI runner for testing CLI commands.
1258 See :ref:`testing-cli`.
1260 Returns an instance of :attr:`test_cli_runner_class`, by default
1261 :class:`~flask.testing.FlaskCliRunner`. The Flask app object is
1262 passed as the first argument.
1264 .. versionadded:: 1.0
1265 """
1266 cls = self.test_cli_runner_class
1268 if cls is None:
1269 from .testing import FlaskCliRunner as cls
1271 return cls(self, **kwargs) # type: ignore
1273 @setupmethod
1274 def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
1275 """Register a :class:`~flask.Blueprint` on the application. Keyword
1276 arguments passed to this method will override the defaults set on the
1277 blueprint.
1279 Calls the blueprint's :meth:`~flask.Blueprint.register` method after
1280 recording the blueprint in the application's :attr:`blueprints`.
1282 :param blueprint: The blueprint to register.
1283 :param url_prefix: Blueprint routes will be prefixed with this.
1284 :param subdomain: Blueprint routes will match on this subdomain.
1285 :param url_defaults: Blueprint routes will use these default values for
1286 view arguments.
1287 :param options: Additional keyword arguments are passed to
1288 :class:`~flask.blueprints.BlueprintSetupState`. They can be
1289 accessed in :meth:`~flask.Blueprint.record` callbacks.
1291 .. versionchanged:: 2.0.1
1292 The ``name`` option can be used to change the (pre-dotted)
1293 name the blueprint is registered with. This allows the same
1294 blueprint to be registered multiple times with unique names
1295 for ``url_for``.
1297 .. versionadded:: 0.7
1298 """
1299 blueprint.register(self, options)
1301 def iter_blueprints(self) -> t.ValuesView["Blueprint"]:
1302 """Iterates over all blueprints by the order they were registered.
1304 .. versionadded:: 0.11
1305 """
1306 return self.blueprints.values()
1308 @setupmethod
1309 def add_url_rule(
1310 self,
1311 rule: str,
1312 endpoint: t.Optional[str] = None,
1313 view_func: t.Optional[ft.RouteCallable] = None,
1314 provide_automatic_options: t.Optional[bool] = None,
1315 **options: t.Any,
1316 ) -> None:
1317 if endpoint is None:
1318 endpoint = _endpoint_from_view_func(view_func) # type: ignore
1319 options["endpoint"] = endpoint
1320 methods = options.pop("methods", None)
1322 # if the methods are not given and the view_func object knows its
1323 # methods we can use that instead. If neither exists, we go with
1324 # a tuple of only ``GET`` as default.
1325 if methods is None:
1326 methods = getattr(view_func, "methods", None) or ("GET",)
1327 if isinstance(methods, str):
1328 raise TypeError(
1329 "Allowed methods must be a list of strings, for"
1330 ' example: @app.route(..., methods=["POST"])'
1331 )
1332 methods = {item.upper() for item in methods}
1334 # Methods that should always be added
1335 required_methods = set(getattr(view_func, "required_methods", ()))
1337 # starting with Flask 0.8 the view_func object can disable and
1338 # force-enable the automatic options handling.
1339 if provide_automatic_options is None:
1340 provide_automatic_options = getattr(
1341 view_func, "provide_automatic_options", None
1342 )
1344 if provide_automatic_options is None:
1345 if "OPTIONS" not in methods:
1346 provide_automatic_options = True
1347 required_methods.add("OPTIONS")
1348 else:
1349 provide_automatic_options = False
1351 # Add the required methods now.
1352 methods |= required_methods
1354 rule = self.url_rule_class(rule, methods=methods, **options)
1355 rule.provide_automatic_options = provide_automatic_options # type: ignore
1357 self.url_map.add(rule)
1358 if view_func is not None:
1359 old_func = self.view_functions.get(endpoint)
1360 if old_func is not None and old_func != view_func:
1361 raise AssertionError(
1362 "View function mapping is overwriting an existing"
1363 f" endpoint function: {endpoint}"
1364 )
1365 self.view_functions[endpoint] = view_func
1367 @setupmethod
1368 def template_filter(
1369 self, name: t.Optional[str] = None
1370 ) -> t.Callable[[T_template_filter], T_template_filter]:
1371 """A decorator that is used to register custom template filter.
1372 You can specify a name for the filter, otherwise the function
1373 name will be used. Example::
1375 @app.template_filter()
1376 def reverse(s):
1377 return s[::-1]
1379 :param name: the optional name of the filter, otherwise the
1380 function name will be used.
1381 """
1383 def decorator(f: T_template_filter) -> T_template_filter:
1384 self.add_template_filter(f, name=name)
1385 return f
1387 return decorator
1389 @setupmethod
1390 def add_template_filter(
1391 self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
1392 ) -> None:
1393 """Register a custom template filter. Works exactly like the
1394 :meth:`template_filter` decorator.
1396 :param name: the optional name of the filter, otherwise the
1397 function name will be used.
1398 """
1399 self.jinja_env.filters[name or f.__name__] = f
1401 @setupmethod
1402 def template_test(
1403 self, name: t.Optional[str] = None
1404 ) -> t.Callable[[T_template_test], T_template_test]:
1405 """A decorator that is used to register custom template test.
1406 You can specify a name for the test, otherwise the function
1407 name will be used. Example::
1409 @app.template_test()
1410 def is_prime(n):
1411 if n == 2:
1412 return True
1413 for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
1414 if n % i == 0:
1415 return False
1416 return True
1418 .. versionadded:: 0.10
1420 :param name: the optional name of the test, otherwise the
1421 function name will be used.
1422 """
1424 def decorator(f: T_template_test) -> T_template_test:
1425 self.add_template_test(f, name=name)
1426 return f
1428 return decorator
1430 @setupmethod
1431 def add_template_test(
1432 self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
1433 ) -> None:
1434 """Register a custom template test. Works exactly like the
1435 :meth:`template_test` decorator.
1437 .. versionadded:: 0.10
1439 :param name: the optional name of the test, otherwise the
1440 function name will be used.
1441 """
1442 self.jinja_env.tests[name or f.__name__] = f
1444 @setupmethod
1445 def template_global(
1446 self, name: t.Optional[str] = None
1447 ) -> t.Callable[[T_template_global], T_template_global]:
1448 """A decorator that is used to register a custom template global function.
1449 You can specify a name for the global function, otherwise the function
1450 name will be used. Example::
1452 @app.template_global()
1453 def double(n):
1454 return 2 * n
1456 .. versionadded:: 0.10
1458 :param name: the optional name of the global function, otherwise the
1459 function name will be used.
1460 """
1462 def decorator(f: T_template_global) -> T_template_global:
1463 self.add_template_global(f, name=name)
1464 return f
1466 return decorator
1468 @setupmethod
1469 def add_template_global(
1470 self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
1471 ) -> None:
1472 """Register a custom template global function. Works exactly like the
1473 :meth:`template_global` decorator.
1475 .. versionadded:: 0.10
1477 :param name: the optional name of the global function, otherwise the
1478 function name will be used.
1479 """
1480 self.jinja_env.globals[name or f.__name__] = f
1482 @setupmethod
1483 def before_first_request(self, f: T_before_first_request) -> T_before_first_request:
1484 """Registers a function to be run before the first request to this
1485 instance of the application.
1487 The function will be called without any arguments and its return
1488 value is ignored.
1490 .. deprecated:: 2.2
1491 Will be removed in Flask 2.3. Run setup code when creating
1492 the application instead.
1494 .. versionadded:: 0.8
1495 """
1496 import warnings
1498 warnings.warn(
1499 "'before_first_request' is deprecated and will be removed"
1500 " in Flask 2.3. Run setup code while creating the"
1501 " application instead.",
1502 DeprecationWarning,
1503 stacklevel=2,
1504 )
1505 self.before_first_request_funcs.append(f)
1506 return f
1508 @setupmethod
1509 def teardown_appcontext(self, f: T_teardown) -> T_teardown:
1510 """Registers a function to be called when the application
1511 context is popped. The application context is typically popped
1512 after the request context for each request, at the end of CLI
1513 commands, or after a manually pushed context ends.
1515 .. code-block:: python
1517 with app.app_context():
1518 ...
1520 When the ``with`` block exits (or ``ctx.pop()`` is called), the
1521 teardown functions are called just before the app context is
1522 made inactive. Since a request context typically also manages an
1523 application context it would also be called when you pop a
1524 request context.
1526 When a teardown function was called because of an unhandled
1527 exception it will be passed an error object. If an
1528 :meth:`errorhandler` is registered, it will handle the exception
1529 and the teardown will not receive it.
1531 Teardown functions must avoid raising exceptions. If they
1532 execute code that might fail they must surround that code with a
1533 ``try``/``except`` block and log any errors.
1535 The return values of teardown functions are ignored.
1537 .. versionadded:: 0.9
1538 """
1539 self.teardown_appcontext_funcs.append(f)
1540 return f
1542 @setupmethod
1543 def shell_context_processor(
1544 self, f: T_shell_context_processor
1545 ) -> T_shell_context_processor:
1546 """Registers a shell context processor function.
1548 .. versionadded:: 0.11
1549 """
1550 self.shell_context_processors.append(f)
1551 return f
1553 def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]:
1554 """Return a registered error handler for an exception in this order:
1555 blueprint handler for a specific code, app handler for a specific code,
1556 blueprint handler for an exception class, app handler for an exception
1557 class, or ``None`` if a suitable handler is not found.
1558 """
1559 exc_class, code = self._get_exc_class_and_code(type(e))
1560 names = (*request.blueprints, None)
1562 for c in (code, None) if code is not None else (None,):
1563 for name in names:
1564 handler_map = self.error_handler_spec[name][c]
1566 if not handler_map:
1567 continue
1569 for cls in exc_class.__mro__:
1570 handler = handler_map.get(cls)
1572 if handler is not None:
1573 return handler
1574 return None
1576 def handle_http_exception(
1577 self, e: HTTPException
1578 ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
1579 """Handles an HTTP exception. By default this will invoke the
1580 registered error handlers and fall back to returning the
1581 exception as response.
1583 .. versionchanged:: 1.0.3
1584 ``RoutingException``, used internally for actions such as
1585 slash redirects during routing, is not passed to error
1586 handlers.
1588 .. versionchanged:: 1.0
1589 Exceptions are looked up by code *and* by MRO, so
1590 ``HTTPException`` subclasses can be handled with a catch-all
1591 handler for the base ``HTTPException``.
1593 .. versionadded:: 0.3
1594 """
1595 # Proxy exceptions don't have error codes. We want to always return
1596 # those unchanged as errors
1597 if e.code is None:
1598 return e
1600 # RoutingExceptions are used internally to trigger routing
1601 # actions, such as slash redirects raising RequestRedirect. They
1602 # are not raised or handled in user code.
1603 if isinstance(e, RoutingException):
1604 return e
1606 handler = self._find_error_handler(e)
1607 if handler is None:
1608 return e
1609 return self.ensure_sync(handler)(e)
1611 def trap_http_exception(self, e: Exception) -> bool:
1612 """Checks if an HTTP exception should be trapped or not. By default
1613 this will return ``False`` for all exceptions except for a bad request
1614 key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It
1615 also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``.
1617 This is called for all HTTP exceptions raised by a view function.
1618 If it returns ``True`` for any exception the error handler for this
1619 exception is not called and it shows up as regular exception in the
1620 traceback. This is helpful for debugging implicitly raised HTTP
1621 exceptions.
1623 .. versionchanged:: 1.0
1624 Bad request errors are not trapped by default in debug mode.
1626 .. versionadded:: 0.8
1627 """
1628 if self.config["TRAP_HTTP_EXCEPTIONS"]:
1629 return True
1631 trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"]
1633 # if unset, trap key errors in debug mode
1634 if (
1635 trap_bad_request is None
1636 and self.debug
1637 and isinstance(e, BadRequestKeyError)
1638 ):
1639 return True
1641 if trap_bad_request:
1642 return isinstance(e, BadRequest)
1644 return False
1646 def handle_user_exception(
1647 self, e: Exception
1648 ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
1649 """This method is called whenever an exception occurs that
1650 should be handled. A special case is :class:`~werkzeug
1651 .exceptions.HTTPException` which is forwarded to the
1652 :meth:`handle_http_exception` method. This function will either
1653 return a response value or reraise the exception with the same
1654 traceback.
1656 .. versionchanged:: 1.0
1657 Key errors raised from request data like ``form`` show the
1658 bad key in debug mode rather than a generic bad request
1659 message.
1661 .. versionadded:: 0.7
1662 """
1663 if isinstance(e, BadRequestKeyError) and (
1664 self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
1665 ):
1666 e.show_exception = True
1668 if isinstance(e, HTTPException) and not self.trap_http_exception(e):
1669 return self.handle_http_exception(e)
1671 handler = self._find_error_handler(e)
1673 if handler is None:
1674 raise
1676 return self.ensure_sync(handler)(e)
1678 def handle_exception(self, e: Exception) -> Response:
1679 """Handle an exception that did not have an error handler
1680 associated with it, or that was raised from an error handler.
1681 This always causes a 500 ``InternalServerError``.
1683 Always sends the :data:`got_request_exception` signal.
1685 If :attr:`propagate_exceptions` is ``True``, such as in debug
1686 mode, the error will be re-raised so that the debugger can
1687 display it. Otherwise, the original exception is logged, and
1688 an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
1690 If an error handler is registered for ``InternalServerError`` or
1691 ``500``, it will be used. For consistency, the handler will
1692 always receive the ``InternalServerError``. The original
1693 unhandled exception is available as ``e.original_exception``.
1695 .. versionchanged:: 1.1.0
1696 Always passes the ``InternalServerError`` instance to the
1697 handler, setting ``original_exception`` to the unhandled
1698 error.
1700 .. versionchanged:: 1.1.0
1701 ``after_request`` functions and other finalization is done
1702 even for the default 500 response when there is no handler.
1704 .. versionadded:: 0.3
1705 """
1706 exc_info = sys.exc_info()
1707 got_request_exception.send(self, exception=e)
1708 propagate = self.config["PROPAGATE_EXCEPTIONS"]
1710 if propagate is None:
1711 propagate = self.testing or self.debug
1713 if propagate:
1714 # Re-raise if called with an active exception, otherwise
1715 # raise the passed in exception.
1716 if exc_info[1] is e:
1717 raise
1719 raise e
1721 self.log_exception(exc_info)
1722 server_error: t.Union[InternalServerError, ft.ResponseReturnValue]
1723 server_error = InternalServerError(original_exception=e)
1724 handler = self._find_error_handler(server_error)
1726 if handler is not None:
1727 server_error = self.ensure_sync(handler)(server_error)
1729 return self.finalize_request(server_error, from_error_handler=True)
1731 def log_exception(
1732 self,
1733 exc_info: t.Union[
1734 t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None]
1735 ],
1736 ) -> None:
1737 """Logs an exception. This is called by :meth:`handle_exception`
1738 if debugging is disabled and right before the handler is called.
1739 The default implementation logs the exception as error on the
1740 :attr:`logger`.
1742 .. versionadded:: 0.8
1743 """
1744 self.logger.error(
1745 f"Exception on {request.path} [{request.method}]", exc_info=exc_info
1746 )
1748 def raise_routing_exception(self, request: Request) -> "te.NoReturn":
1749 """Intercept routing exceptions and possibly do something else.
1751 In debug mode, intercept a routing redirect and replace it with
1752 an error if the body will be discarded.
1754 With modern Werkzeug this shouldn't occur, since it now uses a
1755 308 status which tells the browser to resend the method and
1756 body.
1758 .. versionchanged:: 2.1
1759 Don't intercept 307 and 308 redirects.
1761 :meta private:
1762 :internal:
1763 """
1764 if (
1765 not self.debug
1766 or not isinstance(request.routing_exception, RequestRedirect)
1767 or request.routing_exception.code in {307, 308}
1768 or request.method in {"GET", "HEAD", "OPTIONS"}
1769 ):
1770 raise request.routing_exception # type: ignore
1772 from .debughelpers import FormDataRoutingRedirect
1774 raise FormDataRoutingRedirect(request)
1776 def dispatch_request(self) -> ft.ResponseReturnValue:
1777 """Does the request dispatching. Matches the URL and returns the
1778 return value of the view or error handler. This does not have to
1779 be a response object. In order to convert the return value to a
1780 proper response object, call :func:`make_response`.
1782 .. versionchanged:: 0.7
1783 This no longer does the exception handling, this code was
1784 moved to the new :meth:`full_dispatch_request`.
1785 """
1786 req = request_ctx.request
1787 if req.routing_exception is not None:
1788 self.raise_routing_exception(req)
1789 rule: Rule = req.url_rule # type: ignore[assignment]
1790 # if we provide automatic options for this URL and the
1791 # request came with the OPTIONS method, reply automatically
1792 if (
1793 getattr(rule, "provide_automatic_options", False)
1794 and req.method == "OPTIONS"
1795 ):
1796 return self.make_default_options_response()
1797 # otherwise dispatch to the handler for that endpoint
1798 view_args: t.Dict[str, t.Any] = req.view_args # type: ignore[assignment]
1799 return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
1801 def full_dispatch_request(self) -> Response:
1802 """Dispatches the request and on top of that performs request
1803 pre and postprocessing as well as HTTP exception catching and
1804 error handling.
1806 .. versionadded:: 0.7
1807 """
1808 # Run before_first_request functions if this is the thread's first request.
1809 # Inlined to avoid a method call on subsequent requests.
1810 # This is deprecated, will be removed in Flask 2.3.
1811 if not self._got_first_request:
1812 with self._before_request_lock:
1813 if not self._got_first_request:
1814 for func in self.before_first_request_funcs:
1815 self.ensure_sync(func)()
1817 self._got_first_request = True
1819 try:
1820 request_started.send(self)
1821 rv = self.preprocess_request()
1822 if rv is None:
1823 rv = self.dispatch_request()
1824 except Exception as e:
1825 rv = self.handle_user_exception(e)
1826 return self.finalize_request(rv)
1828 def finalize_request(
1829 self,
1830 rv: t.Union[ft.ResponseReturnValue, HTTPException],
1831 from_error_handler: bool = False,
1832 ) -> Response:
1833 """Given the return value from a view function this finalizes
1834 the request by converting it into a response and invoking the
1835 postprocessing functions. This is invoked for both normal
1836 request dispatching as well as error handlers.
1838 Because this means that it might be called as a result of a
1839 failure a special safe mode is available which can be enabled
1840 with the `from_error_handler` flag. If enabled, failures in
1841 response processing will be logged and otherwise ignored.
1843 :internal:
1844 """
1845 response = self.make_response(rv)
1846 try:
1847 response = self.process_response(response)
1848 request_finished.send(self, response=response)
1849 except Exception:
1850 if not from_error_handler:
1851 raise
1852 self.logger.exception(
1853 "Request finalizing failed with an error while handling an error"
1854 )
1855 return response
1857 def make_default_options_response(self) -> Response:
1858 """This method is called to create the default ``OPTIONS`` response.
1859 This can be changed through subclassing to change the default
1860 behavior of ``OPTIONS`` responses.
1862 .. versionadded:: 0.7
1863 """
1864 adapter = request_ctx.url_adapter
1865 methods = adapter.allowed_methods() # type: ignore[union-attr]
1866 rv = self.response_class()
1867 rv.allow.update(methods)
1868 return rv
1870 def should_ignore_error(self, error: t.Optional[BaseException]) -> bool:
1871 """This is called to figure out if an error should be ignored
1872 or not as far as the teardown system is concerned. If this
1873 function returns ``True`` then the teardown handlers will not be
1874 passed the error.
1876 .. versionadded:: 0.10
1877 """
1878 return False
1880 def ensure_sync(self, func: t.Callable) -> t.Callable:
1881 """Ensure that the function is synchronous for WSGI workers.
1882 Plain ``def`` functions are returned as-is. ``async def``
1883 functions are wrapped to run and wait for the response.
1885 Override this method to change how the app runs async views.
1887 .. versionadded:: 2.0
1888 """
1889 if iscoroutinefunction(func):
1890 return self.async_to_sync(func)
1892 return func
1894 def async_to_sync(
1895 self, func: t.Callable[..., t.Coroutine]
1896 ) -> t.Callable[..., t.Any]:
1897 """Return a sync function that will run the coroutine function.
1899 .. code-block:: python
1901 result = app.async_to_sync(func)(*args, **kwargs)
1903 Override this method to change how the app converts async code
1904 to be synchronously callable.
1906 .. versionadded:: 2.0
1907 """
1908 try:
1909 from asgiref.sync import async_to_sync as asgiref_async_to_sync
1910 except ImportError:
1911 raise RuntimeError(
1912 "Install Flask with the 'async' extra in order to use async views."
1913 ) from None
1915 return asgiref_async_to_sync(func)
1917 def url_for(
1918 self,
1919 endpoint: str,
1920 *,
1921 _anchor: t.Optional[str] = None,
1922 _method: t.Optional[str] = None,
1923 _scheme: t.Optional[str] = None,
1924 _external: t.Optional[bool] = None,
1925 **values: t.Any,
1926 ) -> str:
1927 """Generate a URL to the given endpoint with the given values.
1929 This is called by :func:`flask.url_for`, and can be called
1930 directly as well.
1932 An *endpoint* is the name of a URL rule, usually added with
1933 :meth:`@app.route() <route>`, and usually the same name as the
1934 view function. A route defined in a :class:`~flask.Blueprint`
1935 will prepend the blueprint's name separated by a ``.`` to the
1936 endpoint.
1938 In some cases, such as email messages, you want URLs to include
1939 the scheme and domain, like ``https://example.com/hello``. When
1940 not in an active request, URLs will be external by default, but
1941 this requires setting :data:`SERVER_NAME` so Flask knows what
1942 domain to use. :data:`APPLICATION_ROOT` and
1943 :data:`PREFERRED_URL_SCHEME` should also be configured as
1944 needed. This config is only used when not in an active request.
1946 Functions can be decorated with :meth:`url_defaults` to modify
1947 keyword arguments before the URL is built.
1949 If building fails for some reason, such as an unknown endpoint
1950 or incorrect values, the app's :meth:`handle_url_build_error`
1951 method is called. If that returns a string, that is returned,
1952 otherwise a :exc:`~werkzeug.routing.BuildError` is raised.
1954 :param endpoint: The endpoint name associated with the URL to
1955 generate. If this starts with a ``.``, the current blueprint
1956 name (if any) will be used.
1957 :param _anchor: If given, append this as ``#anchor`` to the URL.
1958 :param _method: If given, generate the URL associated with this
1959 method for the endpoint.
1960 :param _scheme: If given, the URL will have this scheme if it
1961 is external.
1962 :param _external: If given, prefer the URL to be internal
1963 (False) or require it to be external (True). External URLs
1964 include the scheme and domain. When not in an active
1965 request, URLs are external by default.
1966 :param values: Values to use for the variable parts of the URL
1967 rule. Unknown keys are appended as query string arguments,
1968 like ``?a=b&c=d``.
1970 .. versionadded:: 2.2
1971 Moved from ``flask.url_for``, which calls this method.
1972 """
1973 req_ctx = _cv_request.get(None)
1975 if req_ctx is not None:
1976 url_adapter = req_ctx.url_adapter
1977 blueprint_name = req_ctx.request.blueprint
1979 # If the endpoint starts with "." and the request matches a
1980 # blueprint, the endpoint is relative to the blueprint.
1981 if endpoint[:1] == ".":
1982 if blueprint_name is not None:
1983 endpoint = f"{blueprint_name}{endpoint}"
1984 else:
1985 endpoint = endpoint[1:]
1987 # When in a request, generate a URL without scheme and
1988 # domain by default, unless a scheme is given.
1989 if _external is None:
1990 _external = _scheme is not None
1991 else:
1992 app_ctx = _cv_app.get(None)
1994 # If called by helpers.url_for, an app context is active,
1995 # use its url_adapter. Otherwise, app.url_for was called
1996 # directly, build an adapter.
1997 if app_ctx is not None:
1998 url_adapter = app_ctx.url_adapter
1999 else:
2000 url_adapter = self.create_url_adapter(None)
2002 if url_adapter is None:
2003 raise RuntimeError(
2004 "Unable to build URLs outside an active request"
2005 " without 'SERVER_NAME' configured. Also configure"
2006 " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
2007 " needed."
2008 )
2010 # When outside a request, generate a URL with scheme and
2011 # domain by default.
2012 if _external is None:
2013 _external = True
2015 # It is an error to set _scheme when _external=False, in order
2016 # to avoid accidental insecure URLs.
2017 if _scheme is not None and not _external:
2018 raise ValueError("When specifying '_scheme', '_external' must be True.")
2020 self.inject_url_defaults(endpoint, values)
2022 try:
2023 rv = url_adapter.build( # type: ignore[union-attr]
2024 endpoint,
2025 values,
2026 method=_method,
2027 url_scheme=_scheme,
2028 force_external=_external,
2029 )
2030 except BuildError as error:
2031 values.update(
2032 _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
2033 )
2034 return self.handle_url_build_error(error, endpoint, values)
2036 if _anchor is not None:
2037 _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@")
2038 rv = f"{rv}#{_anchor}"
2040 return rv
2042 def redirect(self, location: str, code: int = 302) -> BaseResponse:
2043 """Create a redirect response object.
2045 This is called by :func:`flask.redirect`, and can be called
2046 directly as well.
2048 :param location: The URL to redirect to.
2049 :param code: The status code for the redirect.
2051 .. versionadded:: 2.2
2052 Moved from ``flask.redirect``, which calls this method.
2053 """
2054 return _wz_redirect(location, code=code, Response=self.response_class)
2056 def make_response(self, rv: ft.ResponseReturnValue) -> Response:
2057 """Convert the return value from a view function to an instance of
2058 :attr:`response_class`.
2060 :param rv: the return value from the view function. The view function
2061 must return a response. Returning ``None``, or the view ending
2062 without returning, is not allowed. The following types are allowed
2063 for ``view_rv``:
2065 ``str``
2066 A response object is created with the string encoded to UTF-8
2067 as the body.
2069 ``bytes``
2070 A response object is created with the bytes as the body.
2072 ``dict``
2073 A dictionary that will be jsonify'd before being returned.
2075 ``list``
2076 A list that will be jsonify'd before being returned.
2078 ``generator`` or ``iterator``
2079 A generator that returns ``str`` or ``bytes`` to be
2080 streamed as the response.
2082 ``tuple``
2083 Either ``(body, status, headers)``, ``(body, status)``, or
2084 ``(body, headers)``, where ``body`` is any of the other types
2085 allowed here, ``status`` is a string or an integer, and
2086 ``headers`` is a dictionary or a list of ``(key, value)``
2087 tuples. If ``body`` is a :attr:`response_class` instance,
2088 ``status`` overwrites the exiting value and ``headers`` are
2089 extended.
2091 :attr:`response_class`
2092 The object is returned unchanged.
2094 other :class:`~werkzeug.wrappers.Response` class
2095 The object is coerced to :attr:`response_class`.
2097 :func:`callable`
2098 The function is called as a WSGI application. The result is
2099 used to create a response object.
2101 .. versionchanged:: 2.2
2102 A generator will be converted to a streaming response.
2103 A list will be converted to a JSON response.
2105 .. versionchanged:: 1.1
2106 A dict will be converted to a JSON response.
2108 .. versionchanged:: 0.9
2109 Previously a tuple was interpreted as the arguments for the
2110 response object.
2111 """
2113 status = headers = None
2115 # unpack tuple returns
2116 if isinstance(rv, tuple):
2117 len_rv = len(rv)
2119 # a 3-tuple is unpacked directly
2120 if len_rv == 3:
2121 rv, status, headers = rv # type: ignore[misc]
2122 # decide if a 2-tuple has status or headers
2123 elif len_rv == 2:
2124 if isinstance(rv[1], (Headers, dict, tuple, list)):
2125 rv, headers = rv
2126 else:
2127 rv, status = rv # type: ignore[assignment,misc]
2128 # other sized tuples are not allowed
2129 else:
2130 raise TypeError(
2131 "The view function did not return a valid response tuple."
2132 " The tuple must have the form (body, status, headers),"
2133 " (body, status), or (body, headers)."
2134 )
2136 # the body must not be None
2137 if rv is None:
2138 raise TypeError(
2139 f"The view function for {request.endpoint!r} did not"
2140 " return a valid response. The function either returned"
2141 " None or ended without a return statement."
2142 )
2144 # make sure the body is an instance of the response class
2145 if not isinstance(rv, self.response_class):
2146 if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, _abc_Iterator):
2147 # let the response class set the status and headers instead of
2148 # waiting to do it manually, so that the class can handle any
2149 # special logic
2150 rv = self.response_class(
2151 rv,
2152 status=status,
2153 headers=headers, # type: ignore[arg-type]
2154 )
2155 status = headers = None
2156 elif isinstance(rv, (dict, list)):
2157 rv = self.json.response(rv)
2158 elif isinstance(rv, BaseResponse) or callable(rv):
2159 # evaluate a WSGI callable, or coerce a different response
2160 # class to the correct type
2161 try:
2162 rv = self.response_class.force_type(
2163 rv, request.environ # type: ignore[arg-type]
2164 )
2165 except TypeError as e:
2166 raise TypeError(
2167 f"{e}\nThe view function did not return a valid"
2168 " response. The return type must be a string,"
2169 " dict, list, tuple with headers or status,"
2170 " Response instance, or WSGI callable, but it"
2171 f" was a {type(rv).__name__}."
2172 ).with_traceback(sys.exc_info()[2]) from None
2173 else:
2174 raise TypeError(
2175 "The view function did not return a valid"
2176 " response. The return type must be a string,"
2177 " dict, list, tuple with headers or status,"
2178 " Response instance, or WSGI callable, but it was a"
2179 f" {type(rv).__name__}."
2180 )
2182 rv = t.cast(Response, rv)
2183 # prefer the status if it was provided
2184 if status is not None:
2185 if isinstance(status, (str, bytes, bytearray)):
2186 rv.status = status
2187 else:
2188 rv.status_code = status
2190 # extend existing headers with provided headers
2191 if headers:
2192 rv.headers.update(headers) # type: ignore[arg-type]
2194 return rv
2196 def create_url_adapter(
2197 self, request: t.Optional[Request]
2198 ) -> t.Optional[MapAdapter]:
2199 """Creates a URL adapter for the given request. The URL adapter
2200 is created at a point where the request context is not yet set
2201 up so the request is passed explicitly.
2203 .. versionadded:: 0.6
2205 .. versionchanged:: 0.9
2206 This can now also be called without a request object when the
2207 URL adapter is created for the application context.
2209 .. versionchanged:: 1.0
2210 :data:`SERVER_NAME` no longer implicitly enables subdomain
2211 matching. Use :attr:`subdomain_matching` instead.
2212 """
2213 if request is not None:
2214 # If subdomain matching is disabled (the default), use the
2215 # default subdomain in all cases. This should be the default
2216 # in Werkzeug but it currently does not have that feature.
2217 if not self.subdomain_matching:
2218 subdomain = self.url_map.default_subdomain or None
2219 else:
2220 subdomain = None
2222 return self.url_map.bind_to_environ(
2223 request.environ,
2224 server_name=self.config["SERVER_NAME"],
2225 subdomain=subdomain,
2226 )
2227 # We need at the very least the server name to be set for this
2228 # to work.
2229 if self.config["SERVER_NAME"] is not None:
2230 return self.url_map.bind(
2231 self.config["SERVER_NAME"],
2232 script_name=self.config["APPLICATION_ROOT"],
2233 url_scheme=self.config["PREFERRED_URL_SCHEME"],
2234 )
2236 return None
2238 def inject_url_defaults(self, endpoint: str, values: dict) -> None:
2239 """Injects the URL defaults for the given endpoint directly into
2240 the values dictionary passed. This is used internally and
2241 automatically called on URL building.
2243 .. versionadded:: 0.7
2244 """
2245 names: t.Iterable[t.Optional[str]] = (None,)
2247 # url_for may be called outside a request context, parse the
2248 # passed endpoint instead of using request.blueprints.
2249 if "." in endpoint:
2250 names = chain(
2251 names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0]))
2252 )
2254 for name in names:
2255 if name in self.url_default_functions:
2256 for func in self.url_default_functions[name]:
2257 func(endpoint, values)
2259 def handle_url_build_error(
2260 self, error: BuildError, endpoint: str, values: t.Dict[str, t.Any]
2261 ) -> str:
2262 """Called by :meth:`.url_for` if a
2263 :exc:`~werkzeug.routing.BuildError` was raised. If this returns
2264 a value, it will be returned by ``url_for``, otherwise the error
2265 will be re-raised.
2267 Each function in :attr:`url_build_error_handlers` is called with
2268 ``error``, ``endpoint`` and ``values``. If a function returns
2269 ``None`` or raises a ``BuildError``, it is skipped. Otherwise,
2270 its return value is returned by ``url_for``.
2272 :param error: The active ``BuildError`` being handled.
2273 :param endpoint: The endpoint being built.
2274 :param values: The keyword arguments passed to ``url_for``.
2275 """
2276 for handler in self.url_build_error_handlers:
2277 try:
2278 rv = handler(error, endpoint, values)
2279 except BuildError as e:
2280 # make error available outside except block
2281 error = e
2282 else:
2283 if rv is not None:
2284 return rv
2286 # Re-raise if called with an active exception, otherwise raise
2287 # the passed in exception.
2288 if error is sys.exc_info()[1]:
2289 raise
2291 raise error
2293 def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]:
2294 """Called before the request is dispatched. Calls
2295 :attr:`url_value_preprocessors` registered with the app and the
2296 current blueprint (if any). Then calls :attr:`before_request_funcs`
2297 registered with the app and the blueprint.
2299 If any :meth:`before_request` handler returns a non-None value, the
2300 value is handled as if it was the return value from the view, and
2301 further request handling is stopped.
2302 """
2303 names = (None, *reversed(request.blueprints))
2305 for name in names:
2306 if name in self.url_value_preprocessors:
2307 for url_func in self.url_value_preprocessors[name]:
2308 url_func(request.endpoint, request.view_args)
2310 for name in names:
2311 if name in self.before_request_funcs:
2312 for before_func in self.before_request_funcs[name]:
2313 rv = self.ensure_sync(before_func)()
2315 if rv is not None:
2316 return rv
2318 return None
2320 def process_response(self, response: Response) -> Response:
2321 """Can be overridden in order to modify the response object
2322 before it's sent to the WSGI server. By default this will
2323 call all the :meth:`after_request` decorated functions.
2325 .. versionchanged:: 0.5
2326 As of Flask 0.5 the functions registered for after request
2327 execution are called in reverse order of registration.
2329 :param response: a :attr:`response_class` object.
2330 :return: a new response object or the same, has to be an
2331 instance of :attr:`response_class`.
2332 """
2333 ctx = request_ctx._get_current_object() # type: ignore[attr-defined]
2335 for func in ctx._after_request_functions:
2336 response = self.ensure_sync(func)(response)
2338 for name in chain(request.blueprints, (None,)):
2339 if name in self.after_request_funcs:
2340 for func in reversed(self.after_request_funcs[name]):
2341 response = self.ensure_sync(func)(response)
2343 if not self.session_interface.is_null_session(ctx.session):
2344 self.session_interface.save_session(self, ctx.session, response)
2346 return response
2348 def do_teardown_request(
2349 self, exc: t.Optional[BaseException] = _sentinel # type: ignore
2350 ) -> None:
2351 """Called after the request is dispatched and the response is
2352 returned, right before the request context is popped.
2354 This calls all functions decorated with
2355 :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`
2356 if a blueprint handled the request. Finally, the
2357 :data:`request_tearing_down` signal is sent.
2359 This is called by
2360 :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,
2361 which may be delayed during testing to maintain access to
2362 resources.
2364 :param exc: An unhandled exception raised while dispatching the
2365 request. Detected from the current exception information if
2366 not passed. Passed to each teardown function.
2368 .. versionchanged:: 0.9
2369 Added the ``exc`` argument.
2370 """
2371 if exc is _sentinel:
2372 exc = sys.exc_info()[1]
2374 for name in chain(request.blueprints, (None,)):
2375 if name in self.teardown_request_funcs:
2376 for func in reversed(self.teardown_request_funcs[name]):
2377 self.ensure_sync(func)(exc)
2379 request_tearing_down.send(self, exc=exc)
2381 def do_teardown_appcontext(
2382 self, exc: t.Optional[BaseException] = _sentinel # type: ignore
2383 ) -> None:
2384 """Called right before the application context is popped.
2386 When handling a request, the application context is popped
2387 after the request context. See :meth:`do_teardown_request`.
2389 This calls all functions decorated with
2390 :meth:`teardown_appcontext`. Then the
2391 :data:`appcontext_tearing_down` signal is sent.
2393 This is called by
2394 :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.
2396 .. versionadded:: 0.9
2397 """
2398 if exc is _sentinel:
2399 exc = sys.exc_info()[1]
2401 for func in reversed(self.teardown_appcontext_funcs):
2402 self.ensure_sync(func)(exc)
2404 appcontext_tearing_down.send(self, exc=exc)
2406 def app_context(self) -> AppContext:
2407 """Create an :class:`~flask.ctx.AppContext`. Use as a ``with``
2408 block to push the context, which will make :data:`current_app`
2409 point at this application.
2411 An application context is automatically pushed by
2412 :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`
2413 when handling a request, and when running a CLI command. Use
2414 this to manually create a context outside of these situations.
2416 ::
2418 with app.app_context():
2419 init_db()
2421 See :doc:`/appcontext`.
2423 .. versionadded:: 0.9
2424 """
2425 return AppContext(self)
2427 def request_context(self, environ: dict) -> RequestContext:
2428 """Create a :class:`~flask.ctx.RequestContext` representing a
2429 WSGI environment. Use a ``with`` block to push the context,
2430 which will make :data:`request` point at this request.
2432 See :doc:`/reqcontext`.
2434 Typically you should not call this from your own code. A request
2435 context is automatically pushed by the :meth:`wsgi_app` when
2436 handling a request. Use :meth:`test_request_context` to create
2437 an environment and context instead of this method.
2439 :param environ: a WSGI environment
2440 """
2441 return RequestContext(self, environ)
2443 def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext:
2444 """Create a :class:`~flask.ctx.RequestContext` for a WSGI
2445 environment created from the given values. This is mostly useful
2446 during testing, where you may want to run a function that uses
2447 request data without dispatching a full request.
2449 See :doc:`/reqcontext`.
2451 Use a ``with`` block to push the context, which will make
2452 :data:`request` point at the request for the created
2453 environment. ::
2455 with test_request_context(...):
2456 generate_report()
2458 When using the shell, it may be easier to push and pop the
2459 context manually to avoid indentation. ::
2461 ctx = app.test_request_context(...)
2462 ctx.push()
2463 ...
2464 ctx.pop()
2466 Takes the same arguments as Werkzeug's
2467 :class:`~werkzeug.test.EnvironBuilder`, with some defaults from
2468 the application. See the linked Werkzeug docs for most of the
2469 available arguments. Flask-specific behavior is listed here.
2471 :param path: URL path being requested.
2472 :param base_url: Base URL where the app is being served, which
2473 ``path`` is relative to. If not given, built from
2474 :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
2475 :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
2476 :param subdomain: Subdomain name to append to
2477 :data:`SERVER_NAME`.
2478 :param url_scheme: Scheme to use instead of
2479 :data:`PREFERRED_URL_SCHEME`.
2480 :param data: The request body, either as a string or a dict of
2481 form keys and values.
2482 :param json: If given, this is serialized as JSON and passed as
2483 ``data``. Also defaults ``content_type`` to
2484 ``application/json``.
2485 :param args: other positional arguments passed to
2486 :class:`~werkzeug.test.EnvironBuilder`.
2487 :param kwargs: other keyword arguments passed to
2488 :class:`~werkzeug.test.EnvironBuilder`.
2489 """
2490 from .testing import EnvironBuilder
2492 builder = EnvironBuilder(self, *args, **kwargs)
2494 try:
2495 return self.request_context(builder.get_environ())
2496 finally:
2497 builder.close()
2499 def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any:
2500 """The actual WSGI application. This is not implemented in
2501 :meth:`__call__` so that middlewares can be applied without
2502 losing a reference to the app object. Instead of doing this::
2504 app = MyMiddleware(app)
2506 It's a better idea to do this instead::
2508 app.wsgi_app = MyMiddleware(app.wsgi_app)
2510 Then you still have the original application object around and
2511 can continue to call methods on it.
2513 .. versionchanged:: 0.7
2514 Teardown events for the request and app contexts are called
2515 even if an unhandled error occurs. Other events may not be
2516 called depending on when an error occurs during dispatch.
2517 See :ref:`callbacks-and-errors`.
2519 :param environ: A WSGI environment.
2520 :param start_response: A callable accepting a status code,
2521 a list of headers, and an optional exception context to
2522 start the response.
2523 """
2524 ctx = self.request_context(environ)
2525 error: t.Optional[BaseException] = None
2526 try:
2527 try:
2528 ctx.push()
2529 response = self.full_dispatch_request()
2530 except Exception as e:
2531 error = e
2532 response = self.handle_exception(e)
2533 except: # noqa: B001
2534 error = sys.exc_info()[1]
2535 raise
2536 return response(environ, start_response)
2537 finally:
2538 if "werkzeug.debug.preserve_context" in environ:
2539 environ["werkzeug.debug.preserve_context"](_cv_app.get())
2540 environ["werkzeug.debug.preserve_context"](_cv_request.get())
2542 if error is not None and self.should_ignore_error(error):
2543 error = None
2545 ctx.pop(error)
2547 def __call__(self, environ: dict, start_response: t.Callable) -> t.Any:
2548 """The WSGI server calls the Flask application object as the
2549 WSGI application. This calls :meth:`wsgi_app`, which can be
2550 wrapped to apply middleware.
2551 """
2552 return self.wsgi_app(environ, start_response)