flask route设计思路
admin
2023-07-31 00:40:05
0

引言

本文主要梳理了flask源码中route的设计思路。
首先,从WSGI协议的角度介绍flask route的作用;
其次,详细讲解如何借助werkzeug库的MapRule实现route
最后,梳理了一次完整的http请求中route的完整流程。

flask route 设计思路

源码版本说明

本文参考的是flask 0.5版本的代码。
flask 0.1版本的代码非常短,只有600多行,但是这个版本缺少blueprint机制。
因此,我参考的是0.5版本。

flask route示例

直接使用flask官方文档中的例子

1234567891011121314 from flask import Flaskapp = Flask(__name__) @app.route(\’/\’)def hello_world():    return \’Hello World!\’ @app.route(\’/post/\’)def show_post(post_id):    # show the post with the given id, the id is an integer    return \’Post %d\’ % post_id if __name__ == \’__main__\’:    app.run()

此例中,使用app.route装饰器,完成了以下两个url与处理函数的route:

1234 {     \’/\’: hello_world,     \’/post/\’ : show_post}

这样做的效果为:
当http请求的url为’/’时,flask会调用hello_world函数;
当http请求的url为’/post/’(例如/post/32)时,flask会调用show_post函数;

flask route的作用

从上面的示例中其实可以明白:flask route的作用就是建立url与处理函数的映射

WSGI协议将处理请求的组件按照功能及调用关系分成了三种:server, middleware, application
其中,server可以调用middleware和application,middleware可以调用application。

符合WSGI的框架对于一次http请求的完整处理过程为:
server读取解析请求,生成environ和start_response,然后调用middleware;
middleware完成自己的处理部分后,可以继续调用下一个middleware或application,形成一个完整的请求链;
application位于请求链的最后一级,其作用就是生成最终的响应。

