Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/flask/wrappers.py: 61%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import typing as t
5from werkzeug.exceptions import BadRequest
6from werkzeug.exceptions import HTTPException
7from werkzeug.wrappers import Request as RequestBase
8from werkzeug.wrappers import Response as ResponseBase
10from . import json
11from .globals import current_app
12from .helpers import _split_blueprint_path
14if t.TYPE_CHECKING: # pragma: no cover
15 from werkzeug.routing import Rule
18class Request(RequestBase):
19 """The request object used by default in Flask. Remembers the
20 matched endpoint and view arguments.
22 It is what ends up as :class:`~flask.request`. If you want to replace
23 the request object used you can subclass this and set
24 :attr:`~flask.Flask.request_class` to your subclass.
26 The request object is a :class:`~werkzeug.wrappers.Request` subclass and
27 provides all of the attributes Werkzeug defines plus a few Flask
28 specific ones.
29 """
31 json_module: t.Any = json
33 #: The internal URL rule that matched the request. This can be
34 #: useful to inspect which methods are allowed for the URL from
35 #: a before/after handler (``request.url_rule.methods``) etc.
36 #: Though if the request's method was invalid for the URL rule,
37 #: the valid list is available in ``routing_exception.valid_methods``
38 #: instead (an attribute of the Werkzeug exception
39 #: :exc:`~werkzeug.exceptions.MethodNotAllowed`)
40 #: because the request was never internally bound.
41 #:
42 #: .. versionadded:: 0.6
43 url_rule: Rule | None = None
45 #: A dict of view arguments that matched the request. If an exception
46 #: happened when matching, this will be ``None``.
47 view_args: dict[str, t.Any] | None = None
49 #: If matching the URL failed, this is the exception that will be
50 #: raised / was raised as part of the request handling. This is
51 #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
52 #: something similar.
53 routing_exception: HTTPException | None = None
55 _max_content_length: int | None = None
56 _max_form_memory_size: int | None = None
57 _max_form_parts: int | None = None
59 @property
60 def max_content_length(self) -> int | None:
61 """The maximum number of bytes that will be read during this request. If
62 this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge`
63 error is raised. If it is set to ``None``, no limit is enforced at the
64 Flask application level. However, if it is ``None`` and the request has
65 no ``Content-Length`` header and the WSGI server does not indicate that
66 it terminates the stream, then no data is read to avoid an infinite
67 stream.
69 Each request defaults to the :data:`MAX_CONTENT_LENGTH` config, which
70 defaults to ``None``. It can be set on a specific ``request`` to apply
71 the limit to that specific view. This should be set appropriately based
72 on an application's or view's specific needs.
74 .. versionchanged:: 3.1
75 This can be set per-request.
77 .. versionchanged:: 0.6
78 This is configurable through Flask config.
79 """
80 if self._max_content_length is not None:
81 return self._max_content_length
83 if not current_app:
84 return super().max_content_length
86 return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return]
88 @max_content_length.setter
89 def max_content_length(self, value: int | None) -> None:
90 self._max_content_length = value
92 @property
93 def max_form_memory_size(self) -> int | None:
94 """The maximum size in bytes any non-file form field may be in a
95 ``multipart/form-data`` body. If this limit is exceeded, a 413
96 :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it
97 is set to ``None``, no limit is enforced at the Flask application level.
99 Each request defaults to the :data:`MAX_FORM_MEMORY_SIZE` config, which
100 defaults to ``500_000``. It can be set on a specific ``request`` to
101 apply the limit to that specific view. This should be set appropriately
102 based on an application's or view's specific needs.
104 .. versionchanged:: 3.1
105 This is configurable through Flask config.
106 """
107 if self._max_form_memory_size is not None:
108 return self._max_form_memory_size
110 if not current_app:
111 return super().max_form_memory_size
113 return current_app.config["MAX_FORM_MEMORY_SIZE"] # type: ignore[no-any-return]
115 @max_form_memory_size.setter
116 def max_form_memory_size(self, value: int | None) -> None:
117 self._max_form_memory_size = value
119 @property # type: ignore[override]
120 def max_form_parts(self) -> int | None:
121 """The maximum number of fields that may be present in a
122 ``multipart/form-data`` body. If this limit is exceeded, a 413
123 :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it
124 is set to ``None``, no limit is enforced at the Flask application level.
126 Each request defaults to the :data:`MAX_FORM_PARTS` config, which
127 defaults to ``1_000``. It can be set on a specific ``request`` to apply
128 the limit to that specific view. This should be set appropriately based
129 on an application's or view's specific needs.
131 .. versionchanged:: 3.1
132 This is configurable through Flask config.
133 """
134 if self._max_form_parts is not None:
135 return self._max_form_parts
137 if not current_app:
138 return super().max_form_parts
140 return current_app.config["MAX_FORM_PARTS"] # type: ignore[no-any-return]
142 @max_form_parts.setter
143 def max_form_parts(self, value: int | None) -> None:
144 self._max_form_parts = value
146 @property
147 def endpoint(self) -> str | None:
148 """The endpoint that matched the request URL.
150 This will be ``None`` if matching failed or has not been
151 performed yet.
153 This in combination with :attr:`view_args` can be used to
154 reconstruct the same URL or a modified URL.
155 """
156 if self.url_rule is not None:
157 return self.url_rule.endpoint # type: ignore[no-any-return]
159 return None
161 @property
162 def blueprint(self) -> str | None:
163 """The registered name of the current blueprint.
165 This will be ``None`` if the endpoint is not part of a
166 blueprint, or if URL matching failed or has not been performed
167 yet.
169 This does not necessarily match the name the blueprint was
170 created with. It may have been nested, or registered with a
171 different name.
172 """
173 endpoint = self.endpoint
175 if endpoint is not None and "." in endpoint:
176 return endpoint.rpartition(".")[0]
178 return None
180 @property
181 def blueprints(self) -> list[str]:
182 """The registered names of the current blueprint upwards through
183 parent blueprints.
185 This will be an empty list if there is no current blueprint, or
186 if URL matching failed.
188 .. versionadded:: 2.0.1
189 """
190 name = self.blueprint
192 if name is None:
193 return []
195 return _split_blueprint_path(name)
197 def _load_form_data(self) -> None:
198 super()._load_form_data()
200 # In debug mode we're replacing the files multidict with an ad-hoc
201 # subclass that raises a different error for key errors.
202 if (
203 current_app
204 and current_app.debug
205 and self.mimetype != "multipart/form-data"
206 and not self.files
207 ):
208 from .debughelpers import attach_enctype_error_multidict
210 attach_enctype_error_multidict(self)
212 def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
213 try:
214 return super().on_json_loading_failed(e)
215 except BadRequest as ebr:
216 if current_app and current_app.debug:
217 raise
219 raise BadRequest() from ebr
222class Response(ResponseBase):
223 """The response object that is used by default in Flask. Works like the
224 response object from Werkzeug but is set to have an HTML mimetype by
225 default. Quite often you don't have to create this object yourself because
226 :meth:`~flask.Flask.make_response` will take care of that for you.
228 If you want to replace the response object used you can subclass this and
229 set :attr:`~flask.Flask.response_class` to your subclass.
231 .. versionchanged:: 1.0
232 JSON support is added to the response, like the request. This is useful
233 when testing to get the test client response data as JSON.
235 .. versionchanged:: 1.0
237 Added :attr:`max_cookie_size`.
238 """
240 default_mimetype: str | None = "text/html"
242 json_module = json
244 autocorrect_location_header = False
246 @property
247 def max_cookie_size(self) -> int: # type: ignore
248 """Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
250 See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in
251 Werkzeug's docs.
252 """
253 if current_app:
254 return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return]
256 # return Werkzeug's default when not in an app context
257 return super().max_cookie_size