3

I have an almost complete simple web app written as a Python CGI script. I would like to change it to use WSGI, but I can't find documentation that helps me make sense of what WSGI actually is (one only repeatedly finds calls with start_response etc. but there doesn't seem to be much explanation fo rwhat these calls actually do). Can someone point me to a good explanation, plus a how-to on using WSGI?

Edit: Should add that I've seen this question but the answers still don't seem to tell one how to use WSGI in a direct script (as opposed to in a framework).

Community
  • 1
  • 1
ShankarG
  • 1,105
  • 11
  • 26
  • Oops, I just found [this guide from Armin Ronacher](http://lucumr.pocoo.org/2007/5/21/getting-started-with-wsgi/) which seems to be what I was looking for. Recommended for others as well. Can't clsoe this question, I think, so requesting that others do so. – ShankarG Mar 12 '12 at 08:58

2 Answers2

9

WSGI is PEP 333 (and PEP3333 for Python 3), a.k.a. Web Server Gateway Interface. It has three parts, but the part you're interested in is how you write a WSGI application. And WSGI app is a callable object that takes two arguments and returns an iterable object (or is a generator).

# this is my_app module
def app(environ, start_response):
    # environ is dict-like object containing the WSGI environment
    # refer to the PEP for details

    # start_response is a callable that, well, starts the response
    headers = [('Content-Type', 'text/plain; charset=utf-8')]
    start_response('200 OK', headers)

    return ["I'm a WSGI application.\n"]

To run the application, you need another part of WSGI, which is gateway. In the standard library you'll find wsgiref package. It contains a CGI gateway:

#!/usr/bin/python
# this is a CGI script that runs a WSGI application inside CGI handler
from wsgiref.handlers import CGIHandler
from my_app import app
CGIHandler().run(app)

And also a simple HTTP server for development:

from wsgiref.simple_server import make_server
from my_app import app
httpd = make_server('localhost', 8000, app)
httpd.serve_forever()

As you can see, WSGI allows you to reuse your application in different environments — CGI, SCGI, FastCGI, mod_wsgi, mod_python, etc., without actually rewriting it.

The last part of WSGI is middleware — basically, it's a concept that allows you to combine different WSGI applications. It forms sort of a sandwich — request flows from the top (the gateway) to the bottom (which is usually your application), with some intermediate layers in between, that might implement stuff like database connection pooling or sessions. wsgiref contains one such middleware — wsgiref.validate.validator, which checks whether layers below and above it conforms to the rules of WSGI spec.

And that's basically it. Now go use a framework.

jeromej
  • 10,508
  • 2
  • 43
  • 62
Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • +1 for providing a hell of a lot more detail than I did. And for "Now go use a framework." ;) – Amber Mar 12 '12 at 09:02
  • Thanks very much for a wonderful answer - I was looking for a guide but I've think you've given me the answer right here! Now I intend to make the app WSGI and **then** go use a framework. Lots of wasted time but I'm old school like that :) – ShankarG Mar 12 '12 at 09:06
  • @ShankarG: Most frameworks hide WSGI layer, because it can be bit cumbersome in complex applications. – Cat Plus Plus Mar 12 '12 at 09:07
  • True, I am tempted to use something straightforward like Bottle or Flask. But I would like to avoid rewriting my code too much, and the point you've raised about WSGI being able to use CGI seems tempting (though I don't quite understand it yet). – ShankarG Mar 12 '12 at 09:09
0

Try going straight to the source - PEP 333, the WSGI specification.

Amber
  • 507,862
  • 82
  • 626
  • 550