12 http服务器(比如,nginx> WSGI server(比如gunicornSimpleHttpServer)>middleware> middleware> ... >application

如果接触过Java Web 开发的人可能会立刻发现,这与servlet中的middleware机制是完全一致的。

特别重要的:

在上一小节的示例中app = Flask(__name__)创建了一个middleware
而这个middleware的核心作用是进行请求转发(request dispatch)。

上面这句话非常重要,请在心里重复一百遍。
上面这句话非常重要,请在心里重复一百遍。
上面这句话非常重要,请在心里重复一百遍。

进行请求转发的前提就是能够建立url与处理函数之间的映射关系,即route功能。
因此,在flask中,route是Flask类的一个装饰器。

flask route的实现思路

通过上一小节,我们知道以下两点:

  1. flask route 是url与处理函数的映射关系;
  2. 在http请求时,Flask这个middleware负责完成对url对应的处理函数的调用;

那么,如果是我们自己来实现route,思路也很简单:

  1. 建立一个类Flask,这个类是一个middleware,并且有一个字典型的成员变量url_map
  2. url_map = {url : function}
  3. 当http请求时,进行request dispatch:根据url,从url_map中找到function,然后调用function;
  4. 调用后续的middleware或application,并把function的结果传递下去。

flask的实现思路也是这样的。

123456789101112131415161718 class Flask(object):     def __init__(self):        self.url_map = {}  # 此处定义保存url与处理函数的映射关系     def __call__(self, environ, start_response):  # 根据WSGI协议,middleware必须是可调用对象        self.dispatch_request(    # Flask的核心功能 request dispatch        return application(environ, start_response)  #最后调用下一级的application     def route(self, rule):  # Flask使用装饰器来完成url与处理函数的映射关系建立        def decorator(f):   # 简单,侵入小,优雅            self.url_map[rule] = f            return f        return decorator     def dispath_request(self):        url = get_url_from_environ() #解析environ获得url         return self.url_map[url]() #从url_map中找到对应的处理函数,并调用

至此, 一个简单的Flaskmiddleware的骨架就完成了。
上面的Flask类主要功能包括:

  1. 符合WSGI协议的middleware:可被调用,并且可以调用application
  2. 能够保存url与处理函数的映射信息
  3. 能够根据url找到处理函数并调用(即,request dispatch)

当然,在实际中,不可能这么简单,但是基本思路是一致的。

werkzeug库中的Map与Rule在Flask中的应用

需要指出,上面实现的最简单的Flask类还是有很多问题的。
比如,HTTP请求中相同的url,不同的请求方法,比如GET,POST如果对应不同的处理函数,该如何处理?

flask使用了werkzeug库中的MapRule来管理url与处理函数映射关系。

首先需要简单了解一下MapRule的作用:
werkzeug中,Rule的主要作用是保存了一组urlendpointmethods关系:
每个(url, endpoint, methods)都有一个对应的Rule对象:
其实现如下:

12345 class Rule(object):    def __init__(self, url, endpoint, methods):        self.rule = url        self.endpoint = endpoint        self.methods = methods

这里需要解释一下endpoint
前面说过:url与其处理函数可以使用一个字典来实现:{url: function}

flask在实现的时候,在中间加了一个中介endpoint,于是,url与处理函数的映射yon-h\”> methods

这里需要解释一下endpoint
前面说过:url与其处理函数可以使用一个字典来实现:{url: function}

flask在实现的时候,在中间加了一个中介endpoint,于是,url与处理函数的映射 Ό整流程。

flask route 设计思路

源码版本说明

本文参考的是flask 0.5版本的代码。
flask 0.1版本的代码非常短,只有600多行,但是这个版本缺少blueprint机制。
因此,我参考的是0.5版本。

flask route示例

直接使用flask官方文档中的例子

1234567891011121314 from flask import Flaskapp = Flask(__name__) @app.route(\’/\’)def hello_world():    return \’Hello World!\’ @app.route(\’/post/\’)def show_post(post_id):    # show the post with the given id, the id is an integer    return \’Post %d\’ % post_id if __name__ == \’__main__\’:    app.run()

此例中,使用app.route装饰器,完成了以下两个url与处理函数的route:

1234 {     \’/\’: hello_world,     \’/post/\’ : show_post}

这样做的效果为:
当http请求的url为’/’时,flask会调用hello_world函数;
当http请求的url为’/post/’(例如/post/32)时,flask会调用show_post函数;

flask route的作用

从上面的示例中其实可以明白:flask route的作用就是建立url与处理函数的映射

WSGI协议将处理请求的组件按照功能及调用关系分成了三种:server, middleware, application
其中,server可以调用middleware和application,middleware可以调用application。

符合WSGI的框架对于一次http请求的完整处理过程为:
server读取解析请求,生成environ和start_response,然后调用middleware;
middleware完成自己的处理部分后,可以继续调用下一个middleware或application,形成一个完整的请求链;
application位于请求链的最后一级,其作用就是生成最终的响应。

12 http服务器(比如,nginx> WSGI server(比如gunicornSimpleHttpServer)>middleware> middleware> ... >application

如果接触过Java Web 开发的人可能会立刻发现,这与servlet中的middleware机制是完全一致的。

特别重要的:

在上一小节的示例中app = Flask(__name__)创建了一个middleware
而这个middleware的核心作用是进行请求转发(request dispatch)。

上面这句话非常重要,请在心里重复一百遍。
上面这句话非常重要,请在心里重复一百遍。
上面这句话非常重要,请在心里重复一百遍。

进行请求转发的前提就是能够建立url与处理函数之间的映射关系,即route功能。
因此,在flask中,route是Flask类的一个装饰器。

flask route的实现思路

通过上一小节,我们知道以下两点:

  1. flask route 是url与处理函数的映射关系;
  2. 在http请求时,Flask这个middleware负责完成对url对应的处理函数的调用;

那么,如果是我们自己来实现route,思路也很简单:

  1. 建立一个类Flask,这个类是一个middleware,并且有一个字典型的成员变量url_map
  2. url_map = {url : function}
  3. 当http请求时,进行request dispatch:根据url,从url_map中找到function,然后调用function;
  4. 调用后续的middleware或application,并把function的结果传递下去。

flask的实现思路也是这样的。

123456789101112131415161718 class Flask(object):     def __init__(self):        self.url_map = {}  # 此处定义保存url与处理函数的映射关系     def __call__(self, environ, start_response):  # 根据WSGI协议,middleware必须是可调用对象        self.dispatch_request(    # Flask的核心功能 request dispatch        return application(environ, start_response)  #最后调用下一级的application     def route(self, rule):  # Flask使用装饰器来完成url与处理函数的映射关系建立        def decorator(f):   # 简单,侵入小,优雅            self.url_map[rule] = f            return f        return decorator     def dispath_request(self):        url = get_url_from_environ() #解析environ获得url         return self.url_map[url]() #从url_map中找到对应的处理函数,并调用

至此, 一个简单的Flaskmiddleware的骨架就完成了。
上面的Flask类主要功能包括:

  1. 符合WSGI协议的middleware:可被调用,并且可以调用application
  2. 能够保存url与处理函数的映射信息
  3. 能够根据url找到处理函数并调用(即,request dispatch)

当然,在实际中,不可能这么简单,但是基本思路是一致的。

werkzeug库中的Map与Rule在Flask中的应用

需要指出,上面实现的最简单的Flask类还是有很多问题的。
比如,HTTP请求中相同的url,不同的请求方法,比如GET,POST如果对应不同的处理函数,该如何处理?

flask使用了werkzeug库中的MapRule来管理url与处理函数映射关系。

首先需要简单了解一下MapRule的作用:
werkzeug中,Rule的主要作用是保存了一组urlendpointmethods关系:
每个(url, endpoint, methods)都有一个对应的Rule对象:
其实现如下:

12345 class Rule(object):    def __init__(self, url, endpoint, methods):        self.rule = url        self.endpoint = endpoint        

相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
python绘图库Matplo... 本文简单介绍了Python绘图库Matplotlib的安装,简介如下: matplotlib是pyt...
Prometheus+Graf... 一,Prometheus概述 1,什么是Prometheus?Prometheus是最初在Sound...