Middleware

What is middleware?

Middleware is software that sits in between what receives the request and the application that returns the response. Middleware may modify the request or the response or may just observe them. Multiple layers of middleware may be used.

WSGI Middleware

WSGI is just a contract that applications take an environ and start_response and return the chunked response (and call start_response with the appropriate headers). So it is easy to chain these together.

WSGI middlware obey the WSGI contract and sit between the server and the endpoint application (which they usually take as an argument to their constructor).

Though the diagram shows a "wedge"-like structure, any WSGI layer could branch (i.e. choose between multiple applications/WSGI pipes) or return a response without talking to the endpoint app(s). Usually, things don't get too crazy.

How to wrap a WSGI application:

from webob import Request

class MyMiddleware(object):

  def __init__(self, app, *args, **kwargs):
    self.app = app
    # other initialization
    # ...

  def __call__(self, environ, start_response):
    reqeust = Request(environ)
    # do stuff
    response = request.get_response(self.app)
    return response(environ, start_response)

Chains of middleware: factories

Getting a Response with WebOb

You'll often want to modify or introspect a response in a WSGI chain

Use the Request.get_response method:

from webob import Request, Response

class MyMiddleware(object):

  def __init__(self, app):
    self.app = app

  def __call__(self, environ, start_response):
    request = Request(environ)

    # you might do stuff here
    # ...

    response = request.get_response(self.app)
    response.decode_content()

    # do stuff with the response
    # ...

    # return the response
    return response(environ, start_response)

This used to be a tedious by-hand process before webob

Example middleware service: commenting

http://pythonpaste.org/webob/comment-example.html

Is this a web-service?

What makes good (WSGI) middleware?

Example middleware service: authorization

WSGI states that the identity (typically, the login name) of an authenticated user lives in environ['REMOTE_USER'] (or request.remote_user in webob).

For highly integrated sites, it may be desirable that authentication is dealt with in an integrated fashion. Typically, however, the application (or, more generally, downstream middleware + the application) only cares about who (if anyone) is authenticated. In these cases, it is a good job for middleware.

Typical middleware authentication workflow:

Example software:

if you use bitsyauth in production, please don't hold me responsible! it has not been audited for security!

Is this a web service?

probably!

If you use auth, please don't roll your own.

Amongst other things, Apache (and other general-purpose web servers, such as nginx) is often used to provide HTTP Basic Auth (or digest, etc). In this sense, amongst others, Apache can function as middleware, albeit of a non-WSGI variety. The tighter contract of WSGI (vs. HTTP) allows a richer environment in which to function, assuming you're developing python web services and sites.