wsgi pep333
转自:https://www.aliyun.com/jiaocheng/444966.html?spm=5176.100033.1.11.559a7C
- 摘要:wsgi介绍参考:pep333wsgi有两个interface:server/gateway和application/framework。server会调用一个由app提供的可callable对象。而app怎么提供这个对象给server,就由server决定了。有些server需要app写一个script来创建一个对象给server,有些server就直接根据config或者其它机制来调用这个对象。除了纯粹的server和app,wsgi还可以加入midlleware部件。m
- wsgi介绍
参考:pep 333
wsgi 有两个interface:server/gateway和application/framework。server会调用一个由app提供的可callable 对象。而app怎么提供这个对象给server,就由server决定了。有些server需要app写一个script 来创建一个对象给server,有些server就直接根据config或者其它机制来调用这个对象。
除了纯粹的server和app,wsgi还可以加入midlleware部件。middleware组件对于server就相当于一个app,对于app来说就是个server,可以提供可扩展的api,导航等其它有用的功能。
app
app 就是一个可调用的接受两个参数的对象。它可以是一个函数,一个类,一个带有_call_的对象。app可以多次被server调用。
下面两个是app的例子,一个是函数,一个是类。def simple_app(environ, start_response): """Simplest possible
application object""" status = '200 OK' response_headers =
[('Content-type', 'text/plain')] start_response(status,
response_headers) return ['Hello world!/n']class AppClass:
"""Produce the same output, but using a class (Note: 'AppClass' is
the "application" here, so calling it returns an instance of
'AppClass', which is then the iterable return value of the
"application callable" as required by the spec. If we wanted to
use *instances* of 'AppClass' as application objects instead, we
would have to implement a '__call__' method, which would be invoked
to execute the application, and we would need to create an instance
for use by the server or gateway. """ 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
server每次从client接受一个http请求就调用一次app。为了说明,下面一个简单的调用一个app对象的cgi gateway。但是下面这个例子对于错误处理是不足的,正常情况错误要输出到server log 上。
import os, sysdef run_with_cgi(application): environ =
dict(os.environ.items()) environ['wsgi.input'] = sys.stdin
environ['wsgi.errors'] = sys.stderr environ['wsgi.version']
= (1, 0) environ['wsgi.multithread'] = False
environ['wsgi.multiprocess'] = True environ['wsgi.run_once'] =
True if environ.get('HTTPS', 'off') in ('on', '1'):
environ['wsgi.url_scheme'] = 'https' else:
environ['wsgi.url_scheme'] = 'http' headers_set = [] headers_sent =
[] def write(data): if not headers_set: raise
AssertionError("write() before start_response()") elif not
headers_sent: # Before the first output, send the stored
headers status, response_headers = headers_sent[:] =
headers_set sys.stdout.write('Status: %s/r/n' % status)
for header in response_headers:
sys.stdout.write('%s: %s/r/n' % header)
sys.stdout.write('/r/n') sys.stdout.write(data)
sys.stdout.flush() def start_response(status, response_headers,
exc_info=None): if exc_info: try: if
headers_sent: # Re-raise original exception if
headers sent raise exc_info[0], exc_info[1],
exc_info[2] finally: exc_info = None #
avoid dangling circular ref elif headers_set: raise
AssertionError("Headers already set!") headers_set[:] = [status,
response_headers] return write result = application(environ,
start_response) try: for data in result: if data:
# don't send headers until body appears write(data)
if not headers_sent: write('') # send headers now if
body was empty finally: if hasattr(result, 'close'):
result.close()
middleware
middleware 可以提供如下列几种功能:
- 根据url,把请求转发到不同app处理
- 允许多个app在同一进程使用
- 通过网络中转发请求,实现负载均衡
- 实现内容预处理,例如添加XSL 样式middleware其实对于server就是个app
对于app就是一个server。middlerware可以写得跟app一样接受两个同样的参数,env和start_response,这样middleware就对于server相当于一个app,只要在middleware像server调用app一样再调用app就可以了,而对于app,middleware就相当于server调用它。下面是一个用Joe Strout’s piglatin.py将text/plain的response转化为pig Latin的middleware
from piglatin import piglatinclass LatinIter: """Transform iterated
output to piglatin, if it's okay to do so Note that the "okayness"
can change until the application yields its first non-empty string,
so 'transform_ok' has to be a mutable truth value. """ def
__init__(self, result, transform_ok): if hasattr(result,
'close'): self.close = result.close self._next =
iter(result).next self.transform_ok = transform_ok def
__iter__(self): return self def next(self): if
self.transform_ok: return piglatin(self._next()) else:
return self._next()class Latinator: # by default, don't
transform output transform = False def __init__(self,
application): self.application = application def
__call__(self, environ, start_response): transform_ok = []
def start_latin(status, response_headers, exc_info=None): #
Reset ok flag, in case this is a repeat call del
transform_ok[:] for name, value in response_headers:
if name.lower() == 'content-type' and value == 'text/plain':
transform_ok.append(True) # Strip
content-length if present, else it'll be wrong
response_headers = [(name, value) for name, value
in response_headers if name.lower() !=
'content-length' ] break
write = start_response(status, response_headers, exc_info)
if transform_ok: def write_latin(data):
write(piglatin(data)) return write_latin
else: return write return
LatinIter(self.application(environ, start_latin), transform_ok)# Run
foo_app under a Latinator's control, using the example CGI gatewayfrom
foo_app import foo_apprun_with_cgi(Latinator(foo_app))
细节说明
app必须是接受两个参数,environ和start_response(参数名可以另取,就是一定要代入两个参数)
environ是一个类dict的对象,里面包含cgi-style的环境变量。这个对象必须是使用Python内置的dict对象(不能是子对象或其它),而app能根据自身需求修改这个environ。这个dict也必须包含一些wsgi需要的变量和server需要确认的变量。
start_response是一个可以调用的接受两个必须参数和一个可选参数的对象,这三个参数分别是:status,response_header和exc_info。但是参数不一定要取这些名称。app一定可以用这些参数调用start_response。
satus是一种以”999 Message here”字符串形式给出的。response_header是一个以(header_name,
header_value)tuple形式组成的list,用来描述http reaponse
header。可选的exc_info是用来处理错误信息的,错误信息通过exc_info展现给浏览器。start_response一定要返回一个write(body_data)可调用的需要一个参数的对象:一个写进http response body的字符串
当app被server调用的时候,app一定要返回一个可iterable yielding 0或者字符串。这样的app可以通过很多方式去实现,例如返回一个list的字符串或者app写成一个返回字符串的生成器,或者app写成一个可以iterable 的类。
server一定要以unbuffered形式把生成的字符串发送出去后,再去生成另外的。
server一定要把生成的字符串当做是二进制队列。app负责要把所有的字符串转化成对client可读的形式。
如果app返回的iterable有close()方法,那么server在处理完一个请求后一定要调用这个方法,不管这个请求是否正确处理完或者因为错误停止。
最后,server不能直接使用由app提供的iterable中的所有参数,除非参数是指定给server使用的。
environ variables
environ是根据cgi需要的定义的,下面这些参数是一定要提供的,除非他们的值为空。
REQUEST_METHOD
The HTTP request method, such as "GET" or "POST" . This cannot ever be an empty string, and so is always required.
SCRIPT_NAME
The initial portion of the request URL's "path" that corresponds to the
application object, so that the application knows its virtual
"location". This may be an empty string, if the application corresponds
to the "root" of the server.
PATH_INFO
The remainder of the request URL's "path", designating the virtual
"location" of the request's target within the application. This may be
an empty string, if the request URL targets the application root and
does not have a trailing slash.
QUERY_STRING
The portion of the request URL that follows the "?" , if any. May be empty or absent.CONTENT_TYPE
The contents of any Content-Type fields in the HTTP request. May be empty or absent.
CONTENT_LENGTH
The contents of any Content-Length fields in the HTTP request. May be empty or absent.SERVER_NAME , SERVER_PORT
When combined with SCRIPT_NAME and PATH_INFO , these variables can be
used to complete the URL. Note, however, that HTTP_HOST , if present,
should be used in preference to SERVER_NAME for reconstructing the
request URL. See the URL Reconstruction section below for more detail.
SERVER_NAME and SERVER_PORT can never be empty strings, and so are
always required.
SERVER_PROTOCOL
The version of the protocol the client used to send the request.
Typically this will be something like "HTTP/1.0" or "HTTP/1.1" and may
be used by the application to determine how to treat any HTTP request
headers. (This variable should probably be called REQUEST_PROTOCOL ,
since it denotes the protocol used in the request, and is not
necessarily the protocol that will be used in the server's response.
However, for compatibility with CGI we have to keep the existing name.)
HTTP_ Variables
Variables corresponding to the client-supplied HTTP request headers
(i.e., variables whose names begin with “HTTP_” ). The presence or
absence of these variables should correspond with the presence or
absence of the appropriate HTTP header in the request.
除了要提供cgi需要的参数,另外还有一些系统的环境变量和一些wsgi需要的参数也要包含在里面。
Variable Value wsgi.version wsgi.version The tuple (1, 0) , representing WSGI version 1.0. wsgi.url_scheme A string representing the “scheme” portion of the URL at which
the application is being invoked. Normally, this will have the value
“http” or “https” , as appropriate.wsgi.input An input stream (file-like object) from which the HTTP request
body can be read. (The server or gateway may perform reads on-demand as
requested by the application, or it may pre- read the client’s request
body and buffer it in-memory or on disk, or use any other technique for
providing such an input stream, according to its preference.)wsgi.errors An output stream (file-like object) to which error output can be
written, for the purpose of recording program or other errors in a
standardized and possibly centralized location. This should be a “text
mode” stream; i.e., applications should use “/n” as a line ending, and
assume that it will be converted to the correct line ending by the
server/gateway.For many servers, wsgi.errors will be the server’s main
error log. Alternatively, this may be sys.stderr , or a log file of some
sort. The server’s documentation should include an explanation of how
to configure this or where to find the recorded output. A server or
gateway may supply different error streams to different applications, if
this is desired.wsgi.multithread This value should evaluate true if the application object may be
simultaneously invoked by another thread in the same process, and should
evaluate false otherwise.wsgi.multiprocess This value should evaluate true if an equivalent application
object may be simultaneously invoked by another process, and should
evaluate false otherwise.wsgi.run_once This value should evaluate true if the server or gateway expects
(but does not guarantee!) that the application will only be invoked this
one time during the life of its containing process. Normally, this will
only be true for a gateway based on CGI (or something similar).
wsgi pep333的更多相关文章
- python wsgi PEP333 中文翻译
PEP 333 中文翻译 首先说明一下,本人不是专门翻译的,英文水平也不敢拿来献丑.只是这是两年前用python的时候为了自己学习方便而翻译的,记录着笔记自己看看而已.最近翻出来看看觉得还是放出来吧. ...
- python wsgi 简介
wsgi全称是"Web Server Gateway Interfacfe",web服务器网关接口,wsgi在python2.5中加入,是web服务器和web应用的标准接口,任何实 ...
- Python——eventlet.wsgi
eventlet 的 wsgi 模块提供了一种启动事件驱动的WSGI服务器的简洁手段,可以将其作为某个应用的嵌入web服务器,或作为成熟的web服务器,一个这样的web服务器的例子就是 Spawnin ...
- uwsgi/uWSGI/WSGI简介
参考文章 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换.z WSGI是一种Web服务器网 ...
- Python WSGI v1.0 中文版(转)
add by zhj: WSGI全称Web Server Gateway Interface,即Web网关接口.其实它并不是OSI七层协议中的协议,它就是一个接口而已,即函数,而WSGI规定了该接口的 ...
- Python的Web编程[1] -> Web服务器[0] -> Web 服务器与 CGI / WSGI
Web服务器 / Web Server 对于Web来说,需要建立一个Web服务器,必须建立一个基本的服务器和一个处理程序, 基本服务器的主要作用是,在客户端和服务器端完成必要的HTTP交互, 处理程序 ...
- Nginx、WSGI、 uWSGI、 uwsgi的区别
当我们部署完一个应用程序,浏览网页时具体的过程是怎样的呢?首先我们得有一个 Web 服务器来处理 HTTP 协议的内容,Web 服务器获得客户端的请求,交给应用程序,应用程序处理完,返回给 Web 服 ...
- python nginx+uwsgi+WSGI 处理请求详解
https://blog.csdn.net/a519640026/article/details/76157976 请求从 Nginx 到 uwsgi 到 django 交互概览 作为python w ...
- [原]Paste.deploy 与 WSGI, keystone 小记
Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...
随机推荐
- Hyper-V 虚拟机无法上网的解决方法
创建一个虚拟机网络交换机 2 创建一个 外部网络如下图所示: 3 添加一个旧版的网络适配器: 4 设置旧版网络适配器: END XP系统的情况 1 启动虚拟机,设置虚拟机IP: 2 输入http:// ...
- 多线程-join()方法
在很多情况下,主进程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据 ...
- atitit.jndi的架构与原理以及资源配置and单元测试实践
atitit.jndi的架构与原理以及资源配置and单元测试实践 1. jndi架构 1 2. jndi实现原理 3 3. jndi资源配置 3 3.1. resin <database> ...
- linux下时间操作1
本文是对我之前写的文章:C++时间操作 的更深入补充.之前那个文章就是一个快速入门的东西,后面力图把一些更深入的细节补充完整. 时间分类的基本介绍 在介绍一些时间相关的操作函数之前,先来介绍一下lin ...
- HDU 1358 Period(kmp简单解决)
Period Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- DataBinding 笔记
DataBinding 笔记 android DataBinding notes 那些年踩过的坑 问题 那些年踩过的坑 非 public 类型的变量,getter 方法必须有,没有就会报错:Could ...
- curl myip.ipip.net curl ip.cn curl cip.cc
[命令行] curl查询公网出口IP 2016年07月22日 14:27:02 阅读数:19022 不管是在家里还是办公室,或者是公司的主机,很多时候都是在内网中,也就是说很多都是通过 NAT上网的, ...
- Windows的静态库使用步骤
windows库程序: 1.静态库程序 - 运行时不独立存在,会被链接到可执行文件或者动态库中,目标程序的归档. 文件扩展名:LIB 2.动态库程序 - 运行时独立存在,不会被链接到可执行文件或其他动 ...
- 图像处理之优化---任意半径局部直方图类算法在PC中快速实现的框架
在图像处理中,局部算法一般来说,在很大程度上会获得比全局算法更为好的效果,因为他考虑到了图像领域像素的信息,而很多局部算法可以借助于直方图获得加速.同时,一些常规的算法,比如中值滤波.最大值滤波.最小 ...
- MFC中CString转换成char数组的问题
由于结构体中用到联合体(联合体需要确定分配内存分配大小)或其它因素,需要用char数组来保存字符串,但是在MFC中一般都是用CString来存放字条串.关于它们之间的转换,在VS2008中有时会出现异 ...