深入解析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中的list列表及其切片和迭代操作
Mar 13 Python
python脚本监控docker容器
Apr 27 Python
Python生成8位随机字符串的方法分析
Dec 05 Python
Python利用openpyxl库遍历Sheet的实例
May 03 Python
python2 与 pyhton3的输入语句写法小结
Sep 10 Python
django中瀑布流写法实例代码
Oct 14 Python
Python常用模块sys,os,time,random功能与用法实例分析
Jan 07 Python
Python tcp传输代码实例解析
Mar 18 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
Apr 22 Python
Python pip安装模块提示错误解决方案
May 22 Python
python爬虫框架feapde的使用简介
Apr 20 Python
pandas提升计算效率的一些方法汇总
May 30 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在字符串中查找指定字符串并删除的代码
2008/10/02 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
laravel通用化的CURD的实现
2019/12/13 PHP
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
Javascript中定义方法的另类写法(批量定义js对象的方法)
2011/02/25 Javascript
JS.getTextContent(element,preformatted)使用介绍
2013/09/21 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
JavaScript获取XML数据附示例截图
2014/03/05 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
JavaScript的函数式编程基础指南
2016/03/19 Javascript
详解JavaScript的另类写法
2016/04/11 Javascript
两种方法解决javascript url post 特殊字符转义 + & #
2016/04/13 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
jquery实现动态创建form并提交的方法示例
2019/05/27 jQuery
详解ng-alain动态表单SF表单项设置必填和正则校验
2019/06/11 Javascript
Nodejs libuv运行原理详解
2019/08/21 NodeJs
python实现数据图表
2017/07/29 Python
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
PyQt5每天必学之布局管理
2018/04/19 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
Python学习笔记之字符串和字符串方法实例详解
2019/08/22 Python
Python SELENIUM上传文件或图片实现过程
2019/10/28 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
K近邻法(KNN)相关知识总结以及如何用python实现
2021/01/28 Python
用canvas显示验证码的实现
2020/04/10 HTML / CSS
会计与审计专业大专生求职信
2013/10/03 职场文书
法律进机关实施方案
2014/03/12 职场文书
竞聘书格式及范文
2014/03/31 职场文书
老公保证书范文
2014/04/29 职场文书
城管综合整治方案
2014/05/01 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
《圆明园的毁灭》教学反思
2016/02/16 职场文书
JavaWeb实现显示mysql数据库数据
2022/03/19 Java/Android
JS轻量级函数式编程实现XDM三
2022/06/16 Javascript
MySql按时,天,周,月进行数据统计
2022/08/14 MySQL