打印
[嵌入式linux]

Python Web Server Gateway Interface v1.0(WSGI )

[复制链接]
3182|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sinanjj|  楼主 | 2010-8-24 18:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sinanjj 于 2010-8-25 00:00 编辑

原文: http://www.python.org/dev/peps/pep-0333/

Specification Overview
The WSGI interface has two sides: the "server" or "gateway" side, andthe "application" or "framework" side.  The server side invokes acallable object that is provided by the application side.  Thespecifics of how that object is provided are up to the server orgateway.  It is assumed that some servers or gateways will require anapplication's deployer to write a short script to create an instanceof the server or gateway, and supply it with the application object.Other servers and gateways may use configuration files or othermechanisms to specify where an application object should beimported from, or otherwise obtained.

标准综述
WSGI 接口描述了server/gateway(web服务器)和application/framework(web开发框架)两者之间的通讯.

In addition to "pure" servers/gateways and applications/frameworks,it is also possible to create "middleware" components that implementboth sides of this specification.  Such components act as anapplication to their containing server, and as a server to acontained application, and can be used to provide extended APIs,content transformation, navigation, and other useful functions.
可以用中间件来做接口中转

Throughout this specification, we will use the term "a callable" tomean "a function, method, class, or an instance with a __call__method".  It is up to the server, gateway, or application implementingthe callable to choose the appropriate implementation technique fortheir needs.  Conversely, a server, gateway, or application that isinvoking a callable must not have any dependency on what kind ofcallable was provided to it.  Callables are only to be called, notintrospected upon.
在这个标准中, 我们用"一个可调用函数"来指代python中的函数/方法/类/拥有__call__方法的实例.

The Application/Framework Side
The application object is simply a callable object that accepts two arguments.  The term "object" should not be misconstrued asrequiring an actual object instance: a function, method, class,or instance with a __call__ method are all acceptable foruse as an application object.  Application objects must be able to be invoked more than once, as virtually all servers/gateways(other than CGI) will make such repeated requests.

web开发框架端接口
应用程序就是一个接受两个参数的可调用的对象. 这里的应用程序就是指一个url的处理函数/方法/类/有__call__方法的实例.


Here are two example application objects; one is a function, and theother is a class:
下边是两个例子(一个是函数, 一个是类):

def simple_app(environ, start_response): # 声明一个函数. 函数有两个参数, 一个是environ, 一个是start_respons,
    """Simplest possible application object""" # 最简单的wsgi标准调用
    status = '200 OK'                                   # 将"200 OK" 字符串放入status.
    response_headers = [('Content-type','text/plain')] #序列里放了个元组, 然后赋值给response_headers
    start_response(status, response_headers) # 此句说明1, start_response是个函数. 2, 这个函数有两个参数, 一个是status, 一个是response_headers, 3, status是个字符串. 4, response_headers是个序列, 里边放了元组, 元组的值是http头的返回头.
    return ['Hello world!\n']  # 返回值应该是http 内容
(能定义的这么绕也真不容易啊...)

The Server/Gateway Side
The server or gateway invokes the application callable once for eachrequest it receives from an HTTP client, that is directed at theapplication.  To illustrate, here is a simple CGI gateway, implementedas a function taking an application object.  Note that this simpleexample has limited error handling, because by default an uncaughtexception will be dumped to sys.stderr and logged by the webserver.

web服务器端
web服务器每收到一次http请求就调用一次可调用函数. 为了解释, 这里有一个简单的CGI网关.

import os, sys                            # 包含库
def run_with_cgi(application):    # 定义这个函数, 参数是application
    environ = dict(os.environ.items()) # 当前系统环境变量字典形式放入environ变量
    environ['wsgi.input']  = sys.stdin  # 增加environ字典键值
    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'): #如果键"HTTPS"值为"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()

(插入
python函数调用另一个函数的函数名做参数有什么意义?
函数也是对象,这样的好象就是可以做一个通用的框架。比如根据不同的内容调用不同的函数,可以把条件与函数存成一个对照表,然后动态查找函数进行调用。

最常见的就是做web,一个请求上来,webserver自动分析url,然后找到对应的函数进行调用。那么这一过程一般是有一个调度程序来完成,比如:
def login():pass
def **ut():pass
controllers = {
    '/login/': login,
    '/**ut/':**ut,
}
def dispatcher(url, controllers):
    func = controllers.get(url)
    if func:
        func()
    else:
        response('Wrong url!')
)





相关帖子

沙发
sinanjj|  楼主 | 2010-8-24 21:17 | 只看该作者
本帖最后由 sinanjj 于 2010-8-24 23:09 编辑

