python安装 werkzeug
Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等。
例如我最常用的 Flask 框架就是一 Werkzeug 为基础开发的,这也是我要解析一下 Werkzeug 底层的原因,因为我想知道 Flask 的实现逻辑以及底层控制。这篇文章没有涉及到 Flask 的相关内容,只是以 Werkzeug 创建一个简单的 Web 应用,然后以这个 Web 应用为例剖析请求的处理以及响应的产生过程。
下面我们以一个简短的例子开始,先看看怎么使用 werkzeug,然后再逐步刨析 werkzeug 的实现原理。
安装 werkzeug
我希望读者是在 virtualenv 环境中跟着我的步伐走得,如果你还不知道什么是 virtualenv,那么你可以在我的博客中搜索一下 virtualenv,然后先弄好,再继续,因为很可能因为一些库的冲突等问题导致你看不到本文中介绍的东西。 ok,下面开始安装 werkzeug,
pip install Werkzeug 这条命令下去,几秒钟之后你就可以使用 werkzeug 了。
一个简单地 web 服务器 接下来,我们就开始使用 werkzeug 来创建一个简单的 web 服务器,这个服务器就仅仅返回 “Hello Werkzeug”,没有其他内容。
#!/usr/bin/env python
# encoding: utf-8
import os from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response
from werkzeug.wsgi import SharedDataMiddleware class Shortly(object):
def dispatch_request(self, request):
return Response('Hello Werkzeug!') def wsgi_app(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response) def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response) def create_app(with_static=True):
app = Shortly()
if with_static:
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/static': os.path.join(os.path.dirname(__file__), 'static')
})
return app if __name__ == '__main__':
app = create_app()
run_simple('127.0.0.1', 6666, app, use_debugger=True, use_reloader=True) 这段代码就实现了我说的功能,那么我们就来看看这段代码是怎么运作的? 首先,一切都回到最开始的地方开始,从 main 开始看起,可以发现 main 是非常简单地,只有一个初始化函数,然后就调用了 werkzeug 的 run_simple 函数。okay,我们可以发现这个 app 其实是一个 Shortly 对象,这个类就只实现了 3 个方法,一个是 dispatch_request, wsig_app, call ,就这么简单了,那我们就知道了,关键的代码都不是这些,应该是 run_simple.
run_simple 解析 okay,我们这个系列博客的目的就是解析 werkzeug 源码,所以拿到 werkzeug 源码肯定是我们必须要做的。所以第一步我们就需要从 github 上将 werkzeug clone 下来: git clone https://github.com/mitsuhiko/werkzeug.git
然后,我们就找 run_simple 的代码咯
vim werkzeug/serving.py
goto line 559 我们可以看到这个函数的定义,秉着关注重点的原则,我们就忽略条件判断,以一条最简单地路线来看代码,那么这里就假设: use_debugger = False
static_files = False
use_reloader = False OK, 那到这里其实 run_simple 调用的就是 inner 了,那么就来看看 inner 的代码: 646: try:
647: fd = int(os.environ['WERKZEUG_SERVER_FD'])
648: except (LookupError, ValueError):
649: fd = None
650: srv = make_server(hostname, port, application, threaded,
651: processes, request_handler,
652: passthrough_errors, ssl_context,
653: fd=fd)
654: if fd is None:
655: log_startup(srv.socket)
656: srv.serve_forever() 忽略 fd,那么剩下一点点了: 650: srv = make_server(hostname, port, application, threaded,
651: processes, request_handler,
652: passthrough_errors, ssl_context,
653: fd=fd) 656: srv.serve_forever() 好,你应该和我一样有兴致得想知道这个 make_server 里面是什么内容了,我也很期待,那就跟上去看看。 make_server 的代码我就不贴了,还是最简原则,忽略各种条件,那么这里就假设:
threaded = False
processes = 1
那么代码也很简单了,就剩下:
546: return BaseWSGIServer(host, port, app, request_handler,
547: passthrough_errors, ssl_context, fd=fd) 很好,好不容易跟踪到这,终于上关键了,那就是这个 BaseWSGIServer 了,我们就来看看这个类实现了什么功能。
先看这个类的定义:
443: class BaseWSGIServer(HTTPServer, object):
这个类是继承自 HTTPServer 的,那么我们就有点底了,这差不多到头了,已经和 Python 的 API 碰上了。好,既然是继承自 HTTPServer,那么就把他当做 HTTPServer,然后继续看 run_simple 的代码,我们一路跟踪下来,我们发现了 656 行有一个 srv.serve_forever(),那么这不就是 HTTPServer 的用法吗? server.serve_forever() 。
okay,到这那么事情已经暂告一段落了,虽然很多事情都还没搞清楚,例如请求是怎么被封装的,响应又在哪里被处理了,例如URL路由之类的怎么操作的。但是,我们已经对 Werkzeug 有一个大概的印象了,知道他低层还是 HTTPServer 实现的,没有太多特殊的自定义协议。在下一章我们会逐步得进行进行更深层次的解密
python安装 werkzeug的更多相关文章
- Python 工具包 werkzeug 初探
首先,先向大家介绍一下什么是 werkzeug,Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库.这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架, ...
- python安装、模块安装
python安装 windows 下载安装包 https://www.python.org/downloads 改环境变量 [右键计算机]-->[属性]-->[高级系统设置]-->[ ...
- win7系统下python安装numpy,matplotlib,scipy和scikit-learn
1.安装numpy,matplotlib,scipy和scikit-learn win7系统下直接采用pip或者下载源文件进行安装numpy,matplotlib,scipy时会遇到各种问题,这是因为 ...
- python安装完毕后,提示找不到ssl模块的解决步骤
转载自 醇酒醉影 python安装完毕后,提示找不到ssl模块: [root@localhost ~]# python2.7.5 Python 2.7.5 (default, Jun 3 2013, ...
- [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决
这篇文章主要讲述Python如何安装Numpy.Scipy.Matlotlib.Scikit-learn等库的过程及遇到的问题解决方法.最近安装这个真是一把泪啊,各种不兼容问题和报错,希望文章对你有所 ...
- python安装numpy和pandas
最近要对一系列数据做同比比较,需要用到numpy和pandas来计算,不过使用python安装numpy和pandas因为linux环境没有外网遇到了很多问题就记下来了.首要条件,python版本必须 ...
- python 安装模块
python安装模块的方法很多,在此仅介绍一种,不需要安装其他附带的pip等,python安装完之后,配置环境变量,我由于中英文分号原因,环境变量始终没能配置成功汗. 1:下载模块的压缩文件解压到任意 ...
- linux下python安装到指定目录
由于使用公司服务器时没有root权限,只能把python安装到个人文件夹下,使用源码包方式安装,这里记录一下. 1.python下载 cd到目录/users/w,在此目录下安装python.通过wge ...
- Python安装、配置图文详解(转载)
Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境(I ...
随机推荐
- 关于升级.NetCore3.1启动运行项目之后无法运行之前版本的错误解决方案
昨天在跟上微软的进度,更新VS版本升级.netcore3.1 之后成功运行之后发现,我无法运行之前版本的问题 都是报这种问题: 还有打开解决方案所有的项目都无法正常加载,都是"已卸载&quo ...
- jmeter中设置线程数与设置集合点的区别
1.设置线程数: 表示10秒内启动50个线程, 运行结果如下:10秒内启动了50个线程 2.设置集合点: Number of Simulated Users to Group by:50,表示集合50 ...
- Zabbix4.0如何添加监控信息
二.添加监控信息 监控Windows主机: 首先需要在Windows主机上安装好Zabbix agent,安装方法,见另一篇博客,https://www.cnblogs.com/opsprobe/p/ ...
- BZOJ5509: [Tjoi2019]甲苯先生的滚榜
题解 开n个平衡树对每个AC数维护罚时,然后不同AC数用树状数组维护即可. 其实挺好写的...就是评测的时候评的巨久... #include <bits/stdc++.h> using n ...
- 运行 npm run lint -- --fix,提示:error Use the global form of 'use strict'
运行 npm run lint -- --fix,提示:error Use the global form of 'use strict',使用说明网址:https://eslint.org/docs ...
- oracle row_number() over(partition by .. order by ..)和rank() over(partition by .. order by ..) 和dense_rank() over(partition by .. order by ..)的相似点与区别
新建一个测试表 create table dim_ia_test2(device_number varchar2(20),desc2 varchar2(20)) 插入数据后得到: 一.oracle r ...
- map转list | 对象转数组 | 美菜数据格式转换
function formatData(tempObj){ let bigArr = []; for(let p in tempObj){ let tempArrForeach1 = [] for(l ...
- Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)
http://codeforces.com/contest/1154/problem/E 解题: 举例n=10,k=1 1,2,10,4,7,6,9,8,5,3 第一次,1队先挑2,10,4这三个人 ...
- keepalived是什么及作用?
参考:https://www.cnblogs.com/hqjy/p/7615439.html keepalived介绍 keepalived观察其名可知,保持存活,在网络里面就是保持在线了, 也就是所 ...
- CLR Exception---E0434F4D
什么是CLR Exception---E0434F4D 就是公共语言运行时(CLR)异常,异常代码为0xE0434F4D.因此任何托管异常,如NullReferenceException.invali ...