WSGI简介

来源:互联网 发布:战斗数据预测数据库 编辑:程序博客网 时间:2024/06/05 21:12

RESTful只是设计风格而不是标准,Web服务中通常使用基于HTTP的符合RESTful风格的API。而WSGI(Web Server Gateway Interface, Web服务器网关接口)则是Python语言中所定义的Web服务器和Web应用程序或框架之间的通用接口标准。

从名称上看,WSGI是一个网关,作用就是在协议之间进行转换。换句话说,WSGI就是一座桥梁,桥梁的一端称为服务端或者网关端,另一端称为应用端或者框架端。当处理一个WSGI请求时,服务端为应用端提供上下文信息和一个回调函数,应用端处理完请求后,使用服务端所提供的回调函数返回相对应请求的响应。

作为一个桥梁,WSGI将Web组件分成了三类:Web服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。WSGI Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

WSGI Application是一个可被调用的(Callable)Python对象,它接受两个参数,通常为 environstart_response。比如:

def application(environ, start_response):    start_response('200 OK', [('Content-Type', 'text/plain')])

参数 environ 指向一个Python字典(Context),要求里面至少包含了一些在CGI(通用网关接口规范)中定义的环境变量,比如 REQUEST_METHOD、SCRIPT_NAME、PATH_INFO、QUERY_STRING等。除此之外,environ 里面还至少要包含其他7个WSGI所定义的环境变量,比如wsgi.version、wsgi_input、wsgi.url_scheme 等。WSGI应用可以从 environ 字典中获取相对应的请求及其执行上下文的所有信息。

参数start_response 指向一个回调函数,形如:

start_response(status, response_headers, exc_info=None)

status 参数是一个形如“999 Message here”的表示响应状态的字符串;response_headers参数是一个包含了(header_name, header_value)元组的列表,分别表示HTTP响应中的TTP头及其内容;exec_info一般在出现错误的时候使用,用来让浏览器显示相关错误信息。

参数start_response所指向的这个回调函数需要返回另一个形如write(body_data)的可被调用对象。这个write对象是为了兼容现有的一些特殊框架设计的,一般情况下不使用。

有请求来到时,WSGI Server会准备好environ和start_response参数,然后调用WSGI Application获得对应请求的响应。如下是一个WSGI服务端调用应用端的例子:

def call_application(app, environ):    body = []    status_headers = [None, None]    #定义start_response 回调函数    def start_response(status, headers):        status_headers[:] = [status, headers]        return body.append(status_deaders)    #调用WSGI应用端    app_iter = app(environ, start_response)    try:        for item in app_iter:            body.append(item)        finally:            if hasattr(app_iter, 'close'):                app_iter.close()        return status_headers[0], status_headers[1], ''.join(body)#准备environ环境变量,假设CGI相关变量已经在操作系统的上下文中。environ = os.environ.items()environ['wsgi.input'] = sys.stdin.bufferenviron['wsgi.errors'] = sys.stderrenviron['wsgi.version'] = (1, 0)environ['wsgi.multithread'] = Falseenviron['wsgi.multiprocess'] = Trueenviron['wsgi.run_once'] = Trueif environ.get('HTTPS', 'off') in ('on', '1'):    environ['wsgi.url_scheme'] = 'https'else:    environ['wsgi.url_scheme'] = 'http'status, headers, body = call_application(application, environ)

WSGI中间件同时实现了服务端和应用端的API,因此可以在两端之间起协调作用。从服务端看起来,中间件就是一个WSGI应用;从应用端看起来,中间件则是一个WSGI服务器。

WSGI中间件可以将客户端的HTTP请求,路由给不同的应用对象,然后将应用处理后的结果返回给客户端。

我们也可以将WSGI中间件理解为服务端和应用端交互的一层包装,经过不同中间件的包装,便具有不同的功能,比如URL路由分发,再比如权限认证。这些不同中间件的组合便形成了WSGI的框架,比如Paste。

0 0