深入解析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通过yield实现数组全排列的方法
Mar 18 Python
用Python的线程来解决生产者消费问题的示例
Apr 02 Python
python 产生token及token验证的方法
Dec 26 Python
如何为Python终端提供持久性历史记录
Sep 03 Python
python中有关时间日期格式转换问题
Dec 25 Python
postman和python mock测试过程图解
Feb 22 Python
在python里创建一个任务(Task)实例
Apr 25 Python
IntelliJ 中配置 Anaconda的过程图解
Jun 01 Python
Keras 快速解决OOM超内存的问题
Jun 11 Python
python pip如何手动安装二进制包
Sep 30 Python
python 实现批量图片识别并翻译
Nov 02 Python
python RSA加密的示例
Dec 09 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
BBS(php & mysql)完整版(二)
2006/10/09 PHP
PHP迭代器的内部执行过程详解
2013/11/12 PHP
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
PHP实现获取文件后缀名的几种常用方法
2015/08/08 PHP
详解php魔术方法(Magic methods)的使用方法
2016/02/14 PHP
PHP实现的XXTEA加密解密算法示例
2018/08/28 PHP
实例讲解PHP表单验证功能
2019/02/15 PHP
php7新特性的理解和比较总结
2019/04/14 PHP
DOMAssitant最新版 DOMAssistant 2.5发布
2007/12/25 Javascript
jQuery实现长文字部分显示代码
2013/05/13 Javascript
简单实用的反馈表单无刷新提交带验证
2013/11/15 Javascript
JS获取文件大小方法小结
2015/12/08 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
2016/06/02 Javascript
Bootstrap中的Panel和Table全面解析
2016/06/13 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
2020/12/01 Javascript
基于vue.js中事件修饰符.self的用法(详解)
2018/02/23 Javascript
Vue无限滑动周选择日期的组件的示例代码
2018/07/18 Javascript
Electron-vue脚手架改造vue项目的方法
2018/10/22 Javascript
JS module的导出和导入的实现代码
2019/02/25 Javascript
JS实现给数组对象排序的方法分析
2019/06/24 Javascript
Vue formData实现图片上传
2019/08/20 Javascript
vue 实现图片懒加载功能
2020/12/31 Vue.js
JS canvas实现画板和签字板功能
2021/02/23 Javascript
[01:30]2016国际邀请赛中国区预选赛神秘商店火爆开启
2016/06/26 DOTA
python三元运算符实现方法
2013/12/17 Python
python多进程和多线程究竟谁更快(详解)
2017/05/29 Python
Python常见异常分类与处理方法
2017/06/04 Python
通过shell+python实现企业微信预警
2019/03/07 Python
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
经典c++面试题四
2015/05/14 面试题
团支书的期末学习总结自我评价
2013/11/01 职场文书
庆八一活动方案
2014/01/25 职场文书
2016年感恩节活动总结大全
2016/04/01 职场文书
创业计划书之熟食店
2019/10/16 职场文书
golang http使用踩过的坑与填坑指南
2021/04/27 Golang