深入解析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使用htpasswd实现基本认证授权的例子
Jun 10 Python
Python实现统计单词出现的个数
May 28 Python
python从入门到精通(DAY 1)
Dec 20 Python
Python利用前序和中序遍历结果重建二叉树的方法
Apr 27 Python
python基于pyDes库实现des加密的方法
Apr 29 Python
Python的Tkinter点击按钮触发事件的例子
Jul 19 Python
python实现倒计时小工具
Jul 29 Python
如何为Python终端提供持久性历史记录
Sep 03 Python
python实现替换word中的关键文字(使用通配符)
Feb 13 Python
python pyqtgraph 保存图片到本地的实例
Mar 14 Python
Android Q之气泡弹窗的实现示例
Jun 23 Python
Pandas搭配lambda组合使用详解
Jan 22 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
无数据库的详细域名查询程序PHP版(5)
2006/10/09 PHP
php 远程关机操作的代码
2008/12/05 PHP
PHP检测用户语言的方法
2015/06/15 PHP
定时器(setTimeout/setInterval)调用带参函数失效解决方法
2013/03/26 Javascript
JS实现局部选择打印和局部不选择打印
2014/04/03 Javascript
JavaScript正则表达式之multiline属性的应用
2015/06/16 Javascript
基于JavaScript代码实现微信扫一扫下载APP
2015/12/30 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
2016/06/23 Javascript
微信小程序 数据访问实例详解
2016/10/08 Javascript
DOM 事件的深入浅出(二)
2016/12/05 Javascript
微信小程序 template模板详解及实例
2017/02/21 Javascript
使用OPENLAYERS3实现点选的方法
2020/09/24 Javascript
使用vue + less 实现简单换肤功能的示例
2018/02/21 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
JavaScript类型相关的常用操作总结
2019/02/14 Javascript
详解jQuery-each()方法
2019/03/13 jQuery
在 Vue 中编写 SVG 图标组件的方法
2020/02/24 Javascript
vue 授权获取微信openId操作
2020/11/13 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
2018年Python值得关注的开源库、工具和开发者(总结篇)
2018/01/04 Python
对numpy数据写入文件的方法讲解
2018/07/09 Python
pandas修改DataFrame列名的实现方法
2019/02/22 Python
django为Form生成的label标签添加class方式
2020/05/20 Python
大学毕业感言50字
2014/02/07 职场文书
《海伦?凯勒》教学反思
2014/04/17 职场文书
拾金不昧感谢信范文
2015/01/21 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
领导欢送会主持词
2015/07/06 职场文书
学校食堂管理制度
2015/08/04 职场文书
《黄山奇石》教学反思
2016/02/18 职场文书
公司开业的祝贺语大全(60条)
2019/07/05 职场文书
HTTP中的Content-type详解
2022/01/18 HTML / CSS
一文了解MySQL二级索引的查询过程
2022/02/24 MySQL