深入解析Python中的WSGI接口


Posted in Python onMay 11, 2015

概述

WSGI接口包含两方面:server/gateway 及 application/framework。
server调用由application提供的可调用对象。
另外在server和application之间还可能有一种称作middleware的中间件。
可调用对象是指:函数、方法、类或者带有callable方法的实例。
关于application

函数、方法、类及带有callable方法的实例等可调用对象都可以作为the application object。
WSGI协议要求:
the application object接受两个参数且可以被多次调用

这两个参数分别为:
1.CGI式的字典;
2.回调函数:application用来向server传递http状态码/消息/http头

另外协议要求可调用对象必须将响应体封装成一个可迭代的strings返回。

# the application object. 可以使用其他名字,
# 但是在使用mod_wsgi 时必须为 "application"
def application( environ, start_response):
# 函数接受两个参数:
# environ :包含有CGI 式环境变量的字典,由server负责提供内容
# start_response:由server提供的回调函数,其作用是将状态码和响应头返回给server

# 构造响应体,以可迭代字符串形式封装
  response_body = 'The request method was %s' % environ['REQUEST_METHOD']

# HTTP 响应码及消息
  status = '200 OK'

# 提供给客户端的响应头.
# 封装成list of tuple pairs 的形式:
# 格式要求:[(Header name, Header value)].
  response_headers = [('Content-Type', 'text/plain'),
            ('Content-Length', str(len(response_body)))]

# 将响应码/消息及响应头通过传入的start_reponse回调函数返回给server
  start_response(status, response_headers)

# 响应体作为返回值返回
# 注意这里被封装到了list中.
  return [response_body]

关于server

从概述中可以知道,WSGI server必须要调用application,同时,从application的协议要求可知:
1. WSGI server必须向application提供环境参数,因此,自身也必须能够获取环境参数。
2. WSGI server接收application的返回值作为响应体。
最简单的WSGI server为Python自带的wsgiref.simple_server
示例如下:

from wsgiref.simple_server import make_server
srv = make_server('localhost', 8080, hello_world)
srv.serve_forever()

关于middleware

middleware的概念没有appllication和server那么容易理解。
假设一个符合application标准的可调用对象,它接受可调用对象作为参数,返回一个可调用对象的对象。
那么对于server来说,它是一个符合标准的可调用对象,因此是application。
而对于application来说,它可以调用application,因此是server。
这样的可调用对象称为middleware。

middleware的概念非常接近decorator。

以一个路由的例子示例:

import re

# 这是一个标准的application object
def index(environ, start_response):
  start_response('200 OK', [('Content-Type', 'text/html')])
  return ['index page']

# 这是一个标准的application object
def hello(environ, start_response):
  start_response('200 OK', [('Content-Type', 'text/html')])
  return ['hello page']

# 这是一个标准的application object
def not_found(environ, start_response):
  start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
  return ['Not Found Page']

# map urls to functions
urls = [
  (r'^$', index),
  (r'hello/?$', hello)
]
# 这是一个middleware
# 根据不同的route返回不同的application object
def application(environ, start_response):
  path = environ.get('PATH_INFO', '').lstrip('/')
  for regex, callback in urls:
    match = re.search(regex, path)
    if match is not None:
Python 相关文章推荐
python连接oracle数据库实例
Oct 17 Python
Python利用QQ邮箱发送邮件的实现方法(分享)
Jun 09 Python
在Python中执行系统命令的方法示例详解
Sep 14 Python
Python3处理HTTP请求的实例
May 10 Python
python 统计数组中元素出现次数并进行排序的实例
Jul 02 Python
Python切片操作深入详解
Jul 27 Python
对Python闭包与延迟绑定的方法详解
Jan 07 Python
解决Python正则表达式匹配反斜杠''\''问题
Jul 17 Python
django的csrf实现过程详解
Jul 26 Python
django迁移数据库错误问题解决
Jul 29 Python
python随机生成大小写字母数字混合密码(仅20行代码)
Feb 01 Python
Python list去重且保持原顺序不变的方法
Apr 03 Python
详细解析Python中__init__()方法的高级应用
May 11 #Python
从Python的源码来解析Python下的freeblock
May 11 #Python
详解Python的Django框架中的templates设置
May 11 #Python
Python素数检测的方法
May 11 #Python
Python中IPYTHON入门实例
May 11 #Python
Python使用MONGODB入门实例
May 11 #Python
python学习数据结构实例代码
May 11 #Python
You might like
PHP+MySQL 制作简单的留言本
2009/11/02 PHP
php浏览历史记录的方法
2015/03/10 PHP
PHP实现从远程下载文件的方法
2015/03/12 PHP
php通过淘宝API查询IP地址归属等信息
2015/12/25 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
Ubuntu彻底删除PHP7.0的方法
2018/07/27 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
JS实现文字链接感应鼠标淡入淡出改变颜色的方法
2015/02/26 Javascript
JSON字符串转JSON对象
2015/07/31 Javascript
判断是否存在子节点的实现代码
2016/05/18 Javascript
javascript运算符——逻辑运算符全面解析
2016/06/27 Javascript
详谈$.data()的用法和作用
2017/02/13 Javascript
js css3实现图片拖拽效果
2017/03/04 Javascript
Angular2的管道Pipe的使用方法
2017/11/07 Javascript
深入剖析Express cookie-parser中间件实现示例
2018/02/01 Javascript
一个Vue视频媒体多段裁剪组件的实现示例
2018/08/09 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
2019/02/18 Javascript
JavaScript中的事件与异常捕获详析
2019/02/24 Javascript
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
[43:36]Liquid vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
解析Python中的变量、引用、拷贝和作用域的问题
2015/04/07 Python
Python简单进程锁代码实例
2015/04/27 Python
Python入门_浅谈for循环、while循环
2017/05/16 Python
Python数据可视化编程通过Matplotlib创建散点图代码示例
2017/12/09 Python
Python操作MySQL数据库的方法
2018/06/20 Python
Python日期时间对象转换为字符串的实例
2018/06/22 Python
python中metaclass原理与用法详解
2019/06/25 Python
用CSS3实现瀑布流布局的示例代码
2017/11/10 HTML / CSS
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
大学毕业自我评价
2014/02/02 职场文书
数控技术专业毕业自荐书范文
2014/02/05 职场文书
八一慰问活动方案
2014/02/07 职场文书
CentOS7和8下安装Maven3.8.4
2022/04/07 Servers
使用Python拟合函数曲线
2022/04/14 Python
Oracle数据库事务的开启与结束详解
2022/06/25 Oracle