Web Server Gateway Interface
The Web Server Gateway Interface (WSGI) is a specification for simple and universal interface between web servers and web applications or frameworks for the Python programming language. It was originally specified in PEP 333[1] authored by Phillip J. Eby, and published on 7 December 2003. It has since been adopted as a standard for Python web application development. The latest version of the specification is v1.0.1, also known as PEP 3333, published on 26 September 2010.[2]
Background
Python web frameworks had been a problem for new Python users since the choice of web framework would limit the choice of usable web servers, and vice versa. Python applications were often designed for only one of CGI, FastCGI, mod_python, or some other custom API of a specific web server.[3]
WSGI was created as a low-level interface between web servers and web applications or frameworks to promote common ground for portable web application development.[2]
Specification overview
The WSGI has two sides: the "server" or "gateway" side (often a web server such as Apache or Nginx), and the "application" or "framework" side (the python script itself). To process a WSGI request, the server side executes the application and provides environment information and a callback function to the application side. The application processes the request, returning the response to the server side using the callback function it was provided.
Between the server and the application, there may be a WSGI middleware, which implements both sides of the API. The server receives a request from a client and forwards it to the middleware. After processing, it sends a request to the application. The application's response is forwarded by the middleware to the server and ultimately to the client. There may be multiple middlewares forming a stack of WSGI-compliant applications.
A "middleware" component can perform such functions as:
- Routing a request to different application objects based on the target URL, after changing the environment variables accordingly.
- Allowing multiple applications or frameworks to run side-by-side in the same process
- Load balancing and remote processing, by forwarding requests and responses over a network
- Performing content post-processing, such as applying XSLT stylesheets
Examples
Example application
A WSGI-compatible “Hello World” application written in Python:
1 def application(environ, start_response):
2 start_response('200 OK', [('Content-Type', 'text/plain')])
3 yield 'Hello World\n'
Where:
- Line 1 defines a callable[4] named
application
, which takes two parameters,environ
andstart_response
.environ
is a dictionary containing environment variables in CGI.start_response
is a callable taking two required parametersstatus
andresponse_headers
. - Line 2 calls
start_response
, specifying "200 OK" as the status and a "Content-Type" header. - Line 3 returns the body of the response as a string literal.
Example of calling an application
An example of calling an application and retrieving its response.[5] A web server gives a callback start_response to a web framework application. A start_response has an http protocol status, headers, and body. For Django, an HttpResponse object is returned.[6][7] The "environ" fragment consists of, for example, REQUEST_METHOD info.[8] Depending on this info, it might or might not call ("OPTIONS") this app.
def call_application(app, environ):
body = []
status_headers = [None, None]
def start_response(status, headers):
status_headers[:] = [status, headers]
return body.append(status_headers)
app_iter = app(environ, start_response)
try:
for item in app_iter:
body.append(item)
finally:
if hasattr(app_iter, 'close'):
app_iter.close()
return status_headers[0], status_headers[1], ''.join(body)
status, headers, body = call_application(app, {...environ...})
WSGI-compatible applications and frameworks
Numerous web frameworks support WSGI:
- BlueBream
- bobo[9]
- Bottle
- CherryPy
- Django[10]
- Eventlet[11]
- Flask
- Gevent-FastCGI[12]
- Google App Engine's webapp2
- Gunicorn
- prestans[13]
- mod_wsgi for use with Apache[14]
- netius
- pycnic[15]
- Pylons
- Pyramid
- restlite[16]
- Tornado
- Trac
- TurboGears
- Uliweb[17]
- uWSGI
- web.py[18]
- Falcon[19]
- web2py
- weblayer[20]
- Werkzeug[21]
- Radicale[22]
Wrappers
The server or gateway invokes the application callable once for each request it receives from an HTTP client that is directed at the application.
Currently wrappers are available for FastCGI, CGI, SCGI, AJP (using flup), twisted.web, Apache (using mod_wsgi or mod_python), Nginx (using ngx_http_uwsgi_module),[23] and Microsoft IIS (using WFastCGI,[24] isapi-wsgi,[25] PyISAPIe,[26] or an ASP gateway).
WSGI and Python 3
The separation of binary and text data in Python 3 poses a problem for WSGI, as it specifies that header data should be strings, while it sometimes needs to be binary and sometimes text. This works in Python 2 where text and binary data both are kept in "string" variables, but in Python 3 binary data is kept in "bytes" variables and "string" variables are for unicode text data. An updated version of the WSGI specification that deals with this is PEP 3333.[27]
A reworked WSGI spec Web3 has also been proposed, specified in PEP444. This standard is an incompatible derivative of WSGI designed to work on Python 2.6, 2.7, 3.1+.[28]
See also
- Rack – Ruby web server interface
- PSGI – Perl Web Server Gateway Interface
- SCGI – Simple Common Gateway Interface
- JSGI – JavaScript web server gateway interface
References
- ↑ "PEP 333, Python Web Server Gateway Interface v1.0".
- 1 2 "PEP 3333, Python Web Server Gateway Interface v1.0.1".
- ↑ "The Python Wiki "Web Programming" topic".
- ↑ i.e. "a function, method, class, or an instance with a
__call__
method" - ↑ Creating WSGI Middleware
- ↑ https://docs.djangoproject.com/en/1.10/ref/request-response/#httpresponse-objects
- ↑ Django Response object code on github
- ↑ PEP3333
- ↑ "Bobo light-weight framework for creating WSGI web applications".
- ↑ "Django with WSGI support".
- ↑ http://eventlet.net/doc/modules/wsgi.html
- ↑ https://pypi.python.org/pypi/gevent-fastcgi
- ↑ "prestans Micro-Framework".
- ↑ Python WSGI adapter module for Apache
- ↑ "Pycnic a JSON API oriented WSGI framework".
- ↑ "restlite server tools for quick prototyping".
- ↑ "Ulibweb github source code".
- ↑ "web.py official site".
- ↑ "Falcon Web Framework".
- ↑ "weblayer package for writing WSGI application".
- ↑ "Werkzeug, the Python WSGI Utility Library".
- ↑ "Radicale, CalDAV and CardDAV solution".
- ↑ http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html
- ↑ https://pytools.codeplex.com/wikipage?title=wfastcgi
- ↑ http://code.google.com/p/isapi-wsgi/
- ↑ http://pyisapie.sourceforge.net/
- ↑ Eby, P.J. (2010-09-26). "PEP 3333". Retrieved 2011-07-27.
- ↑ McDonough, Chris; Ronacher, Armin (2010-07-19). "PEP 444 – Python Web3 Interface". Retrieved 2010-09-20.
External links
- PEP 333 – Python Web Server Gateway Interface
- PEP 3333 – Python Web Server Gateway Interface v1.0.1
- WSGI metaframework
- Comprehensive wiki about everything WSGI
- WSGI Tutorial
- Python standard library module wsgiref
- Getting Started with WSGI
- NWSGI – .NET implementation of the Python WSGI specification for IronPython and IIS
- Gevent-FastCGI server implemented using gevent coroutine-based networking library