WSGI(Web Server Gateway Interface) IN A NUTSHELL

WSGI(Web Server Gateway Interface)既不是一个服务器,也不是一个Python模块或者框架,它是是服务器和Python 开发的web应用程序之间的一个接口标准。该标准包含了两方面:一面是服务器需要实现的,另一面是应用需要是实现的。关于它的详细介绍可以参看PEP 3333
下面对WSGI做个简单标准做个很简单的介绍以及使用Python的一个WSGI内建实现一个WSGI Hello World程序。
WSGI app 可以是函数、模块、类等,只要表示它的对象能被直接调用,例如一个实现了__call__方法的类。该对象接收两个位置参数,为了方便演示,可以将这两个参数分别命名为environ以及start_response,服务器会通过result = app(environ, start_response)的形式调用它。
其中,environ是一个保存了CGI形式的环境变量的字典,而且该字典必须是python内建字典,而不能是内建字典的其他子类或者类字典的其他对象;start_response是一个接收两个不可省略的位置参数的可调用的对象,这两个位置参数分别是HTTP状态码和应答头。假设这两个位置参数是status, response_headers,在App中调用该对象的方法是start_response(status, response_headers)start_response返回一个需要一个形如write(data)的可调用对象,该对象接收的一个位置参数data是一个bytestring,他是应答体的一部分。

下面的表格列出了部分字典中可能包含的字段内容,完整的字段介绍可参看PEP 3333,这些内容由服务器负责设置:

Name(key) Description
REQUEST_METHOD HTTP 请求方法,如GET\POST
SCRIPT_NAME app 所对应的在URL中的路径,可以为空,如果app所在位置为服务器的根目录
PATH_INFO 请求URL路径中确定资源位置的部分,他与SCRIPT_NAME一起构成了完整的请求路径
QUERY_STRING 请求参数,即URL中?后面的那部分
CONTENT_TYPE 请求头中Content-Type 字段的内容
CONTENT_LENGTH 请求头中Content-Length字段的内容
SERVER_NAME, SERVER_PORT 当与SCRIPT_NAME 以及 PATH_INFO合在一起的时候,可以用补全URL
SERVER_PROTOCOL 客户端发送该请求所使用的HTTP协议版本

WSGI app 返回一个可迭代的包含0到多个的bytestring的对象,这个对象可以是列表、生成器等,只要这个对象能让服务器迭代获取0到多个bytestring。调用WSGI app的服务器会一非缓冲的方式,将app返回的对象的内容迭代发送给客户端,如果需要缓冲,则需要app自己去实现,例如,如果返回的是一个字符串,可以将它构造成一个包含该字符串的列表,这样服务器只迭代一次(因为整个列表只包含一个字符串)而不是迭代整个字符串长度的次数。
下面举个栗子:

def application ( 
    # 一个包含CGI样式环境变量的字典,该字典的内容服务器会负责填充
    environ,
    # 服务器传进来的一个的接收HTTP状态码和应答首部作为参数的可调用对象
    start_response
):

    # 处理请求并生成返回内容
    response_body = 'Hello World, Here is a WSGI app'

    # HTTP 状态码
    status = '200 OK'

    # HTTP 设置客户端需要的响应首部
    response_headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(response_body)))
    ]

    # 使用服务器提供的可调用对象将状态信息发送给服务
    start_response(status, response_headers)

    # 返回一个可迭代的对象,由于服务器不负责缓冲,这里使用列表进行缓冲操作
    return [response_body]

以上就是一个非常简单的WSGI app了。使用Python 自带的一个自带的一个WSGI参考实现的简单服务器wsgiref,可以运行我们的Demo。
使用任意文本编辑器,输入以下内容:

#!/usr/bin/env python

from wsgiref.simple_server import make_server

# 开发WSGI app
def application ( 
    # 一个包含CGI样式环境变量的字典,该字典的内容服务器会负责填充
    environ,
    # 服务器传进来的一个的接收HTTP状态码和应答首部作为参数的可调用对象
    start_response
):

    # 处理请求并生成返回内容
    response_body = 'Hello World, Here is a WSGI app'

    # HTTP 状态码
    status = '200 OK'

    # HTTP 设置客户端需要的响应首部
    response_headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(response_body)))
    ]

    # 使用服务器提供的可调用对象将状态信息发送给服务
    start_response(status, response_headers)

    # 返回一个可迭代的对象,由于服务器不负责缓冲,这里使用列表进行缓冲操作
    return [response_body]
    
# 初始化服务器
httpd = make_server('localhost', 8051, application)
# 启动服务器监听
httpd.serve_forever()

将该文件保存成.py后缀的任意名字文件,如wsgi_demo.py,打开命令行进入到存放该文件的文件夹执行python wsgi_demo.py,在浏览器地址栏输入http://localhost:8051即可看到服务器返回的内容。
运行结果


本文首发于个人公众号TensorBoy。如果你觉得内容还不错,欢迎分享并关注我的公众号TensorBoy,扫描下方二维码获取更多精彩原创内容!

公众号二维码

发布了45 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ZM_Yang/article/details/86243105
今日推荐