深入解析Python中的WSGI接口

概述

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:
(0)

相关推荐

  • linux系统使用python监测网络接口获取网络的输入输出

    net.py 获取网络接口的输入和输出 复制代码 代码如下: #!/usr/bin/env Pythonimport timeimport sys if len(sys.argv) > 1: INTERFACE = sys.argv[1]else: INTERFACE = 'eth0'STATS = []print 'Interface:',INTERFACE def rx(): ifstat = open('/proc/net/dev').readlines() for interface i

  • 使用Python的Bottle框架写一个简单的服务接口的示例

    是不是有这么一个场景,对外提供一堆数据或者是要返回给用户一个结果.但是不想把内部的一些数据和逻辑暴露给对方...简单点来说,就是想以服务的方式对外提供一个接口.对于这种有很多处理方式,RPC,搭建一个web服务啥的....但是这些毕竟都太重量级了,操作起来很麻烦.我这里给出的一种非常easy的方式来处理.使用bottle解决问题. 需求: 检查一个zookeeper服务中的某些节点是否存在,如果存在返回OK,不存在则给出不存的节点信息.要求返回的信息是和pyunit的结果信息一致. 实现环境:

  • 在Python的框架中为MySQL实现restful接口的教程

    最近在做游戏服务分层的时候,一直想把mysql的访问独立成一个单独的服务DBGate,原因如下: 请求收拢到DBGate,可以使DBGate变为无状态的,方便横向扩展 当请求量或者存储量变大时,mysql需要做分库分表,DBGate可以内部直接处理,外界无感知 通过restful限制对数据请求的形式,仅支持简单的get/post/patch/put 进行增删改查,并不支持复杂查询.这个也是和游戏业务的特性有关,如果网站等需要复杂查询的业务,对此并不适合 DBGate使用多进程模式,方便控制与my

  • 基于Python的接口测试框架实例

    背景 最近公司在做消息推送,那么自然就会产生很多接口,测试的过程中需要调用接口,我就突然觉得是不是可以自己写一个测试框架? 说干就干,由于现有的接口测试工具Jmeter.SoupUI等学习周期有点长,干脆自己写一个吧,不求人,所有功能自己都能一清二楚. 当然,写工具造轮子只是学习的一种方式,现成成熟的工具肯定比我们自己的写的好用. 开发环境 ------------------------------------------------------------- 操作系统:Mac OS X EI

  • Python+微信接口实现运维报警

    说到运维报警,我觉得都可以写个长篇历史来详细解释了报警的前世来生,比如最早报警都是用邮件,但邮件实时性不高,比如下班回家总不能人一直盯着邮箱吧,所以邮件这种报警方式不适合用来报紧急的故障,日常磁盘利用率监控什么的可以用它来报没问题,网站宕机不能访问这种故障,用它就明显不合适了,那对这种业务稳定性要求比较高的业务,后来就发展成了用短信,就是公司买个短信机,提供一个http接口,然后运维人员写脚本把收集到的异常数据写入文件,然后脚本实时检测如果这个文件不为空,就调用短信机接口把文件里的内容发送出去,

  • 使用python实现接口的方法

    接口基础知识: 简单说下接口测试,现在常用的2种接口就是http api和rpc协议的接口,今天主要说:http api接口是走http协议通过路径来区分调用的方法,请求报文格式都是key-value形式,返回报文一般是json串: 接口协议:http.webservice.rpc等. 请求方式:get.post方式 请求参数格式: a. get请求都是通过url?param=xxx&param1=xxx b. post请求的请求参数常用类型有:application/json.applicat

  • 详解Python程序与服务器连接的WSGI接口

    了解了HTTP协议和HTML文档,我们其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作为HTTP响应的Body发送给浏览器: 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示. 所以,最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回.Apache.Nginx.Lighttpd等这些常见的静态服务器就是干这件事情的. 如果要动

  • 深入解析Python中的WSGI接口

    概述 WSGI接口包含两方面:server/gateway 及 application/framework. server调用由application提供的可调用对象. 另外在server和application之间还可能有一种称作middleware的中间件. 可调用对象是指:函数.方法.类或者带有callable方法的实例. 关于application 函数.方法.类及带有callable方法的实例等可调用对象都可以作为the application object. WSGI协议要求: th

  • 浅析Python 中的 WSGI 接口和 WSGI 服务的运行

    HTTP格式 HTTP GET请求的格式: GET /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3 每个Header一行一个,换行符是\r\n. HTTP POST请求的格式: POST /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3 body data goes here... 当遇到连续两个\r\n时,Header部分结束,后面的数据全部

  • 通过Python中的CGI接口讲解什么是WSGI

    目录 前言 为什么是 WSGI? WSGI 实施概略 1)Application 端 2)Server 端 3) 作为 middleware 其他资源: 前言 今天在 git.oschina 的首页上看到他们推出演示平台,其中,Python 的演示平台支持 WSGI 接口的应用.虽然,这个演示平台连它自己提供的示例都跑不起来,但是,它还是成功的勾起了我对 WSGI 的好奇心.一番了解,对该机制的认识,总结如下.如有不妥,还望斧正. 为什么是 WSGI? 写过网页应用的各位亲,应该对 CGI 有了

  • 解析python 中/ 和 % 和 //(地板除)

    python / 和 % 和 //(地板除)用于对数据进行除法运算. python中 // 和 / 和 % 简介 python中与除法相关的三个运算符是// 和 / 和 %,下面逐一介绍. "/",这是传统的除法,3/2=1.5 "//",在python中,这个叫"地板除",3//2=1 "%",这个是取模操作,也就是区余数,4%2=0,5%2=1 Python中分为3种除法:1./,2.%,3.//. 1./ 基于 pyth

  • python中的mock接口开发示例详解

    什么是mock? mock在翻译过来有模拟的意思.它允许您用模拟对象替换您的系统的部分,并对它们已使用的方式进行断言. Mock通常是指,在测试一个对象时,我们构造一些假的对象来模拟与其交互.而这些Mock对象的行为是我们事先设定且符合预期.通过这些Mock对象来测试对象在正常逻辑,异常逻辑或压力情况下工作是否正常,Mock的行为固定,它确保当你访问该Mock的某个方法时总是能够获得一个没有任何逻辑的直接就返回的预期结果.Mock接口就是用一些合理的手段构造对象去模拟真实接口. import f

  • 源码解析python中randint函数的效率缺陷

    目录 一.前言 二.对randint()运行效率的测试 三.从源码分析randint()的缺陷 random.random() random.randint() 四.更快的生成随机整数的方法 random.random() 直接使用 getrandbits() 使用 Numpy.random 一.前言 前几天,在写一个与差分隐私相关的简单程序时,我发现了一些奇怪的东西:相对于其他的随机数生成函数,Python的random.randint()函数感觉很慢. 由于 randint() 是 Pyth

  • 深入解析Python中的多进程

    目录 前言 1.创建进程 2.多进程中的Queue 3.多进程与多线程的性能比较 4.进程池pool 5.共享内存 6.进程锁lock 前言 现在我们的计算机都是多个核的,通俗来说就是多个处理或者计算单元.为了加快运算和处理速度,我们可以将不同的任务交给多个核心进行同时处理,从而提高了运算速度和效率,多个核心同时运作就是多个进程同时进行,这就是多进程. 1.创建进程 创建进程和创建线程的方法基本一致,请看下面代码: # coding:utf-8 # 导入多进程的包,并重命名为mp import

  • 深入解析Python中的urllib2模块

    Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库.这里总结了一些 urllib2 的使用细节. Proxy 的设置 Timeout 设置 在 HTTP Request 中加入特定的 Header Redirect Cookie 使用 HTTP 的 PUT 和 DELETE 方法 得到 HTTP 的返回码 Debug Log Proxy 的设置 urllib2 默认会使用环境变量 http_proxy

  • 详细解析Python中__init__()方法的高级应用

    通过工厂函数对 __init__() 加以利用 我们可以通过工厂函数来构建一副完整的扑克牌.这会比枚举所有52张扑克牌要好得多,在Python中,我们有如下两种常见的工厂方法: 定义一个函数,该函数会创建所需类的对象. 定义一个类,该类有创建对象的方法.这是一个完整的工厂设计模式,正如设计模式书所描述的那样.在诸如Java这样的语言中,工厂类层次结构是必须的,因为该语言不支持独立的函数. 在Python中,类并不是必须的.只是当有相关的工厂非常复杂的时候才会显现出优势.Python的优势就是当一

  • 深入解析Python中函数的参数与作用域

    传递参数 函数传递参数时的一些简要的关键点: 参数的传递是通过自动将对象赋值给本地变量名来实现的.所有的参数实际上都是通过指针进行传递的,作为参数被传递的对象从来不自动拷贝. 在函数内部的参数名的赋值不会影响调用者. 改变函数的可变对象参数的值会对调用者有影响. 实际上,Python的参数传递模型和C语言的相当相似: 不可变参数"通过值"进行传递.像整数和字符串这样的对象是通过对象引用而不是拷贝进行的,但是因为不论怎么样都不可能在原处改变不可变对象,实际的效果就很像创建了一份拷贝. 可

随机推荐