WSGI,是Web Server Gateway Interface首字符缩写, 发音 “whiz-gee”(g发硬/g/) 或者 “whiskey”。
WSGI 历史很久了,2003年由PEP-333规范,2010年,PEP3333基于Python3进行了更新。由于出现比较早,没有Python3.5引入的async、await 等异步内容,这导致2019年出现了ASGI(Asynchronous Server Gateway Interface)。
规范
WSGI 是一个规范,它遵循这种规范将一个Web组件抽象成三个部件层:
- 服务器(server、gateway)
- 中间件(middleware)
- 应用程序(application、framework)
要提升程序的可移植性,需要规范服务器和应用程序之间的交互操作,这就是WSGI做的事情。
接下来只考虑应用程序端
例子
通过简单例子,一点点看看
Hello world
一个简单的WSGI的应用程序,大致这个样子:
1 2 3 |
|
而要执行它,需要将其告知WSGI服务器才行。
在python标准库中有一个wsgi服务器的参考实现,我们可以启动它并告知其我们的应用程序入口:
1 2 |
|
此时用浏览器打开127.0.0.1:8000,即可看到程序运行内容。
应用程序参数
environ
:一个dict类型对象。一般包含- 浏览器相关的上下文信息
- CGI接口定义的环境变量:
REQUEST_METHOD
、SCRIPT_NAME
、PATH_INFO
、QUERY_STRING
等 - WSGI接口定义的环境变量:
wsgi.version
、wsgi.input
等 - OS或Web服务器相关的环境变量
start_response
:一个在Server中定义的回调函数。这个回调函数接受两个必选参数status和response_headers
,以及可选参数exec_info
。status
:字符串,标识HTTP响应状态。比如"200 OK"
或"404 Not Found"
response_headers
:列表类型对应,列表元素是(header_name, header_value)
。HTTP响应的headers。exec_info
:出错时,返回错误信息给浏览器
- 返回值:如果HTTP响应没有body,可以返回None,否则返回可迭代对象。
我们稍微修改一下程序,输出些额外信息
1 2 3 |
|
此时用浏览器打开127.0.0.1:8000/aaa/bbb/ccc,即可在页面中看到路径信息。
中间件(Middleware)
中间件是一个运行在 Server 和 Application 之间的应用程序。它同时具备了 Server 和 Application 的角色功能:
- 对于 Server 来说,它是一个 Application;
- 对于 Application来说,它是一个 Server。
中间件并不修改 Server 端和 Application 端的规范,只是需要同时实现了这两个角色的功能以便于两端之间起协调作用。中间件也可以将客户端 HTTP Request 路由给不同的 Application。中间件可以由很多层。
比如,可以写一个简单的中间件,添加到前面的例子中,并告知wsgi服务器:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
装饰器模式可能更直观:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Werkzeug
- https://werkzeug.palletsprojects.com
Wekzeug,/ˈvɛrkʦɔyk/,德语,工具的意思。
Werkzeug 这个python库,是一个WSGI(Web Server Gateway Interface)工具包,提供了一系列实用功能来帮助开发者处理HTTP请求、响应、URL等。
Werkzeug 是WSGI的中间件。它也提供了WSGI的Server,这个Server只作为开发使用,不用于生产环境。
开发用 Server
既然是WSGI Server,可以用它跑前面的应用程序:
1 2 |
|
也可以为其启用ssl证书:
1 2 3 |
|
中间件
- Werkzeug为HTTP请求和响应提供易于使用的包装器
使用其提供的Request和Response,上面的例子可以改写成:
1 2 3 4 5 6 |
|
- Werkzeug提供了强大的URL路由功能。
使用Map和Rule:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
WSGI服务器
生产用...
不过,这些WSGI基本都要用 Nginx或Apache等http服务器作为反向代理服务器。
Gunicorn
- https://gunicorn.org/
不支持原生Windows(可通过WSL使用)。
告知它如何加载我们的application。比如要等价于from hello import application
1 |
|
-w
指定进程数(--workers=4
)。默认是1,建议CPU * 2?-b
指定监听地址和端口(--bind
)。格式HOST
,HOST:PORT
,默认是localhost和8000- 语法格式:
{module_import}:{app_variable}
gunicorn使用root权限运行不安全(会让application以root运行),而不用root的话,会造成无妨绑定80和443端口。所以最好使用 nginx或apache作为反向代理服务器。
Waitress
- https://docs.pylonsproject.org/projects/waitress/
原生支持Windows。
安装:
1 |
|
启动:
1 |
|
- 参数格式
{module}:{app}
--host
指定监听地址。默认监听 0.0.0.0:8080
它不支持ssl,需要反向代理服务器。
mod_wsgi
- https://modwsgi.readthedocs.io/
与 apache httpd 集成使用。
1 |
|
它由一个现代的命令mod_wsgi-express
,用于启动server
1 |
|
其中 wsgi.py 是我们的程序,里面必须要包含application
这个对象:
1 2 3 |
|
uwsgi
- https://uwsgi-docs.readthedocs.io/en/latest/
官网上说,The project is in maintenance mode (only bugfixes and updates for new languages apis).
启动命令
1 |
|
其他
- gevent
- eventlet
参考
- https://peps.python.org/pep-3333/
- https://peps.python.org/pep-0333/
- https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
- https://segmentfault.com/a/1190000003069785
- https://gunicorn.org/