WSGI到底是什么?

WSGI是PythonWebServerGatewayInterface的缩写,定义了Web服务器与PythonWeb应用之间的标准接口,确保移植性。它规定Web服务器需将HTTP报文转化为WSGI格式,Web应用提供可调用对象接收请求信息并返回响应。本文通过一个简单的例子解释了如何实现WSGI服务,并以Flask框架为例展示了其如何遵循WSGI规范。

在Python Web开发时经常会遇到WSGI,所以WSGI到底是什么呢?本文我们一起来揭开WSGI神秘的面纱!

先来看一下WSGI的介绍

全称Python Web Server Gateway Interface,指定了web服务器和Python web应用或web框架之间的标准接口,以提高web应用在一系列web服务器间的移植性。 具体可查看 官方文档

从以上介绍我们可以看出:

  1. WSGI是一套接口标准协议/规范;
  2. 通信(作用)区间是Web服务器和Python Web应用程序之间;
  3. 目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信

你可能会问,为什么需要WSGI?

首先,我们明确一下web应用处理请求的具体流程:

  1. 用户操作操作浏览器发送请求;
  2. 请求转发至对应的web服务器
  3. web服务器将请求转交给web应用程序,web应用程序处理请求
  4. web应用将请求结果返回给web服务器,由web服务器返回用户响应结果
  5. 浏览器收到响应,向用户展示

可以看到,请求时Web服务器需要和web应用程序进行通信,但是web服务器有很多种啊,Python web应用开发框架也对应多种啊,所以WSGI应运而生,定义了一套通信标准。试想一下,如果不统一标准的话,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。

既然定义了标准,那么WSGI的标准或规范是?

web服务器在将请求转交给web应用程序之前,需要先将http报文转换为WSGI规定的格式。

WSGI规定,Web程序必须有一个可调用对象,且该可调用对象接收两个参数,返回一个可迭代对象:

  1. environ:字典,包含请求的所有信息
  2. start_response:在可调用对象中调用的函数,用来发起响应,参数包括状态码,headers等

通过以上学习,一起实现一个简单WSGI服务吧

首先,我们编写一个符合WSGI标准的一个http处理函数:

def hello(environ, start_response):
    status = "200 OK"
    response_headers = [('Content-Type', 'text/html')]
    start_response(status, response_headers)
    path = environ['PATH_INFO'][1:] or 'hello'
    return [b'<h1> %s </h1>' % path.encode()]

该方法负责获取environ字典中的path_info,也就是获取请求路径,然后在前端展示。

接下来,我们需要一个服务器启动WSGI服务器用来处理验证,使用Python内置的WSGI服务器模块wsgiref,编写server.py:

# coding:utf-8
"""
desc: WSGI服务器实现
"""
from wsgiref.simple_server import make_server
from learn_wsgi.client import hello


def main():
    server = make_server('localhost', 8001, hello)
    print('Serving HTTP on port 8001...')
    server.serve_forever()


if __name__ == '__main__':
    main()

执行python server.py,浏览器打开"http://localhost:8001/a",即可验证。

通过实现一个简单的WSGI服务,我们可以看到:通过environ可以获取http请求的所有信息,http响应的数据都可以通过start_response加上函数的返回值作为body。

当然,以上只是一个简单的案例,那么在python的Web框架内部是如何遵循WSGI规范的呢?以Flask举例,

Flask与WSGI

Flask中的程序实例app就是一个可调用对象,我们创建app实例时所调用的Flask类实现了__call方法,__call方法调用了wsgi_app()方法,该方法完成了请求和响应的处理,WSGI服务器通过调用该方法传入请求数据,获取返回数据:

def wsgi_app(self, environ, start_response):
    ctx = self.request_context(environ)
    error = None
    try:
        try:
            ctx.push()
            response = self.full_dispatch_request()
        except Exception as e:
            error = e
            response = self.handle_exception(e)
        except:  # noqa: B001
            error = sys.exc_info()[1]
            raise
        return response(environ, start_response)
    finally:
        if self.should_ignore_error(error):
            error = None
        ctx.auto_pop(error)

def __call__(self, environ, start_response):
    return self.wsgi_app(environ, start_response)

Flask的werkzeug库是一个非常优秀的WSGI工具库,具体的实现我们之后再详细学习。

### WSGI Web Application 的概念和用途 WSGI(Web Server Gateway Interface)是 Python 中定义的一种标准接口,用于实现 Web 服务器与 Web 应用程序之间的通信[^3]。一个 WSGI Web Application 是符合 WSGI 规范的可调用对象,它能够接收 HTTP 请求并返回 HTTP 响应。这种规范的设计使得开发者可以使用多种不同的 Web 服务器和框架来构建和部署应用程序。 #### WSGI Web Application 的核心要素 根据 WSGI 规范,一个 WSGI Web Application 必须是一个可调用对象(如函数或类实例),并且接受两个参数: 1. **environ**:一个包含 HTTP 请求信息的字典,包括请求头、方法、路径等。 2. **start_response**:一个回调函数,用于设置响应的状态码和头部信息。 以下是一个简单的 WSGI Web Application 示例代码: ```python def application(environ, start_response): # 设置响应状态码和头部 start_response('200 OK', [('Content-Type', 'text/html')]) # 返回响应体 return [b'<h1>Hello, WSGI World!</h1>'] ``` #### WSGI Web Application 的工作原理 当一个 HTTP 请求到达 Web 服务器时,服务器会将请求转发给 WSGI 服务器。WSGI 服务器负责将原始 HTTP 请求解析为符合 WSGI 标准的格式,并调用 WSGI Web Application 提供的可调用对象[^4]。具体流程如下: 1. **接收请求**:Web 服务器接收到客户端的 HTTP 请求。 2. **传递给 WSGI 服务器**:Web 服务器将请求转发给 WSGI 服务器。 3. **解析请求**:WSGI 服务器将请求解析为 `environ` 字典。 4. **调用 WSGI 应用程序**:WSGI 服务器调用 WSGI Web Application 的可调用对象,传入 `environ` 和 `start_response`。 5. **生成响应**:WSGI Web Application 使用 `start_response` 设置响应状态和头部,并返回响应体。 6. **发送响应**:WSGI 服务器将生成的响应发送回 Web 服务器,再由 Web 服务器返回给客户端。 #### WSGI Web Application 的用途 WSGI Web Application 的主要用途是作为 Python Web 应用程序的核心组件,提供一种标准化的方式与 Web 服务器进行交互。以下是其主要用途: - **跨平台兼容性**:通过 WSGI 规范,开发者可以轻松地在不同 Web 服务器(如 Apache、Nginx)和框架(如 Flask、Django)之间切换。 - **简化开发和部署**:WSGI 提供了一种统一的接口,减少了开发者在不同环境下的适配成本[^2]。 - **支持多种框架**:许多现代 Python Web 框架(如 Flask、Django)都基于 WSGI 构建,开发者可以利用这些框架快速开发功能丰富的 Web 应用程序。 ### 示例代码 以下是一个完整的 WSGI Web Application 示例,展示如何使用 `wsgiref` 模块创建一个简单的 WSGI 服务器: ```python from wsgiref.simple_server import make_server def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'<h1>Hello, WSGI World!</h1>'] # 创建 WSGI 服务器 httpd = make_server('localhost', 8000, application) print("Serving on port 8000...") # 启动服务器 httpd.serve_forever() ``` 运行上述代码后,在浏览器中访问 `http://localhost:8000`,可以看到 "Hello, WSGI World!" 的响应[^1]。 ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

松叔汇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值