美文网首页
Flask 源码解析

Flask 源码解析

作者: 梦醒家先生 | 来源:发表于2018-06-19 23:55 被阅读0次
    • 目标:
      阅读源码了解瓶服务器启动后,用户访问http://127.0.0.1:5000/后浏览“Hello World”这个过程Flask的工作原理及代码框架。
    • flask_ source.py源码:
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run()
    
    
    • Flask框架:
        1.浏览器发送一个IP地址,
        2.服务器收到地址以后把地址通过WSGI协议发送给WEB框架
        3.(服务端)地址是通过字典来保存的
            3.1 先定义一个字典(访问的IP地址)
            3.2 定义函数(接收响应头)
            3.3 WSGI接口函数的引用(接收响应体)
        4.WSGI协议是一个字典和一个函数的引用
            4.1 WSGI协议里面的API(函数)接口返回响应头和响应体(服务端接收到的数据)
        5.服务器接收到数据以后
            5.1 响应头+空行+响应体(渲染页面)
    框架部分代码:
    # 1.框架第一个思想:入口函数简洁
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8'), ("class", "python11")])
    # return :响应体显示
    # environ:服务器给框架传数据,使用的是字典
    # start_response:这个框架给服务器传响应头
    
        file_name = environ['file_name']  # 从字典中去获取路径
        for url, func in url_dict.items():
            match = re.match(url, file_name)
            # 判断当前是否匹配
            if match:
                # 说明匹配
                return func(match)
    
        # 如果都没有找到
        return "not page is find!"
    # 根据不同的文件路径返回不同的内容,地址与我们函数的对应字典
    def route(file_name):
        def set_fun(func):
            def call_fun(*args, **kwargs):
                print("额外功能")
                return func(*args, **kwargs)
    
            # 把地址跟函数添加到字典中
            url_dict[file_name] = call_fun  # 这个只能放在call_fun函数之后
    
            return call_fun
    
        return set_fun
    # 2. 可调用对象是一个类实例
    class AppClass:
        """这里的可调用对象就是 AppClass 的实例,使用方法类似于: 
            app = AppClass()
            for result in app(environ, start_response):
                do_somthing(result)
        """
    
        def __init__(self):
            pass
    
        def __call__(self, environ, start_response):
            status = '200 OK'
            response_headers = [('Content-type', 'text/plain')]
            self.start(status, response_headers)
            yield "Hello world!\n"
    
    
    服务器部分代码:
                .......
                # 定义传送数据的字典
                service_dict = dict()
                service_dict['file_name'] = file_name
    
                # 根据不同的路径返回不同的内容
                body = mini_07.application(service_dict, self.head_params)
                head = "HTTP/1.1 %s \r\n" % self.status  # 这个一定要在我们wsgi调之后再去拼接
                # 把响应头进行拼接
                for temp in self.params:
                    head += "%s:%s\r\n" % (temp[0], temp[1])
                # head += "%s:%s\r\n"%(temp) 可以去试一下
    
                content = head + "\r\n" + body
                # 发送数据
                new_socket.send(content.encode("utf-8"))
                .......
        # 用来接收框架传过来响应头,函数在那里定义,那么对应的参数就会传过来
        def head_params(self, status, params):
            # 保存框架传过来的响应头
            self.status = status
            self.params = params
    
    浏览器访问过程中wsgi的使用.png

    WSGI

    WSGI,全称Web服务器网关接口,或者Python Web服务器网关接口,是基于Python定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。WSGI接口的作用是确保HTTP请求能够转化成蟒蛇应用的一个功能调用,这也就是网关的意义所在,网关的作用就是在协议之前进行转换。
    WSGI接口中有一个非常明确的标准,每个Python的网络应用必须是可调用的可调用的对象且返回一个iterator,并实现app(environ,start_response)的接口,server会调用应用程序,并传递给它的两个参数:environ包含请求的所有信息,start_response是应用程序处理完之后需要调用的函数,参数是状态码,响应头部还有错误信息引用。

    相关文章

      网友评论

          本文标题:Flask 源码解析

          本文链接:https://www.haomeiwen.com/subject/uyazeftx.html