Python-WSGI接口
Python WSGI规定了Web服务器和Python Web应用程序或Web框架之间的标准接口,主要是为了促进Web应用程序在各种Web服务器上的可移植性。
上述这句话翻译自Python官方的PEP333标准:PEP 333 – Python Web Server Gateway Interface v1.0
WSGI接口概述
WSGI的含义:Web Server Gateway Interface(Web服务器网管接口)。
WSGI接口包含两方面:server/gateway端 及 application/framework端。后面直接使用server和application来说明,不再使用gateway和framework。server端直接调用application端提供的可调用对象。另外在server和application之间还可以有一种称作middleware的中间件。中间件对于server来说就是一个application,但是对于application来说中间件却是一个server。
上述可调用对象是指:函数、方法、类或者带有__call__
方法的实例。
以下分别介绍application端,Server端和middleware三个部分
Application端
函数、方法、类及带有callable方法的实例等可调用对象都可以作为application对象。application对象接受两个参数并且可以被多次调用。
参数
- environ:environ参数是一个字典对象,该对象必须是内置的Python字典,应用程序可以任意修改该字典。字典还必须包含某些WSGI必需的变量。
- start_response:由server提供的回调函数,其作用是由application将状态码和响应头返回给server。这个函数有两个必需的位置参数和一个可选参数,三个参数分别为status,response_headers和exc_info
start_response的三个参数的意义如下:
- status:HTTP 响应码及消息,例如status = ‘200 OK’
- response_headers:提供给客户端的响应头,需要封装成list of tuple pairs 的形式
response_headers = [('Content-Type', 'text/plain'), ('Content-Length', str(len(response_body)))]
- exc_info:Python sys.exc_info()元组
返回值
application对象必须返回一个响应体,响应体的形式是list of str,也就是说返回值是由一个或多个字符串组成的列表。
以下是一个函数作为application对象的例子
def simple_app(environ, start_response):
"""最简单的application对象"""
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return ['Hello world!n']
以下是一个类作为application对象的例子
class AppClass:
"""
AppClass()会返回一个AppClass类对象作为application,然后在迭代的时候就会调用__iter__方法,然后就可以产生相同的输出。
如果我们也可以实现__call__方法直接将实例当做application
"""
def __init__(self, environ, start_response):
self.environ = environ
self.start = start_response
def __iter__(self):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
self.start(status, response_headers)
yield "Hello world!n"
Server端
WSGI server必须要调用application,而且要使用位置参数的形式调用application。同时,从application的协议要求可知:
- WSGI server必须向application提供环境参数,因此,自身也必须能够获取环境参数。
- WSGI server接收application的返回值作为响应体。
最简单的WSGI server为Python自带的wsgiref.simple_server。
代码
from wsgiref.simple_server import make_server
server = make_server('localhost', 8080, application)
server.serve_forever()
Middleware
中间件位于WSGI server和WSGI application之间,关于中间件的部分代码参考:
代码如下
from wsgiref.simple_server import make_server
def application(environ, start_response):
response_body = 'hello world!'
status = '200 OK'
response_headers = [
('Content-Type', 'text/plain'),
('Content-Length', str(len(response_body)))
]
start_response(status, response_headers)
return [response_body]
# 中间件
class Upperware:
def __init__(self, app):
self.wrapped_app = app
def __call__(self, environ, start_response):
for data in self.wrapped_app(environ, start_response):
yield data.upper()
wrapped_app = Upperware(application)
httpd = make_server('localhost', 8051, wrapped_app)
httpd.serve_forever()
print 'end'
- 【sklearn机器学习】——应用机器学习的建议
- BFC用途总结
- Android安装包相关知识汇总
- 【独家】手把手教线性回归分析(附R语言实例)
- 四两拨千斤:借助Spark GraphX将QQ千亿关系链计算提速20倍
- 仿微信聊天表情发送
- ASP.NET Web API对OData的支持
- 小技巧 - 简化你的泛型API
- 优化OEA中的聚合SQL
- Universal Image Loader for Android 使用实例
- 如何从 Ring Buffer 读取?
- OEA中的AutoUI重构(1) - Command自动生成
- 开源项目Universal Image Loader for Android
- android Universal Image Loader for Android 说明文档 (1)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android开发之背景动画简单实现方法
- 15.深入k8s:Event事件处理及其源码分析
- 说一说 HashMap 底层数据结构
- 详解Android Service 使用时的注意事项
- Android自定义View实现QQ运动积分转盘抽奖功能
- 请简述Spring JDBC是如何进行配置的
- Java高频面试题 -- 静态
- 2020Java核心面试题--基础题
- 一日一技:在网页上如何获取鼠标当前指向的元素
- B树和B+树
- 根据CCDS数据库信息拿到全部外显子坐标
- 查找算法其实不简单
- 一日一技:如何防止 Homebrew 自动升级和自动清理过期程序
- 吐血整理--史上最全排序算法Python实现
- 2020数据库最新面试题常考汇总