Ian Bicking: the old part of his blog

WSGI Sample Apps and Middleware

I'm starting to write some sample applications and middleware (along these lines) for WSGI. They are in svn://colorstudy.com/trunk/WSGI, or online. These are an attempt to see how these things feel in practice.

It's probably not the best example, but here's the hello-world application I wrote for this:

import cgi

def application(environ, start_response):
    form = cgi.FieldStorage(fp=environ['wsgi.input'],
                            environ=environ,
                            keep_blank_values=1)
    write = start_response('200 OK', [('Content-type', 'text/html')])
    if form.getvalue('name'):
        write('<html><head><title>Hello!</title></head>\n')
        write('<body>\n')
        write('<h1>Hello %s!</h1>\n' % form['name'].value)
    else:
        write('<html><head><title>Who is there?</title></head>\n')
        write('<body>\n')
        write('<h1>Who is there?</h1>\n')
    write('<form action="%s" method="POST">\n' % environ['SCRIPT_NAME'])
    write('What is your name?<br>\n')
    write('<input type="text" name="name" value="%s"><br>\n'
          % cgi.escape(form.getvalue('name', ''), 1))
    write('<input type="submit" value="That is my name"></form>\n')
    write('</body></html>\n')
    return None
In most cases you wouldn't be writing your application on this level, but it's really no worse than the cgi module (which isn't very good, but eh).

Something like cgitb_catcher is maybe a bit more interesting -- it provides cgitb tracebacks for any uncaught exceptions.

Created 25 Aug '04
Modified 14 Dec '04

Comments:

Hm, I just skimmed trough the pep and looked at your example. Is it right that the primary focus of WSGI is the response, and not the request?
You still use the cgi-module to retrieve the get/post parameters. I don't think that all kinds of servers realy support the cgi-interface, or guarantee it to be correct when not invoking a cgi ( in the dark mysts of my mind ther's some faint doubt about this cgi-thingy working with mod_python )
I understand that the WSGI should be kept as simple as possible. But I do not realy see the point of it when I still have to write server specific code just in order to get hold of the parameters ( which is apart from the reply the most profane task of a dynamic web-page )
# Florian

I use the cgi module to parse the request, specifically the query string. This is one of cgi's undocumented features (well, it's only documented in cgi.py, in the docstrings). I pass it an explicit environment (which includes the query string) and file-in. It will work quite well with mod_python -- it's not using stdin or os.environ. Though an application coded for mod_python might be a bit harder, as such an application might use mod_python features that WSGI doesn't include.

It's expected that you won't code your application to WSGI directly, but use some framework or library to make it a bit easier to work with. The cgi is one such library, though it's not a very good one.
# Ian Bicking

I must admit to have been a bit disappointed by the WSGI drafts. The first thing I noticed was that the documentation was confusing; 2 examples are given that are 'Much the same thing' except it quickly becomes apparent that no, they're quite different and use different approaches. I think that draft needs looking over by a neutral third party who is going to hammer it into something more readable. The second thing was that I couldn't really see this benefitting a lot of people. As a web application developer currently using mod_python, this doesn't help me significantly. After all, 'freeing' my application from the mod_python/Apache dependency is another way of losing me the other benefits it brings such as smart module reloading, easier HTTP status handling, automatically parsed URIs and query strings, session management and so on. If someone was to standardise those features across various webserver implementations - features that PHP and ASP users take for granted - then I would be much happier.
# Ben Sizer

I agree that a standard of the more high-level tasks would add much to the usability, yet it makes the standard harder to implement for the maintainers of web-frameworks.

Maybe it would help to see this as a sort of first stage standard, which is later extended to a wsig 1.1 that includes some more features. This way wsig is still easely implemented, yet it offers a specific way to the next step, as soon as the respective maintainer has some more spare time.
# Florian

I would like to second Ben and Florian!!
Does any one know why under "Thread Suppor" it say "provid the option of running an applicaiton in a single-threded fashion"? I don't understand why this "*should*" be an option.
This is awsome can't wait!
lhj
# Lateef Jackson

Folks, the place for discussing the PEP or proposing changes is the Web-SIG mailing list.

But as long as I'm here, I'll answer the question about "single-threaded", by quoting the PEP:

"""so that applications or frameworks that are not thread-safe may still be used with that server."""

Anyway, "shoulds" are recommendations, not requirements. A server can fail to provide this facility and still be considered conforming.

As for the examples "that are 'Much the same thing'", I agree that it should be rephrased to say that the two examples produce the same output, but are implemented differently, using a variety of WSGI features.

As for the looking over by other persons, I've previously asked for diffs/patches proposing rephrasings; only one person has actually given me any thus far, although Ian has at least also provided suggestions in in-line replies. This thing is over 1000 lines long now, and it's getting more and more difficult to find stuff when people say, "oh the stuff about X and Y was confusing", especially if they don't propose an alternative phrasing!

Anyway, I've submitted an updated draft to the PEPs editor, so it will be in Python CVS soon, which will make it easier to make and use patches.

Finally, I should mention that at this stage, the benefits of WSGI are primarily for web *framework* authors, and web *server* authors, not web *application* authors. This is *not* an application API, it's a framework-to-server glue API. It doesn't compete with any existing framework APIs.

It does, however, form a basis for future web APIs to be "plug-and-play" and "mix-and-match". But that day is still a ways off, and we won't reach it if framework and server authors don't implement this first stage.
# Phillip J. Eby

A couple points:

Phillip is working on another draft, mostly trying to make some of the text easier to understand.

Thread support: I think it's a little weird too, as it's mostly just broken if you are running without threads in a single process. I'm not entirely sure how well this would support an asynchronous application, which would allow single-process, single-thread concurrent programs. Right now environ['wsgi.input'] only is specified to have a blocking interface (AFAICT). This may be the only place that's a problem, and an extension could allow interested programs to avoid that. Right now I don't believe there are any Twisted people actively giving feedback on this, which is too bad.

Features (or lack of): as the PEP says, this isn't meant to be a replacement framework, rather its a foundation upon which you can build frameworks (or port frameworks). This doesn't preclude featureful frameworks built on top of WSGI in any way. Most of the features you note from mod_python could be implemented just as easily on top of WSGI. There are some features that wouldn't be supported -- like mod_python's ability to put hooks into different places of the request, do a local redirect or recursive redirect, etc. But even in these cases, mod_python could provide extensions to provide these features as well, the spec specifically allows for these kind of extensions.

The value added with WSGI is not that suddenly you will have great new features. Instead, it's a foundation so that when developers add new features, they can share them outside of their personal framework. Or, when there are new server targets, those too can be used with other frameworks. I think this can lead to a more organic development of standards -- when people are able to choose features and implementations in a more granular manner, they can be more discriminating. This way we can slowly get past diversity, as people choose the best solutions for particular aspects of the system.
# Ian Bicking

"""I think it's a little weird too, as it's mostly just broken if you are running without threads in a single process."""

That model is often adequate for two scenarios:

1) Debugging an application in a single-user mode, and

2) Running a desktop application whose UI is via a web browser.

These are important uses of HTTP that shouldn't be left out.
# Phillip J. Eby

Web Frameworks/Servers differ by features and performance.

But there's a common ground to all, in that they accept requests and deliver content. Nowadays most frameworks also feature cookie-handling, authentication and session-persistence.

I see web-applications explicitly adressed in this PEP, and therefore I also see this rather as a unified interface on top of which I can write web-applications, then as a way I can deal with web-servers as a framework writer.
# Florian

Your run_with_cgi handler has some problems, primarily with using \n instead of \r\n.
# Peter Hunt