深入解析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的Bottle框架写一个简单的服务接口的示例
Aug 25 Python
vue.js实现输入框输入值内容实时响应变化示例
Jul 07 Python
python 实现图片旋转 上下左右 180度旋转的示例
Jan 24 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
Feb 13 Python
Python实现账号密码输错三次即锁定功能简单示例
Mar 29 Python
使用Python计算玩彩票赢钱概率
Jun 26 Python
Python爬虫 bilibili视频弹幕提取过程详解
Jul 31 Python
python matplotlib如何给图中的点加标签
Nov 14 Python
Python跑循环时内存泄露的解决方法
Jan 13 Python
keras 指定程序在某块卡上训练实例
Jun 22 Python
python爬虫利用代理池更换IP的方法步骤
Feb 21 Python
python 标准库原理与用法详解之os.path篇
Oct 24 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实现多张图片上传加水印技巧
2013/04/18 PHP
浅析PHP的ASCII码转换类
2013/07/05 PHP
PHP微信开发之根据用户回复关键词\位置返回附近信息
2016/06/24 PHP
javaScript 页面自动加载事件详解
2014/02/10 Javascript
JQuery 使用attr方法实现下拉列表选中
2014/10/13 Javascript
Bootstrap每天必学之进度条
2015/11/30 Javascript
JavaScript基础语法之js表达式
2016/06/07 Javascript
React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)
2017/07/11 Javascript
基于js 各种排序方法和sort方法的区别(详解)
2018/01/03 Javascript
Vue如何实现响应式系统
2018/07/11 Javascript
基于Vue+element-ui 的Table二次封装的实现
2018/07/20 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
vue中v-show和v-if的异同及v-show用法
2019/06/06 Javascript
利用js实现简易红绿灯
2020/10/15 Javascript
[01:05:59]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
数据挖掘之Apriori算法详解和Python实现代码分享
2014/11/07 Python
简介Python的collections模块中defaultdict类型的用法
2016/07/07 Python
Python处理PDF及生成多层PDF实例代码
2017/04/24 Python
Python实现基于二叉树存储结构的堆排序算法示例
2017/12/08 Python
Python操作MySQL模拟银行转账
2018/03/12 Python
python简单贪吃蛇开发
2019/01/28 Python
Python3实现的旋转矩阵图像算法示例
2019/04/03 Python
python添加菜单图文讲解
2019/06/04 Python
python 消费 kafka 数据教程
2019/12/21 Python
python异常处理try except过程解析
2020/02/03 Python
python GUI库图形界面开发之PyQt5拖放控件实例详解
2020/02/25 Python
python与js主要区别点总结
2020/09/13 Python
使用pandas实现筛选出指定列值所对应的行
2020/12/13 Python
Appium+Python实现简单的自动化登录测试的实现
2021/01/26 Python
检察官就职演讲稿
2014/01/13 职场文书
"9.18"国耻日演讲稿范文
2014/09/14 职场文书
单位作风建设自查报告
2014/10/23 职场文书
生死牛玉儒观后感
2015/06/11 职场文书
植树节新闻稿
2015/07/17 职场文书
《红领巾真好》教学反思
2016/02/16 职场文书
mysql中整数数据类型tinyint详解
2021/12/06 MySQL