In 2003, Python web frameworks were typically written against only CGI, FastCGI, mod_python, or some other custom API of a specific web server. To quote PEP 333:
Python currently boasts a wide variety of web application frameworks, such as Zope, Quixote, Webware, SkunkWeb, PSO, and Twisted Web -- to name just a few. This wide variety of choices can be a problem for new Python users, because generally speaking, their choice of web framework will limit their choice of usable web servers, and vice versa... By contrast, although Java has just as many web application frameworks available, Java's "servlet" API makes it possible for applications written with any Java web application framework to run in any web server that supports the servlet API.
the server/gateway side. This is often running full web server software such as Apache or Nginx, or is a lightweight application server that can communicate with a webserver, such as .
the application/framework side. This is a Python callable, supplied by the Python program or framework.
Between the server and the application, there may be one or more WSGI middleware components, which implement both sides of the API, typically in Python code. WSGI does not specify how the Python interpreter should be started, nor how the application object should be loaded or configured, and different frameworks and webservers achieve this in different ways.
WSGI middleware
A WSGI middleware component is a Python callable that is itself a WSGI application, but may handle requests by delegating to other WSGI applications. These applications can themselves be WSGI middleware components. 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: def application: start_response yield b'Hello, World\n'
Where:
Line 1 defines a function named application, which takes two parameters, environ and start_response. environ is a dictionary containing CGI environment variables as well as other request parameters and metadata under well-defined keys. start_response is a callable itself, taking two positional parameters, status and response_headers.
Line 2 calls start_response, specifying "200 OK" as the HTTP status and a "Content-Type" response header.
Line 3 makes the function into a generator. The body of the response is returned as an iterable of byte strings.
Example of calling an application
A full example of a WSGI network server is outside the scope of this article. Below is a sketch of how one would call a WSGI application and retrieve its HTTP status line, response headers, and response body, as Python objects. Details of how to construct the environ dict have been omitted. from io import BytesIO def call_application: status = None headers = None body = BytesIO
app_iter = app try: for data in app_iter: assert status is not None and headers is not None, \ "start_response was not called" body.write finally: if hasattr: app_iter.close return status, headers, body.getvalue environ = # "environ" dict status, headers, body = call_application