深入解析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 相关文章推荐
Django中传递参数到URLconf的视图函数中的方法
Jul 18 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
Feb 03 Python
python实时监控cpu小工具
Jun 21 Python
python调用pyaudio使用麦克风录制wav声音文件的教程
Jun 26 Python
Python PyCharm如何进行断点调试
Jul 05 Python
Django使用Jinja2模板引擎的示例代码
Aug 09 Python
python采集百度搜索结果带有特定URL的链接代码实例
Aug 30 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
Dec 04 Python
python求一个字符串的所有排列的实现方法
Feb 04 Python
jupyter note 实现将数据保存为word
Apr 14 Python
Django多层嵌套ManyToMany字段ORM操作详解
May 19 Python
keras 使用Lambda 快速新建层 添加多个参数操作
Jun 10 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学习笔记 数组遍历实现代码
2011/06/09 PHP
PHP字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
PHP中字符串长度的截取用法示例
2017/01/12 PHP
解决在laravel中auth建立时候遇到的问题
2019/10/15 PHP
javascript 面向对象编程基础:封装
2009/08/21 Javascript
使用CSS3的scale实现网页整体缩放
2014/03/18 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
js中for in语句的用法讲解
2015/04/24 Javascript
JavaScript实现选择框按比例拖拉缩放的方法
2015/08/04 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
微信小程序 增、删、改、查操作实例详解
2017/01/13 Javascript
Nodejs 发送Post请求功能(发短信验证码例子)
2017/02/09 NodeJs
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
使用3D引擎threeJS实现星空粒子移动效果
2020/09/13 Javascript
在小程序中使用canvas的方法示例
2018/09/17 Javascript
vue项目中使用Hbuilder打包app 设置沉浸式状态栏的方法
2018/10/22 Javascript
Vue使用axios出现options请求方法
2019/05/30 Javascript
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
微信小程序后端实现授权登录
2020/02/24 Javascript
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
Python用requests库爬取返回为空的解决办法
2021/02/21 Python
时尚的CSS3进度条效果
2012/02/22 HTML / CSS
周仰杰(JIMMY CHOO)法国官方网站:闻名世界的鞋子品牌
2019/09/27 全球购物
SQL里面IN比较快还是EXISTS比较快
2012/07/19 面试题
体育教育个人自荐信范文
2013/12/01 职场文书
门卫岗位安全职责
2013/12/13 职场文书
学生会主席就职演讲稿
2014/01/14 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
资金主管岗位职责范本
2014/03/04 职场文书
重阳节活动总结
2014/08/27 职场文书
2014国庆节主题活动方案:快乐的国庆节
2014/09/16 职场文书
2014副局长群众路线对照检查材料思想汇报
2014/09/22 职场文书
健康证明
2015/06/19 职场文书
2015秋季幼儿园开学通知
2015/07/16 职场文书
Java反应式框架Reactor中的Mono和Flux
2021/07/25 Java/Android