深入解析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 制作图片转pdf工具
Jan 30 Python
python处理csv中的空值方法
Jun 22 Python
Python socket套接字实现C/S模式远程命令执行功能案例
Jul 06 Python
python生成九宫格图片
Nov 19 Python
Linux 修改Python命令的方法示例
Dec 03 Python
Python文件读写常见用法总结
Feb 22 Python
Python XlsxWriter模块Chart类用法实例分析
Mar 11 Python
Python实用工具FuckIt.py介绍
Jul 02 Python
PyTorch加载预训练模型实例(pretrained)
Jan 17 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
May 18 Python
Python通过fnmatch模块实现文件名匹配
Sep 30 Python
Python Django 后台管理之后台模型属性详解
Apr 25 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开发大型项目的一点经验
2006/10/09 PHP
php图片验证码代码
2008/03/27 PHP
使用Limit参数优化MySQL查询的方法
2008/11/12 PHP
PHP 巧用数组降低程序的时间复杂度
2010/01/01 PHP
php eval函数用法总结
2012/10/31 PHP
Laravel 5框架学习之用户认证
2015/04/09 PHP
利用PHP生成CSV文件简单示例
2016/12/21 PHP
PHP利用DWZ.CN服务生成短网址
2019/08/11 PHP
Javascript 获取滚动条位置等信息的函数
2009/09/08 Javascript
谷歌浏览器不支持showModalDialog模态对话框的解决方法
2014/09/22 Javascript
兼容主流浏览器的jQuery+CSS 实现遮罩层的简单代码
2014/10/14 Javascript
javascript实现将文件保存到本地方法汇总
2015/07/26 Javascript
JavaScript自定义函数实现查找两个字符串最长公共子串的方法
2016/11/24 Javascript
jQuery Validate设置onkeyup验证的实例代码
2016/12/09 Javascript
详解Vue.js搭建路由报错 router.map is not a function
2017/06/27 Javascript
纯js实现画一棵树的示例
2017/09/05 Javascript
浅谈angular2路由预加载策略
2017/10/04 Javascript
React操作真实DOM实现动态吸底部的示例
2017/10/23 Javascript
JS获取并处理php数组的方法实例分析
2018/09/04 Javascript
详解vue.js移动端配置flexible.js及注意事项
2019/04/10 Javascript
Angular value与ngValue区别详解
2019/11/27 Javascript
JavaScript自定义超时API代码实例
2020/04/30 Javascript
解决ant Design中Select设置initialValue时的大坑
2020/10/29 Javascript
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
python实现本地批量ping多个IP的方法示例
2019/08/07 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
如何用Python输出一个Fibonacci数列
2016/08/28 面试题
采购文员岗位职责
2013/11/20 职场文书
小学安全教育材料
2014/02/17 职场文书
文案策划专业自荐信
2014/07/07 职场文书
初二英语教学反思
2016/02/15 职场文书
2016年小学圣诞节活动总结
2016/03/31 职场文书
简历自我评价范文
2019/04/24 职场文书
闭幕词的写作格式与范文!
2019/06/24 职场文书
GoLang中生成UUID唯一标识的实现
2021/05/08 Golang