码迷,mamicode.com
首页 > 其他好文 > 详细

剖析Flask上下文管理(源码)

时间:2018-12-22 01:19:59      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:llb   response   port   ddl   路由   for   occurs   push   def   

一、源码开始

示例一

from  flask import  Flask


#1. 实例化Flask对象
app = Flask(__name__)


#2. 设置路由
"""
app.url_map = [ 
        (‘/login‘, login)
        (‘/home‘, home)
    ]
"""

@app.route(/index)
def index():
    return index



if __name__ == __main__:
    #3. 启动socket服务端
    app.run()

在以上示例中,app.run是请求的入口,而app是Flask实例化的对象,所以执行的是Flask类中的run方法,而在该改方法中又执行了run_simple方法,以下是run方法部分源码摘抄(其中self就是app对象):

from werkzeug.serving import run_simple

try:
    run_simple(host, port, self, **options)
finally:
    # reset the first request information if the development server
    # reset normally.  This makes it possible to restart the server
    # without reloader and that stuff from an interactive shell.
    self._got_first_request = False

在run_simple中会执行app(environ, start_response),参考werkzeug的源码,源码会执行app(environ, start_response)也就是执行app的__call__方法,以下是__call__方法源码摘抄:

1. 当用户请求来以后会执行__call__方法, __call__方法返回值是执行wsgi_app.

def __call__(self, environ, start_response):
    """The WSGI server calls the Flask application object as the
    WSGI application. This calls :meth:`wsgi_app` which can be
    wrapped to applying middleware."""
    return self.wsgi_app(environ, start_response)  #当用户请求进来后会执行wsgi_app将请求的数据和响应的数据传到wsgi_app中

2.执行wsgi_app

    def wsgi_app(self, environ, start_response):
        """The actual WSGI application. This is not implemented in
        :meth:`__call__` so that middlewares can be applied without
        losing a reference to the app object. Instead of doing this::

            app = MyMiddleware(app)

        It‘s a better idea to do this instead::

            app.wsgi_app = MyMiddleware(app.wsgi_app)

        Then you still have the original application object around and
        can continue to call methods on it.

        .. versionchanged:: 0.7
            Teardown events for the request and app contexts are called
            even if an unhandled error occurs. Other events may not be
            called depending on when an error occurs during dispatch.
            See :ref:`callbacks-and-errors`.

        :param environ: A WSGI environment.
        :param start_response: A callable accepting a status code,
            a list of headers, and an optional exception context to
            start the response.
        """

        """
        1. 获取environ并对其进行再次封装
        2. 从environ中获取名称为session的cookie,解密,反序列化。
        3. 放在一个存数据的地方
        """
        # ctx = RequestContext(self,environ) #self就是app对象,environ请求相关原始的数据
        # ctx.request = app.request_class(environ)
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                #将ctx放到一个存放数据的地方
                #执行SecureCookieSessionInterface.open_session,去cookie中获取值并给ctx.session重新赋值
                ctx.push()
                #4.执行视图函数
                #5.“获取某个地方的session”加密 => 写cookie
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

            """
            6、“某个神奇的”位置清空
            """

 

剖析Flask上下文管理(源码)

标签:llb   response   port   ddl   路由   for   occurs   push   def   

原文地址:https://www.cnblogs.com/liuxiangpy/p/10159187.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!