PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受, 它已基本达成它的可移植性方面的目标。2003年PEP333协议定义了WSGI,目前协议最新的版本是PEP3333(https://www.python.org/dev/peps/pep-3333/),已经替代了原有的PEP333协议,那就从协议入手来了解WSGI协议及其原理。
在协议的abstract中,描述了WSGI的目的:
This document specifies a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers.
WSGI定义的是一个标准接口,用于web服务器和应用/框架之间的交互。早期web应用开发的框架选择多,不统一,对于开发者来说难以选择,而且和服务器端框架强耦合,于是将JAVA的servlet API模式引入了进来,在这个时期又诞生了好几种API,而经过时代更迭,WSGI这种简单易用的API最终得到广泛认可,目前主流的Python web框架都是基于WSGI。关于WSGI,协议中反复强调,只是定义了一个接口,不管是server还是app,都需要开发者自行设计,它存在的目的,下面这句话说得非常明了: the goal of WSGI is to facilitate easy interconnection of existing servers and applications or frameworks, not to create a new web framework.
二、2+2=?
下面就来认识下这个接口,The WSGI interface has two sides: the “server” or “gateway” side, and the “application” or “framework” side. 既然是接口,有两面是毋庸置疑的,只是下面这句话比较拗口:The server side invokes a callable object that is provided by the application side.
A user who desires to incorporate middleware into an application simply provides the middleware component to the server, as if it were an application, and configures the middleware component to invoke the application, as if the middleware component were a server.
其中用到了虚拟语气,as if it were an application,as if the middleware component were a server.说明它既不是应用程序,也不是服务器,它就叫中间件,它位于WSGI的应用端,为更上层的web开发提供基础服务。
对于中间件的要求,协议用下面这段话来描述:For the most part, middleware must conform to the restrictions and requirements of both the server and application sides of WSGI. In some cases, however, requirements for middleware are more stringent than for a “pure” server or application, and these points will be noted in the specification.
Flask类中,定义了自己的call方法,因此可以保证Werkzeug可以调用到,这点在协议中也讲到了:The term “object” should not be misconstrued as requiring an actual object instance: a function, method, class, or instance with a call method are all acceptable for use as an application object.