WSGI规范(PEP 3333)

WSGI 的全称是:Web Server Gateway Interface,介于 web server(uwsgi) 和应用 server (flask)之间的接口规范。当使用 Python 进行 web 开发时,要深刻理解 Django、Flask、Tornado等 web 框架,WSGI是你绕不过去的槛儿。

应用/框架端

WSGI 对于 application 对象有如下三点要求

  1. 必须是一个可调用的对象,由WSGI服务器来调用
  2. 接收两个必选参数environ、start_response。environ和start_response由WSGI提供
  3. 返回值必须是可迭代对象,用来表示http body

可调用对象:可能代表函数、方法、类或者实现了__call__方法的实例(flask app就是一个实现__call__方法实例)

参数说明:

  • environ:一个包含所有HTTP请求信息的dict对象
  • start_response:一个发送HTTP响应的函数,理解成回调函数?

函数对象

HELLO_WORLD = b"Hello world!\n"

def simple_app(environ, start_response):
    """最简单的应用对象"""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return [HELLO_WORLD]

# 名字随意,不过建议命名成environ和start_response
def app(e, s):
    s('200 OK', [('Content-Type', 'text/html')])
    for k, v in e.items():
        print('{} {}'.format(k, v))
    return [b'<h1>Hello, web!</h1>']

类对象

class AppClass:
    """产生相同的输出,但是用类实现。

    (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

参考

接收请求–》创建请求上下文–》请求上下文入栈–》创建该请求的应用上下文–》应用上下文入栈–》处理逻辑–》请求上下文出栈–》应用上下文出栈