1.14.2 Understanding Middleware

As we learned in the introduction, WSGI middleware components can be chained together since each middleware, application pair is also a valid WSGI application.

In the example given, the Session class changes the environ dictionary to provide the application with more functionality. It could also have been chained with an Auth middleware component to provide auth functionality as shown below:

def exampleApplication(environ, start_response):
    if not environ.has_key('imaginaryAuth'):
        raise Exception{'No auth module found')
    if environ['superSession'].has_key('visited'):
        text = "You have already visited!"
    else:
        environ['superSession']['visited'] = 1
        text = "This is your first visit."
    start_response('200 OK', [('Content-type','text/plain')])
    return [text]
    
class Session:
    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):
        if "superSession" not in environ:
            import superSession
            environ["superSession"] = superSession.session()
        return self.application(environ, start_response)
        
class Auth:
    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):
        if "imaginaryAuth" not in environ:
            import imaginaryAuth
            environ["imaginaryAuth"] = imaginaryAuth.auth()
        return self.application(environ, start_response)
    
application = Auth(Session(exampleApplication))

Middleware classes usually do one of four things or a combination of them:

The most common use is to alter the environ dictionary in order to provide more functionality but here are some other ways in which they can be used.

Error Handling
Error handling middleware might catch an error raised, format it for display as HTML, change any HTTP headers and status set and return the correct settings for an error page.
User Sign In
User sign in middleware might wait for a '403 Forbidden' status and instead display a sign in page, setting a new status of '200 OK', new headers and of course a different result containg the HTML of the sign in page.