深入解析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 contextlib模块使用示例
Feb 18 Python
Python中的descriptor描述器简明使用指南
Jun 02 Python
python数据结构之链表的实例讲解
Jul 25 Python
Python的numpy库中将矩阵转换为列表等函数的方法
Apr 04 Python
解决pycharm每次新建项目都要重新安装一些第三方库的问题
Jan 17 Python
利用ctypes获取numpy数组的指针方法
Feb 12 Python
Python matplotlib学习笔记之坐标轴范围
Jun 28 Python
Python math库 ln(x)运算的实现及原理
Jul 17 Python
Python Opencv图像处理基本操作代码详解
Aug 31 Python
python实现简单的五子棋游戏
Sep 01 Python
python 如何利用argparse解析命令行参数
Sep 11 Python
Python max函数中key的用法及原理解析
Jun 26 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
VOLVO车载收音机
2021/03/02 无线电
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
一道关于php变量引用的面试题
2010/08/08 PHP
php另类上传图片的方法(PHP用Socket上传图片)
2013/10/30 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
php 实现一个字符串加密解密的函数实例代码
2016/11/01 PHP
JavaScipt基本教程之前言
2008/01/16 Javascript
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
2014/06/23 Javascript
jQuery实现按钮只点击一次后就取消点击事件绑定的方法
2015/06/26 Javascript
js弹出框、对话框、提示框、弹窗实现方法总结(推荐)
2016/05/31 Javascript
Angularjs使用ng-repeat中$even和$odd属性的注意事项
2016/12/31 Javascript
基于hover的用法实例(推荐)
2017/07/04 Javascript
详解离线安装npm包的几种方法
2018/11/25 Javascript
js中!和!!的区别与用法
2020/05/09 Javascript
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
[46:53]Secret vs Liquid 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python中二维阵列的变换实例
2014/10/09 Python
python对html过滤处理的方法
2018/10/21 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
2019/04/09 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
2019/07/22 Python
python3中rank函数的用法
2019/11/27 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
2020/06/04 Python
python 装饰器的实际作用有哪些
2020/09/07 Python
详解CSS3的opacity属性设置透明效果的用法
2016/05/09 HTML / CSS
Marriott国际:万豪国际酒店查询预订
2017/09/25 全球购物
Java基础面试题
2012/11/02 面试题
印刷工程专业应届生求职信
2013/09/29 职场文书
工商企业管理实习自我鉴定
2013/12/04 职场文书
青年文明号服务承诺
2014/03/31 职场文书
关于感恩的演讲稿800字
2014/08/26 职场文书
四风批评与自我批评范文
2014/10/14 职场文书
2016计划生育先进个人事迹材料
2016/02/29 职场文书
canvas 中如何实现物体的框选
2022/08/05 Javascript