Spaces:
Runtime error
Runtime error
from __future__ import annotations | |
import typing as t | |
from werkzeug.exceptions import BadRequest | |
from werkzeug.exceptions import HTTPException | |
from werkzeug.wrappers import Request as RequestBase | |
from werkzeug.wrappers import Response as ResponseBase | |
from . import json | |
from .globals import current_app | |
from .helpers import _split_blueprint_path | |
if t.TYPE_CHECKING: # pragma: no cover | |
from werkzeug.routing import Rule | |
class Request(RequestBase): | |
"""The request object used by default in Flask. Remembers the | |
matched endpoint and view arguments. | |
It is what ends up as :class:`~flask.request`. If you want to replace | |
the request object used you can subclass this and set | |
:attr:`~flask.Flask.request_class` to your subclass. | |
The request object is a :class:`~werkzeug.wrappers.Request` subclass and | |
provides all of the attributes Werkzeug defines plus a few Flask | |
specific ones. | |
""" | |
json_module: t.Any = json | |
#: The internal URL rule that matched the request. This can be | |
#: useful to inspect which methods are allowed for the URL from | |
#: a before/after handler (``request.url_rule.methods``) etc. | |
#: Though if the request's method was invalid for the URL rule, | |
#: the valid list is available in ``routing_exception.valid_methods`` | |
#: instead (an attribute of the Werkzeug exception | |
#: :exc:`~werkzeug.exceptions.MethodNotAllowed`) | |
#: because the request was never internally bound. | |
#: | |
#: .. versionadded:: 0.6 | |
url_rule: Rule | None = None | |
#: A dict of view arguments that matched the request. If an exception | |
#: happened when matching, this will be ``None``. | |
view_args: dict[str, t.Any] | None = None | |
#: If matching the URL failed, this is the exception that will be | |
#: raised / was raised as part of the request handling. This is | |
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or | |
#: something similar. | |
routing_exception: HTTPException | None = None | |
def max_content_length(self) -> int | None: # type: ignore[override] | |
"""Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" | |
if current_app: | |
return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] | |
else: | |
return None | |
def endpoint(self) -> str | None: | |
"""The endpoint that matched the request URL. | |
This will be ``None`` if matching failed or has not been | |
performed yet. | |
This in combination with :attr:`view_args` can be used to | |
reconstruct the same URL or a modified URL. | |
""" | |
if self.url_rule is not None: | |
return self.url_rule.endpoint | |
return None | |
def blueprint(self) -> str | None: | |
"""The registered name of the current blueprint. | |
This will be ``None`` if the endpoint is not part of a | |
blueprint, or if URL matching failed or has not been performed | |
yet. | |
This does not necessarily match the name the blueprint was | |
created with. It may have been nested, or registered with a | |
different name. | |
""" | |
endpoint = self.endpoint | |
if endpoint is not None and "." in endpoint: | |
return endpoint.rpartition(".")[0] | |
return None | |
def blueprints(self) -> list[str]: | |
"""The registered names of the current blueprint upwards through | |
parent blueprints. | |
This will be an empty list if there is no current blueprint, or | |
if URL matching failed. | |
.. versionadded:: 2.0.1 | |
""" | |
name = self.blueprint | |
if name is None: | |
return [] | |
return _split_blueprint_path(name) | |
def _load_form_data(self) -> None: | |
super()._load_form_data() | |
# In debug mode we're replacing the files multidict with an ad-hoc | |
# subclass that raises a different error for key errors. | |
if ( | |
current_app | |
and current_app.debug | |
and self.mimetype != "multipart/form-data" | |
and not self.files | |
): | |
from .debughelpers import attach_enctype_error_multidict | |
attach_enctype_error_multidict(self) | |
def on_json_loading_failed(self, e: ValueError | None) -> t.Any: | |
try: | |
return super().on_json_loading_failed(e) | |
except BadRequest as e: | |
if current_app and current_app.debug: | |
raise | |
raise BadRequest() from e | |
class Response(ResponseBase): | |
"""The response object that is used by default in Flask. Works like the | |
response object from Werkzeug but is set to have an HTML mimetype by | |
default. Quite often you don't have to create this object yourself because | |
:meth:`~flask.Flask.make_response` will take care of that for you. | |
If you want to replace the response object used you can subclass this and | |
set :attr:`~flask.Flask.response_class` to your subclass. | |
.. versionchanged:: 1.0 | |
JSON support is added to the response, like the request. This is useful | |
when testing to get the test client response data as JSON. | |
.. versionchanged:: 1.0 | |
Added :attr:`max_cookie_size`. | |
""" | |
default_mimetype: str | None = "text/html" | |
json_module = json | |
autocorrect_location_header = False | |
def max_cookie_size(self) -> int: # type: ignore | |
"""Read-only view of the :data:`MAX_COOKIE_SIZE` config key. | |
See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in | |
Werkzeug's docs. | |
""" | |
if current_app: | |
return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return] | |
# return Werkzeug's default when not in an app context | |
return super().max_cookie_size | |