flask v0.1 内部运行程序

Werkzeug is an HTTP and WSGI utility library for Python.提供:

1.WSGI server 类似于tomcat,是一个server 容器
2.对requestresponse的封装
3.路由处理,将url和func联系起来

所有的python web都要遵循WSGI协议,每个python web都是一个callable对象,就像app = Flask(__name__)创建出来的app一样.下图中
client就是我们的浏览器,比如chrome,edge,firefox等
server就是apache,nginx,tomcat,和我们要讲的wekzug.WSGIServer
application就是springmvc,springboot,或者flask
在这里插入图片描述
WSGI规定了ServerApplication通信的规范,比如app(environ,start_response)接口,Server会调用Application,并传递environ(请求的所有信息),和start_response(Application处理完需要调用的函数,参数是状态码,响应头等)

1.从flask讲起,这里用的是最初的版本(v0.0.1).

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()

2.app.run()是入口,查找run方法

def run(self, host='localhost', port=5000, **options):
    from werkzeug import run_simple
    if 'debug' in options:
        self.debug = options.pop('debug')
    options.setdefault('use_reloader', self.debug)
    options.setdefault('use_debugger', self.debug)
    return run_simple(host, port, self, **options) # self 就是Flask(__name__)自身

3.run_simple就是监听指定port,收到HTTP时解析为WSGI格式,然后调用app来处理逻辑
WSGI要给app传入environstart_response两个参数,所以要找app__call__

def __call__(self, environ, start_response):
    """Shortcut for :attr:`wsgi_app`"""
    return self.wsgi_app(environ, start_response)

4.可以看到__call__返回的是调用self.wsgi_app,之所以没把self.wsgi_app内容写在__call__中,是因为以后添加中间件方便,
例如app.wsgi_app = MyMiddleware(app.wsgi_app)

def wsgi_app(self, environ, start_response):

    with self.request_context(environ):
        rv = self.preprocess_request()
        if rv is None:
            rv = self.dispatch_request()
        response = self.make_response(rv)
        response = self.process_response(response)
        return response(environ, start_response)

5.首先看self.request_context

def request_context(self, environ):
    return _RequestContext(self, environ)

直接调用的是_RequestContext(self, environ)

class _RequestContext(object):
    def __init__(self, app, environ):
        self.app = app
        self.url_adapter = app.url_map.bind_to_environ(environ)
        self.request = app.request_class(environ)
        self.session = app.open_session(self.request)
        self.g = _RequestGlobals()
        self.flashes = None
    def __enter__(self):
        _request_ctx_stack.push(self)
    def __exit__(self, exc_type, exc_value, tb):
        if tb is None or not self.app.debug:
            _request_ctx_stack.pop()

就是用来存储上下文的,必须用with打开

所以:self.request_context主要是利用stack保证在一个线程里处理这个请求

6.接着看preprocess_request

def preprocess_request(self):
     for func in self.before_request_funcs:
         rv = func()
         if rv is not None:
             return rv

对请求先进行预处理

7.dispatch_requestrequest进行分发处理

    def dispatch_request(self):
        try:
            endpoint, values = self.match_request()
            return self.view_functions[endpoint](**values)
        except HTTPException, e:
            handler = self.error_handlers.get(e.code)
            if handler is None:
                return e
            return handler(e)
        except Exception, e:
            handler = self.error_handlers.get(500)
            if self.debug or handler is None:
                raise
            return handler(e)

返回处理函数的处理结果,就是在flask里写的

@app.route('/')
def hello_world():
    return 'Hello, World!'

8.self.make_response 将结果封装成response,有的在上一步中已经封装了

def make_response(self, rv):
    if isinstance(rv, self.response_class):
        return rv
    if isinstance(rv, basestring):
        return self.response_class(rv)
    if isinstance(rv, tuple):
        return self.response_class(*rv)
    return self.response_class.force_type(rv, request.environ)

9.process_response(self, response)对response进行最后一步处理

def process_response(self, response):
    session = _request_ctx_stack.top.session
    if session is not None:
        self.save_session(session, response)
    for handler in self.after_request_funcs:
        response = handler(response)
    return response

参考:
https://cizixs.com/2017/01/11/flask-insight-start-process/
https://www.toptal.com/python/pythons-wsgi-server-application-interface

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值