Flask 源码解析

  • 目标:
    阅读源码了解瓶服务器启动后,用户访问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
Flask 源码解析_第1张图片
浏览器访问过程中wsgi的使用.png

WSGI

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

你可能感兴趣的:(Flask 源码解析)