Ubuntu下SSH安装及提高SSH登陆认证速度的办法
引言
本文主要梳理了flask
源码中route
的设计思路。
首先,从WSGI
协议的角度介绍flask route
的作用;
其次,详细讲解如何借助werkzeug
库的Map
、Rule
实现route
;
最后,梳理了一次完整的http请求中route
的完整流程。
flask route 设计思路
源码版本说明
本文参考的是flask 0.5
版本的代码。flask 0.1
版本的代码非常短,只有600多行,但是这个版本缺少blueprint
机制。
因此,我参考的是0.5版本。
flask route示例
直接使用flask
官方文档中的例子
- from flask import Flask
- app = Flask(__name__)
- @app.route('/')
- def hello_world():
- return 'Hello World!'
- @app.route('/post/<int:post_id>')
- 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
:
- {
- '/': hello_world,
- '/post/<int:post_id>' : 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位于请求链的最后一级,其作用就是生成最终的响应。
- http服务器(比如,nginx)--> WSGI server(比如gunicorn,SimpleHttpServer)-->middleware-->
- middleware--> ... -->application
如果接触过Java Web 开发的人可能会立刻发现,这与servlet中的middleware机制是完全一致的。
特别重要的:
- 在上一小节的示例中app = Flask(__name__)创建了一个middleware,
- 而这个middleware的核心作用是进行请求转发(request dispatch)。
上面这句话非常重要,请在心里重复一百遍。
进行请求转发的前提就是能够建立url与处理函数之间的映射关系,即route
功能。
因此,在flask
中,route是Flask类的一个装饰器。
flask route的实现思路
通过上一小节,我们知道以下两点:
flask route
是url与处理函数的映射关系;在http请求时,
Flask
这个middleware
负责完成对url对应的处理函数的调用;
那么,如果是我们自己来实现route
,思路也很简单:
建立一个类
Flask
,这个类是一个middleware,并且有一个字典型的成员变量url_map
;url_map = {url : function}
当http请求时,进行request dispatch:根据url,从url_map中找到
function
,然后调用function;调用后续的middleware或application,并把function的结果传递下去。
flask的实现思路也是这样的。
- 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中找到对应的处理函数,并调用
至此, 一个简单的Flask
middleware的骨架就完成了。
上面的Flask
类主要功能包括:
符合WSGI协议的middleware:可被调用,并且可以调用application
能够保存url与处理函数的映射信息
能够根据url找到处理函数并调用(即,request dispatch)
当然,在实际中,不可能这么简单,但是基本思路是一致的。
werkzeug库中的Map与Rule在Flask中的应用
需要指出,上面实现的最简单的Flask
类还是有很多问题的。
比如,HTTP请求中相同的url,不同的请求方法,比如GET,POST如果对应不同的处理函数,该如何处理?
flask使用了werkzeug
库中的Map
和Rule
来管理url与处理函数映射关系。
首先需要简单了解一下Map
和Rule
的作用:
在werkzeug
中,Rule
的主要作用是保存了一组url
,endpoint
,methods
关系:
每个(url, endpoint, methods)都有一个对应的Rule对象:
其实现如下:
- 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与处理函数的映射变成了这样:
- url-->endpoint-->function #一个url对应一个endpoint,一个endpoint对应一个function
- {url: endpoint} # 保存url与endpoint之间的关系
- {endpoint: function} #保存endpoint与function之间的关系
于是,刚才我们实现的简单的flask
骨架中{url: function}
的字典,就变成了{endpoint: function}
,
而{url: endpoint}
这个映射关系就需要借助Map
和Rule
这两个类来完成。
可以发现:endpoint
就是url和处理函数映射关系中的一个中介,所以,它可以是任何可以用作字典键的值,比如字符串。
但是在实际使用中endpoint
,一般endpoint
均为字符串,并且默认情况下:
如果是通过
Flask.route
装饰器建立的映射关系,那么endpoint
就是处理函数的函数名;如果是通过
blueprint
建立的映射关系,那么endpoint
是blueprint名.处理函数名;
因为,每建立一个url-->endpoint-->function
关系就会创建一个Rule
对象,所以,会有很多Rule
对象存在。Map
的作用则是保存所有Rule
对象。
所以,一般情况下Map
的用法如下:
- m = Map([
- Rule('/', endpoint='index'),
- Rule('/downloads/', endpoint='downloads/index'),
- Rule('/downloads/<int:id>', endpoint='downloads/show')
- ])
在flask的源码中
- class Flask(object):
- def __init__(self):
- self.url_map = Map() # url_map为保存所有Rule关系的容器Map
- self.view_functions = {} # view_functions保存endpoint-->function
成员变量
url_map
保存所有的(url, endpoint, method)
关系成员变量
view_functions
保存所有的{endpoint, function}关系
所以,对于一个url,只要能找到(url,endpoint,method)
,就能根据endpoint
找到对应的function
。
route的完整流程
首先,建立Flask
对象:
- app = Flask(__name__)
然后,建立url
与function
之间的映射关系:
- @app.route('/')
- def hello_world():
- return 'Hello World!'
在装饰器route
中,创建(url, endpoint, method)
和{endpoint: function}
两组映射关系:
- if endpoint is None:
- endpoint = view_func.__name__ # 默认使用响应函数名作为endpoint
- self.url_map.add(Rule(url, endpoint, method)) # 保存(url, endpoint, method)映射关系
- self.view_functions[endpoint] = view_func # 保存{endpoint: function}映射关系
这样,就完成了对url和响应函数的映射关系。
下一步,调用WSGI server响应http请求,在文章开始的示例中使用:
- app.run()
调用python
标准库提供的WSGI server,在实际使用时,可能是gunicorn
或uwsgi
。
不论server是什么,最终都会调用Flask.__call__
函数。这个函数完成request dispatch的任务。
对于request dispatch而言,首先根据请求,解析environ,得到url,
然后调用Map.match
函数,这个函数会最终找到预先保存的(url, endpoint, method)
映射,
然后返回(endpoint, url请求参数),
由于得到了endpoint,然后,可以从Flask.view_functions
中直接取到对应的响应函数,
所以,可以直接进行函数调用
- self.view_functions[endpoint](url请求参数)
至此,就完成了完整的route
。
总结
flask
的Flask
类是WSGI
的dispatch middleware
;Flask
的url_map
保存所有的(url, endpoint, method)映射关系;Flask
的view_functions
保存所有的{endpoint: function}映射关系;dispath request
就是根据url找到endpoint,再根据endpoint找到function,最后调用function的过程
https://segmentfault.com/a/1190000004213652
Ubuntu下SSH安装及提高SSH登陆认证速度的办法的更多相关文章
- ubuntu下git安装及使用
ubuntu下git安装及使用 其实,好几个月前,就已经安装好了,可是一直搁置在那儿,所以密码等一些其它细节都忘的差不多了,所以今天就重新部署了一下,并开始积极使用......... 1,git ...
- Torch7在Ubuntu下的安装与配置
Torch7的本系列教程的主要目的是介绍Torch的入门使用.今天首先分享一下Torch7的安装.(在Ubuntu14.04安装torch7) 为什么选择Torch Torch的目标是在建立科学算法的 ...
- premake Ubuntu下的安装
premake是个跨平台的编译工具,先看看在Ubuntu下怎么安装. 首先下载,在/usr目录下: sudo wget -O premake-4.4-beta4-linux.tar.gz http:/ ...
- linux,windows,ubuntu下git安装与使用
ubuntu下git安装与使用:首先应该检查本地是否已经安装了git ,如果没有安装的话,在命令模式下输入 sudo apt-get install git 进行安装 输入git命令查看安装状态及常用 ...
- ubuntu下如何安装codeblocks集成开发环境
codeblocks是一个十分优秀的C/C++开发IDE,虽然后起之秀codelite目前来看大有超越之势哦. 不过在ubuntu下安装codeblocks却比较麻烦,不像其他linux发行版,比如s ...
- ubuntu下makeinfo安装,其实真正安装的是texinfo包
操作系统环境:ubuntu 在终端中执行命令:sudo apt-get install texinfo 今天在打包的时候有个包需要 makeinfo,当时就各种搜结果就没有 makeinfo 这个 ...
- Ubuntu下软件安装方式、PATH配置、查找安装位置
Ubuntu 18.04, 安装方式 目前孤知道的Ubuntu下安装软件方式有3种(命令): 1.make 2.apt/apt-get 3.dpkg 方式1基于软件源码安装,需要经历配置(可选).编译 ...
- Mac下新安装的MySQL无法登陆root用户解决方法
一 设置MySQL命令行搜索路径 0.苹果->系统偏好设置->最下边点mysql 在弹出页面中 启动mysql服务 1.打开终端,输入: sudo vi ~/.bash_profile ...
- ubuntu 下python安装及hello world
//@desn:ubuntu 下python安装及hello world //@desn:码字不宜,转载请注明出处 //@author:张慧源 <turing_zhy@163.com> ...
随机推荐
- (二)Linux实操之——网络配置、进程管理、服务管理、组管理、YUM
接上段 (一)Linux实操之——权限.任务调度.磁盘分区 4.网络配置 4.1 NAT模式的网络配置 目前我们采用的网络配置是NAT模式. windows下cmd通过 ipconfig 命令可以 ...
- 初步了解“C#反射”
来源:http://zhidao.baidu.com/link?url=YzuEaWpYMxYV86bAFVmSAGYtXEzkJ_ndMyZ69QuvNJfikwXvlmtP42hAslGFS2uu ...
- [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)
转自:[CXF REST标准实战系列] 一.JAXB xml与javaBean的转换 文章Points: 1.不认识到犯错,然后得到永久的教训. 2.认识JAXB 3.代码实战 1.不认识到犯错,然后 ...
- HDUOJ----2487Ugly Windows
Ugly Windows Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDUOJ-----1556Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- iphone 如何给cydia添加中文源和威锋源
http://zhidao.baidu.com/question/270663590.html英文的也没关系, 步骤是这样的, 1. 打开Cydia, 下面有五个项目, 然后选倒数第二个manage, ...
- 基于HTTP在互联网传输敏感数据的消息摘要、签名与加密方案
基于HTTP在互联网传输敏感数据的消息摘要.签名与加密方案 博客分类: 信息安全 Java 签名加密AESMD5HTTPS 一.关键词 HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数 ...
- js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象
我最近在做一个vue + element-UI + vue-resource + vuex项目的时候,遇到了一个对象的问题. 当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后 ...
- 10条建议让你创建更好的jQuery插件(转载)
为了避免重复造轮子,自己手动开发jquery 插件,让小组其他成员可以直接使用.学习开发中,看到Phillip Senn 写的 关于jquery 插件开发注意10点,转载之! ------------ ...
- RGB(FFFFFF)转255:255:255
NSString *color = model.display_color; long colorLong = strtoul([color cStringUsingEncoding:NSUTF8St ...