Flask之Response
Response
的构建流程和
Resquest
流程类似
flask.Response -> werkzeug.Response -> sansio.Response
Response的构建
在
flask
的
full_dispatch_request
方法中拿到视图函数的返回结果
def full_dispatch_request(self) -> Response:
self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
rv = self.preprocess_request()
if rv is None:
# rv 是视图函数的返回结果
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)
调用
self.finalize_reuqest
方法构建
Response
响应对象
def finalize_request(
self,
rv: t.Union[ResponseReturnValue, HTTPException],
from_error_handler: bool = False,
) -> Response:
response = self.make_response(rv)
...
看一下
make_response
方法
def make_response(self, rv: ResponseReturnValue) -> Response:
status = headers = None
if isinstance(rv, tuple):
len_rv = len(rv)
if len_rv == 3:
rv, status, headers = rv
elif len_rv == 2:
if isinstance(rv[1], (Headers, dict, tuple, list)):
rv, headers = rv
else:
rv, status = rv
else:
raise TypeError(
"The view function did not return a valid response tuple."
" The tuple must have the form (body, status, headers),"
" (body, status), or (body, headers)."
if rv is None:
raise TypeError(
f"The view function for {request.endpoint!r} did not"
" return a valid response. The function either returned"
" None or ended without a return statement."
if not isinstance(rv, self.response_class):
if isinstance(rv, (str, bytes, bytearray)):
rv = self.response_class(rv, status=status, headers=headers)
status = headers = None
elif isinstance(rv, dict):
rv = jsonify(rv)
elif isinstance(rv, BaseResponse) or callable(rv):
rv = self.response_class.force_type(rv, request.environ)
except TypeError as e:
raise TypeError(
f"{e}\nThe view function did not return a valid"
" response. The return type must be a string,"
" dict, tuple, Response instance, or WSGI"
f" callable, but it was a {type(rv).__name__}."
).with_traceback(sys.exc_info()[2]) from None
else:
raise TypeError(
"The view function did not return a valid"
" response. The return type must be a string,"
" dict, tuple, Response instance, or WSGI"
f" callable, but it was a {type(rv).__name__}."
rv = t.cast(Response, rv)
# prefer the status if it was provided
if status is not None:
if isinstance(status, (str, bytes, bytearray)):
rv.status = status # type: ignore
else:
rv.status_code = status
# extend existing headers with provided headers