Specification Details
The application object must accept two positional arguments. For the sake of illustration, we have named them environ and start_response, but they are not required to have these names. A server or gateway must invoke the application object using positional (not keyword) arguments. (E.g. by calling result = application(environ,start_response) as shown above.)

标准细节
web开发框架调用的函数必须包含两个参数, 为了方便解释, 我们这里命名为 environ和start_response. webserver软件必须有这两个参数来调用web开发框架函数. (比如: result=application(environ, start_response))


The environ parameter is a dictionary object, containing CGI-style environment variables. This object must be a builtin Python dictionary (not a subclass, UserDict or other dictionary emulation), and the application is allowed to modify the dictionary in any way it desires. The dictionary must also include certain WSGI-required variables (described in a later section), and may also include server-specific extension variables, named according to a convention that will be described below.
enciron 是个字典对象, 必须有cgi的基本信息. 其他信息随便加.

The start_response parameter is a callable accepting two required positional arguments, and one optional argument. For the sake of illustration, we have named these arguments status, response_headers, and exc_info, but they are not required to have these names, and the application must invoke the start_response callable using positional arguments (e.g. start_response(status,response_headers)).
start_reponse 参数是个两个必须参数一个可选参数的函数.为了方便起见, 我命名这几个参数为 status, response_header, exc_info . application 函数(就是web开发框架的调用函数)必须调用这个函数, 并给予2个必须参数, 比如: start_response(status, response_headers)

The status parameter is a status string of the form "999 Message here", and response_headers is a list of (header_name,header_value) tuples describing the HTTP response header. The optional exc_info parameter is described below in the sections on The start_response() Callable and Error Handling. It is used only when the application has trapped an error and is attempting to display an error message to the browser.
status 参数是一个表征状态的字符串, response_headers是一个http回复头信息的元组.
那个可选的exc_info参数会在描述start_response()函数的章节写. 这个参数仅仅用于在浏览器里显示错误信息时用.


The start_response callable must return a write(body_data) callable that takes one positional parameter: a string to be written as part of the HTTP response body. (Note: the write() callable is provided only to support certain existing frameworks' imperative output APIs; it should not be used by new applications or frameworks if it can be avoided. See the Buffering and Streaming section for more details.)



When called by the server, the application object must return an iterable yielding zero or more strings. This can be accomplished in a variety of ways, such as by returning a list of strings, or by the application being a generator function that yields strings, or by the application being a class whose instances are iterable. Regardless of how it is accomplished, the application object must always return an iterable yielding zero or more strings.


The server or gateway must transmit the yielded strings to the client in an unbuffered fashion, completing the transmission of each string before requesting another one. (In other words, applications should perform their own buffering. See the Buffering and Streaming section below for more on how application output must be handled.)


The server or gateway should treat the yielded strings as binary byte sequences: in particular, it should ensure that line endings are not altered. The application is responsible for ensuring that the string(s) to be written are in a format suitable for the client. (The server or gateway may apply HTTP transfer encodings, or perform other transformations for the purpose of implementing HTTP features such as byte-range transmission. See Other HTTP Features, below, for more details.)


If a call to len(iterable) succeeds, the server must be able to rely on the result being accurate. That is, if the iterable returned by the application provides a working __len__() method, it must return an accurate result. (See the Handling the Content-Length Header section for information on how this would normally be used.)


If the iterable returned by the application has a close() method, the server or gateway must call that method upon completion of the current request, whether the request was completed normally, or terminated early due to an error. (This is to support resource release by the application. This protocol is intended to complement PEP 325's generator support, and other common iterables with close() methods.

(Note: the application must invoke the start_response() callable before the iterable yields its first body string, so that the server can send the headers before any body content. However, this invocation may be performed by the iterable's first iteration, so servers must not assume that start_response() has been called before they begin iterating over the iterable.)

Finally, servers and gateways must not directly use any other attributes of the iterable returned by the application, unless it is an instance of a type specific to that server or gateway, such as a "file wrapper" returned by wsgi.file_wrapper (see Optional Platform-Specific File Handling). In the general case, only attributes specified here, or accessed via e.g. the PEP 234 iteration APIs are acceptable.

使用特权

评论回复
板凳
sinanjj|  楼主 | 2010-8-24 23:10 | 只看该作者
environ Variables

The environ dictionary is required to contain these CGI environment variables, as defined by the Common Gateway Interface specification [2]. The following variables must be present, unless their value would be an empty string, in which case they may be omitted, except as otherwise noted below.

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.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:In God We Trust 独立的个人,体赖科学技术工具提供针对个人的产品与服务,是通向幸福的唯一道路 工程师,设计师等可以个人创业的群体,将逐步瓦解官僚体制公司,成为中国中产。(重复劳动,工厂等,将逐步机械化) seacer.co

456

主题

6300

帖子

25

粉丝