第1步:Flask Request 的执行流程
启动先执行manage.py 中的 app.run()
class Flask(_PackageBoundObject):
def run(self, host=None, port=None, debug=None, **options):
from werkzeug.serving import run_simple
try:
#run_simple 是werkzeug 提供的方法,会执行第三个参数 self()
run_simple(host, port, self, **options)
调用了wsgi方法,执行初步的请求,wsgi把要处理的信息交给__call__方法去执行wsgi_app(),通过app.request_context方法,把请求的相关信息传给RequestContext(),并返回,得到ctx对象,其中封装了request,session
class Flask(_PackageBoundObject):
def wsgi_app(self, environ, start_response):
#1.
ctx = self.request_context(environ)
#self.request_context
#2.
ctx.push()
try:
try:
#3.执行视图函数
response = self.full_dispatch_request()
except Exception as e:
error = e
#4.
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
#5.
ctx.auto_pop(error)
def request_context(self, environ):
return RequestContext(self, environ)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
class RequestContext(object):
def __init__(self, app, environ, request=None):
self.app = app
if request is None:
request = app.request_class(environ)
#app.request_class = Request
self.request = request
self.session = None
ctx = self.request_context(environ)
ctx.push()
ctx是一个RequestContext对象,这个对象里面封装了两个主要的属性,一个是self.request = Request实例的对象,Request对象里面封装了请求进来的所有数据;另外一个是self.session = None。
第1.1步:到_app_ctx_stack这个栈中取最后一个数据,如果未取到或者取到的不是当前的app,就调用app.app_context()方法,就是新实例一个上下文app_ctx对象,再执行app_ctx.push()方法 (在这再次强调,因为app_ctx是AppContext对象,就要先去AppContext类中找push方法),
class RequestContext(object):
def push(self):
#2.1.
app_ctx = _app_ctx_stack.top
if app_ctx is None or app_ctx.app != self.app:
app_ctx = self.app.app_context()
# self.app.app_context = app.app_context = AppContext(app)
app_ctx.push() # 将封装好的request/session放在一个空间中
#2.2.
_request_ctx_stack.push(self)
#_request_ctx_stack = LocalStack()
#2.3.
self.session = self.app.open_session(self.request)
#判断没有 secret_key时:
if self.session is None:
self.session = self.app.make_null_session()
#raise RuntimeError('The session is unavailable because no secret ''key was set.)
class AppContext(object):
def push(self):
_app_ctx_stack.push(self) #把新创建的app_ctx上下文app对象添加到了_app_ctx_stack这个栈中
appcontext_pushed.send(self.app) #在这里遇到了第一个信号,请求app上下文push时执行
第1.2步:LocalStack类,帮助操作local __storage__字典,把ctx对象添加到local中,(对local维护的__sto