Flask前言 - Python WSGI

所有的Python web框架都需要WSGI协议,所以要深入了解一个web框架,很有必要去了解下WSGI;

WSGI(Web Server Gateway Interface) 的任务就是把上面的数据在 http server 和 python 程序之间简单友好地传递。它是一个标准,被定义在PEP 333。需要 http server 和 python 程序都要遵守一定的规范,实现这个标准的约定内容,才能正常工作。

Flask前言 - Python WSGI_第1张图片
image

图片出处

WSGI Application端

application端定义非常简单,它只要求开发者实现一个函数来响应HTTP请求。

这个函数就是一个符合WSGI标准的一个HTTP处理函数,它接收两个参数:

  • environ: 一个包含所有HTTP请求信息的dict对象。
  • start_response: 一个发送HTTP响应的函数,这个函数接受两个参数,一个是HTTP响应码,一个是HTTP header。
# wsgi_client.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["hello world"]

WSGI Server端

envrionstart_response这两个参数由服务端提供,PEP333里给出了一个wsgi server的简单实现:

import os, sys

def run_with_cgi(application):    # application 是程序端的可调用对象
    # 准备 environ 参数,这是一个字典,里面的内容是一次 HTTP 请求的环境变量
    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         
    environ['wsgi.url_scheme'] = 'http'

    headers_set = []
    headers_sent = []

    # 把应答的结果输出到终端
    def write(data):
        sys.stdout.write(data)
        sys.stdout.flush()

    # 实现 start_response 函数,根据程序端传过来的 status 和 response_headers 参数,
    # 设置状态和头部
    def start_response(status, response_headers, exc_info=None):
        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)
    finally:
        if hasattr(result, 'close'):
            result.close()

或者,python中也内置了一个WSGI服务器模块wsgiref, 通过这个模块就可以快速实现了个WSGI Server来测试我们的application:

# wsgi_server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
import wsgi_client

# 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, wsgi_client.application)
print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()

可以看到结果为wsgi_client.py中定义的hello world

200ok.png

Flask框架中的一个核心库werkzeug其实就是Python的WSGI规范的实用函数库

参考

  • python wsgi简介
  • WSGI接口

你可能感兴趣的:(Flask前言 - Python WSGI)