What is a WSGI application?

The WSGI PEP can be quite confusing if all you want to do is write applications quickly and easily. The best way to explain the WSGI is to work through an example demonstrating how an application written as a CGI script has to be modified to work as a WSGI application.

Consider the CGI script code below:

#!/usr/bin/env python
print 'Content-type: text/plain\n\n'
print 'Hello world!'

This does nothing more than print the words 'Hello world!' to a web browser in plain text. What we have done is sent an HTTP header Content-type: text/plain\n\n and then a text string to the browser. The webserver may also have sent a '200 OK' response if the application completed successfully.

To create the same result using a WSGI application we would use this code:

def simplestApp(environ, start_response):
    start_response('200 OK',[('Content-type','text/plain')])
    return ['Hello world!']

application = simplestApp

This is the most basic WSGI application. It is a function names application which a WSGI server will call and pass two parameters. The first is a dictionary named environ containing environmental variables and the second is a function named start_response which must be called before the application returns a value.

You may not be happy with the function start_response being passed as a parameter to our application callable. Whilst it is not possible to pass a function as a parameter in some languages it is allowed in Python. This ability to pass callables as function parameters is crucial to understanding how the WSGI works.

Here is an example to consider:

def b(text):
    print text
def a(print_response):
    print_response("Hello World!")
    return "It worked!"
print a(b)

In this case we are passing the function b to the a as the parameter print_response. We are then printing the value returned from a. What do you think the result will be?

The answer is this:

Hello World!
It worked!

Make sure you understand this example before you read on.

A WSGI application must do two things, these are:

  1. Call the start_response function (passed to our application callable) with the parameters status and headers in the correct order. This will set the status of the application and send the HTTP headers. In our example the status is '200 OK' meaning everything has gone according to plan and we only send one header, the Content-type header with the value text/plain.
  2. Return an iterable containing nothing but strings. In this example the iterable is simply a list containing one string. The return value could equally well have been ['Hello', ' ', 'world!'] but there was no need to make things more complicated.

There are some big advantages in rewriting our code as a WSGI application: