Flask 中的 request session执行流程分析

本文详细分析了Flask框架中Request Session的工作流程,从启动应用到处理请求,包括RequestContext的创建、session的初始化、LocalStack的使用以及视图函数的执行。特别关注了session的保存过程,涉及到SecureCookieSessionInterface的is_null_session和save_session方法。此外,还讨论了多应用环境下RequestContext的pop方法以及teardown_request阶段的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值