深入解析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 除法小技巧
Sep 06 Python
快速排序的算法思想及Python版快速排序的实现示例
Jul 02 Python
Python自动化测试ConfigParser模块读写配置文件
Aug 15 Python
简单谈谈Python中的闭包
Nov 30 Python
Python2实现的LED大数字显示效果示例
Sep 04 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
Jan 10 Python
python实现生命游戏的示例代码(Game of Life)
Jan 24 Python
pytorch 共享参数的示例
Aug 17 Python
python实现大学人员管理系统
Oct 25 Python
TensorFLow 变量命名空间实例
Feb 11 Python
Python sorted对list和dict排序
Jun 09 Python
查找适用于matplotlib的中文字体名称与实际文件名对应关系的方法
Jan 05 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 压缩文件夹的类代码
2009/11/05 PHP
一个PHP针对数字的加密解密类
2014/03/20 PHP
PHP中数据库单例模式的实现代码分享
2014/08/21 PHP
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
Smarty环境配置与使用入门教程
2016/05/11 PHP
PHP支付系统设计与典型案例分享
2016/08/02 PHP
PHP面向对象类型约束用法分析
2019/06/12 PHP
使用JQuery进行跨域请求
2010/01/25 Javascript
Mootools 图片展示插件(lightbox,ImageMenu)收集集合
2010/05/21 Javascript
JS声明变量背后的编译原理剖析
2012/12/28 Javascript
confirm的用法示例用于按钮操作时确定是否执行
2014/06/19 Javascript
浅谈jQuery操作类数组的工具方法
2016/12/23 Javascript
React Native 集成jpush-react-native的示例代码
2017/08/16 Javascript
js中Object.defineProperty()方法的不详解
2018/07/09 Javascript
vue拖拽组件使用方法详解
2018/12/01 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
vue接通后端api以及部署到服务器操作
2020/08/13 Javascript
[01:00:04]DOTA2上海特级锦标赛B组小组赛#1 Alliance VS Spirit第二局
2016/02/26 DOTA
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
Python中的Descriptor描述符学习教程
2016/06/02 Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
2017/09/18 Python
python 对txt中每行内容进行批量替换的方法
2018/07/11 Python
简单了解python变量的作用域
2019/07/30 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
2019/12/20 Python
python add_argument()用法解析
2020/01/29 Python
python 密码学示例——理解哈希(Hash)算法
2020/09/21 Python
英国顶级足球鞋的领先零售商:Lovell Soccer
2019/08/27 全球购物
预备党员入党思想汇报
2014/01/04 职场文书
给男朋友的道歉信
2014/01/12 职场文书
老师给学生的表扬信
2014/01/17 职场文书
优秀医生事迹材料
2014/02/12 职场文书
公司领导班子四风对照检查材料
2014/09/27 职场文书
教师拔河比赛广播稿
2014/10/14 职场文书
贷款担保书范本
2015/09/22 职场文书
(开源)微信小程序+mqtt,esp8266温湿度读取
2021/04/02 Javascript