💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
WSGI,或者 Web Server Gateway Interface,是 Python 中用于在 Web 服务器和 Web 应用之间进行通信的标准接口。WSGI 不仅定义了 Web 服务器怎么与 Web 应用交互,也定义了 Web 应用程序如何处理 HTTP 请求。 基本的 WSGI 接口定义了两个方面: 服务器或网关端:这一侧会将接受的 HTTP 请求转化为 WSGI 格式并发送给应用程序。 应用程序端:Web 应用会接受 WSGI 请求并返回 HTTP 响应。 一个简单的 WSGI 程序示例: python Copy code def simple_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return ["Hello WSGI World!\n"] if __name__ == '__main__': from wsgiref.simple_server import make_server httpd = make_server('', 8000, simple_app) print("Serving on port 8000...") httpd.serve_forever() 在这个例子中,simple_app 是 WSGI 应用,它接受两个参数:environ 和 start_response。environ 是一个包含所有 HTTP 请求信息的字典,start_response 是一个用于发送 HTTP 响应的回调函数。 此代码使用 wsgiref 来创建一个 WSGI HTTP 服务器,它监听8000端口,等待 HTTP 请求并把请求传递给 simple_app WSGI 应用处理。 WSGI 已经广泛应用在各类 Python Web 框架中,例如 Flask、Django 等。通过 WSGI,Python 的 Web 应用可以与各种不同的 Web 服务器(如 Apache,Nginx 等)进行通信 ## WSGI是 Python 用于 Web 服务器和 Web 应用程序间通信的标准化的接口定义。它存在的目的是为了使得更换 Web 服务器或 Web 框架变得更为简单,因为借助 WSGI,它们都遵循了相同的规范以实现相互的通信。 基于 WSGI 的应用需要实现一个简单的调用接口,这个接口接受两个参数:"环境"(environ)(一个包含了 WSGI/CGI 环境变量的字典)和 "开始响应"(start_response)(一个用来启动响应过程的回调函数)。这个函数需要返回一个可迭代的对象,这个对象将被用于作为 HTTP 响应的体。 一个最基本的实现一个 WSGI 应用的例子是这样的: python Copy code def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b"Hello World!"] # 返回一个 byte 字符串 这个例子接受 HTTP 请求,并返回 "Hello World!" 的 HTTP 响应。 WSGI 使得 Python 可以更方便地开发 Web 应用,允许开发者可以使用各种不同的 Web 服务器(例如 Apache,Nginx,Gunicorn 等)以及各种不同的 Web 框架(例如 Django,Flask,Pyramid 等)。所有支持 WSGI 的应用在所有支持 WSGI 的服务器上的工作方式是相同的。这为 Python Web 开发提供了很大的灵活性。 ## Sample ``` def simple_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return ["Hello WSGI World!\n".encode()] if __name__ == '__main__': from wsgiref.simple_server import make_server httpd = make_server('', 8000, simple_app) print("Serving on port 8000...") httpd.serve_forever() ``` ## 问题 ``` Traceback (most recent call last): File "C:\inssoftware\Python\Python311\Lib\wsgiref\handlers.py", line 138, in run self.finish_response() File "C:\inssoftware\Python\Python311\Lib\wsgiref\handlers.py", line 184, in finish_response self.write(data) File "C:\inssoftware\Python\Python311\Lib\wsgiref\handlers.py", line 278, in write assert type(data) is bytes, \ ``` WSGI 应用返回的数据类型应该是字节(bytes),而不是其他类型。WSGI 规范规定,WSGI 应用的返回值必须是字节流(也就是 bytes 类型的数据),如果你尝试返回一个字符串(str 类型的数据),就会收到这个错误。 在你的代码中,确保你的 WSGI 应用返回一个字节流。在 Python 中,可以使用字符串的 encode() 方法来将其转变成字节流: python Copy code def simple_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return ["Hello WSGI World!\n".encode()] # encode the string to bytes if __name__ == '__main__': from wsgiref.simple_server import make_server httpd = make_server('', 8000, simple_app) print("Serving on port 8000...") httpd.serve_forever() 在这个修改后的例子中,返回的字符串 "Hello WSGI World!\n" 被通过 .encode() 方法转变为了字节流,因此不会再触发上述的错误。 ## 不符合WSGI标准 Python 的 WSGI(Web Server Gateway Interface)规定了一套标准,定义了 Web 服务器(或者说是网关)如何与 Python Web 应用之间进行通信。如果一个应用或服务器不能满足这个规范,我们就通常会说它不符合 WSGI 标准。 一些不符合 WSGI 标准的例子可能包括: 无法适配WASGI环境和回调函数的应用:一个 WSGI 应用必须是一个可调用的 Python 对象(最常见的是一个函数或者一个类的实例),它需要接受两个参数:一个包含了所有 WSGI 和 CGI 环境变量的字典,和一个用来开始响应过程的回调函数。如果一个应用无法满足这个要求,那它就不是一个 WSGI 应用。 python Copy code def application(environ, start_response): #... 返回类型不正确的应用:WSGI 应用需要返回一个响应主体(body),这个主体必须是一个可以返回字节串的可迭代对象。如果返回的对象无法迭代,或者迭代出来的不是字节串,那这个应用就不符合 WSGI 规范。 python Copy code def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b"Hello World!"] # 返回一个 byte 字符串 不兼容错误流的应用:WSGI 规定了 WSGI 应用需要可以写入到 wsgi.errors 流。如果无法做到这一点,那此应用就不符合 WSGI 规范。 以上这些都只是一些例子,实际上,有许多其他的可能会导致一个应用或者服务器不符合 WSGI 规范。为了确保兼容性,你应当参照 PEP 3333(这是 WSGI 规范的官方定义)创建你的应用,或是使用兼容 WSGI 规范的 Web 框架(比如 Flask,Django 等)。