Building a Python Web Application, Part 1
Recently, I’ve been interested in writing web applications in Python, and one of the fun things that I discovered was the Python Web Server Gateway Interface, which is a standard interface for Python web servers, web applications, and something called middleware which can sit between the two.
One of the coolest things about WSGI is the fact that you now don’t have to decide on a specific web server before you start coding. In fact, the Python wsgiref module comes with a built-in simple web server which allows you to start coding up your web application with nothing but a bare install of Python 2.5 (or higher, of course)!
There are plenty of overviews of WSGI out there, so I won’t bother creating yet another in-depth explanation. What I will do, though, is show you how easy it is to get started.
Your basic “Hello, World!” application can be accomplished, server and all, with as little as the following:
def handle_request(environment, start_response): start_response('200 OK', [('content-type', 'text/html')]) return ['Hello, World!'] if __name__ == '__main__': from wsgiref import simple_server simple_server.make_server('', 8080, handle_request).serve_forever()
So what’s going on there is that the simpleserver passes each request to the handlerequest function, which calls start_response with the HTTP status code and a list of tuples of header names and values.
Then, an iterable is returned. This iterable will be iterated through for the output to send to the browser. In more complex applications, this iterable would most likely be a generator or some sort (a function which yields values or a generator expression, perhaps), rather than simply putting the entire output into a list.
The environment parameter contains all the information that any regular web application might need such as request information, server information, and any extra values set up by previously run middleware.
Using the basics we have from above, and a couple of nice utility functions from wsgiref.util, it’s a simple step to add a bit more and make this a full-fledged mini-framework.
from wsgiref import util from string import Template # Templates wrapper = Template(""" <html><head><title>$title</title></head><body> $body </body></html> """) four_oh_four = Template(""" <html><body> <h1>404-ed!</h1> The requested URL <i>$url</i> was not found. </body></html>""") # Template Variables for each page pages = { 'index': { 'title': "Hello There", 'body': """This is a test of the WSGI system. Perhaps you would also be interested in <a href="this_page">this page</a>?""" }, 'this_page': { 'title': "You're at this page", 'body': """Hey, you're at this page. <a href="/">Go back</a>?""" } } def handle_request(environment, start_response): try: fn = util.shift_path_info(environment) if not fn: fn = 'index' response = wrapper.substitute(**pages[fn]) start_response('200 OK', [('content-type', 'text/html')]) except: start_response('404 Not Found', [('content-type', 'text/html')]) response = four_oh_four.substitute(url=util.request_url(environ)) return [response] if __name__ == '__main__': from wsgiref import simple_server print("Starting server on port 8080...") try: simple_server.make_server('', 8080, handle_request).serve_forever() except KeyboardInterrupt: print("Ctrl-C caught, Server exiting...")
This now handles different URLs by rendering the wrapper template with the variables from the corresponding item in the pages dict, or it sends a 404 page if the requested page doesn’t exist (or if there are any other exceptions, actually).
With the addition of a templating engine and some way to get at your data, this would be something resembling a real web application.
For now, that’s all you’re getting out of me, though. I’ve shown that it’s pretty easy to get started with Python web development without anything but plain-ol-Python at your disposal, putting off choices on things like what server to use so you can get to the important part of actually writing some code. I’ll probably do another post in the next few days, probably starting to use some third-party packages to really start developing something useful.
Until then, if you want some more, see the WSGI tutorials at the link I posted above, especially A Do-It-Yourself Framework, which gives you a bunch more information of parsing requests, sending response headers, and using middleware. Keep in mind that some of the code there is Paste-specific, not that that is a bad thing. Since Paste is intended to be fairly lightweight it won’t really limit your options if you use it, and it doesn’t make sense to write a whole bunch of code to do the mundane parts from scratch anyway.
Tags: Python, web applications, wsgi

June 27th, 2008 at 2:52 am
Mate, your site is totally messed up in Opera!
June 27th, 2008 at 5:37 am
ehm…ya…/* no comment */
.
June 27th, 2008 at 7:47 am
No No No .. just download web2py and type:
def index(): response.title="Hello There" return dict(message=P("""This is a test of the WSGI system. Perhaps you would also be interested in""", A("this page",_href="this_page"),"?")) def this_page(): response.title="This Page" return dict(message=P("""Hey, you’re at this page.""",A("Go back",_href="index")))June 27th, 2008 at 8:00 am
Your blog is also completely messed up in Safari.
June 27th, 2008 at 8:03 am
@Timmy: I’ll have to take a look at that, I’ve not tested it with Opera at all.
@Andreas: Yeah, I suppose I didn’t put any comments in there, I guess I’ll go back in and add some. Oh, and that should’be been # no comment
@Max: Well, yes, if this had been “Building a Python Web Application using web2py”, but it’s not. The idea was to show that you can do it fairly easily without having to download any third-party applications. Also, that doesn’t seem to be a complete example, where’s the WSGI in that and where does it actually start serving things up? Your example is not a standalone web application, mine is.
June 27th, 2008 at 8:09 am
@James: Uggh, I suppose I need to look at my site in browsers other than Firefox, eh?
June 27th, 2008 at 8:20 am
Thanks for this article, nice easy intro to wsgi.
I also have to note: Ignore Max, web2py blows long and hard.
June 27th, 2008 at 9:57 am
Page also laid out incorrectly in IE7…
June 27th, 2008 at 10:21 am
Nicely written article. Hope the series continues.
June 27th, 2008 at 10:28 am
@pib: Actually, I think Andreas meant “”" no comment “”"
June 27th, 2008 at 10:36 am
Using opera 9.50 and it looks fine to me.
June 27th, 2008 at 11:05 am
Dude, nice article. Pd. Your site looks messy in Safari 3.1 on Leopard.
June 27th, 2008 at 2:10 pm
pib, I agree. Your article is in fact quite excellent. The problem I see is that while Python is an excellent language for web development (because of wsgi) most of the examples posted out there scare non-python programmers away, they are too low level. This is the point I tried to make with my comment and with my work. I do not think we should encourage people to program at this low level because they may create very insecure applications (no url validation, no input validation, no secure cookies, no escaping of output, etc.) Python may get the same bad reputation as PHP does. We need to encourage people to use a high level framework (web2py or Django or TurboGears, etc.) that will give access to the power of python but that will take care of many issues for them. There is no progress if we all start from scratch. There is progress we all “stand of the shoulders of giants”.
June 27th, 2008 at 8:13 pm
[...] PIBlog » Blog Archive » Building a Python Web Application, Part 1 (tags: python webdev wsgi webapp) [...]
June 27th, 2008 at 8:51 pm
@Max: I agree that starting completely from scratch is probably not a good idea. However, I wouldn’t say that we need to encourage people to use high-level frameworks. Or at least, we don’t need to encourage people to use entire high-level frameworks.
That’s the nice thing about wsgi, you can take bits and pieces from all over the place and glue them together with relatively little effort.
Unless you’re creating an application which fits perfectly into the model of a given framework, it will probably take you less time to make your own framwork which matches your needs exactly. Not from scratch, but from existing standalone pieces. Otherwise, you’ll end up spending a large chunk of time working around quirks in the framwork you’ve chosen, or even worse, you’ll find yourself locked into a given framework even when it proves to not fit as well as another would.
This is especially bad when you run into issues of scalability. If you make your application out of loosely coupled components, you can easily swap out the chunk that doesn’t scale well. With some framworks, this (swapping out bits and pieces) can be difficult to do.
In my next post on this subject I’ll be going into more detail of using preexisting components to build you own application, so you’ll see I’m not advocating building a whole application at such a low level. This starting post was just to give an idea of what will lie below everything.
June 27th, 2008 at 11:34 pm
[...] PIBlog » Blog Archive » Building a Python Web Application, Part 1 (tags: python webdev programming wsgi webapp web) [...]
June 28th, 2008 at 6:05 pm
Pid, it depends on the goal. If the goal is to develop simple web applications than it is fine to take bits and pieces from different sources. I personally do not think there is much progress this way. I think we need few stable frameworks so that wen start developing complex plugins and specifications so that we can start programming at an even higher layer that any of us do know. Let’s say I see a web app that has a nice widget. I want to be able to get the widget (literally grab it from the web page) and paste it into my app and it should just work. We’ll never get there if people we continue bottom-up development. web2py API have been frozen for 8 months (we only add features and fix bugs, but never break backward compatibility) because we going to move to the next level.
June 28th, 2008 at 7:16 pm
I would also say that it’s not just if the goal is to develop simple web applications.
Another perfectly acceptable reason is education.
By developing my own fairly complete (albeit simple) framework, I can better understand how things work at a lower level. This will, among other things, help me to make a good decision about what framework to use for more complex applications.
June 29th, 2008 at 3:34 pm
[...] PIBlog » Blog Archive » Building a Python Web Application, Part 1 Recently, I’ve been interested in writing web applications in Python, and one of the fun things that I discovered was the Python Web Server Gateway Interface, which is a standard interface for Python web servers, web applications, and something called m (tags: blog.paulbonser.com 2008 mes5 dia28 at_home Python web blog_post) [...]
July 2nd, 2008 at 9:59 am
[...] más en: Building a Python Web Application, Part 1. Archivado en Diseño Web, Miniblog, Programación Deja aquí tu comentario ↓ [...]
July 7th, 2008 at 7:44 pm
[...] Building a Python Web Application, Part 1 (tags: python web wsgi programming blog) [...]
July 24th, 2008 at 9:40 am
One odd thing, to stop the server (at least under Windows) I have to press Ctrl-C and reload a page before the server loop will exit. This is the same behavior that you see under Google’s AppEngine; maybe they are both using simple_server, I haven’t checked.
December 30th, 2008 at 12:02 am
Hi, I am a newcomer with Python using. So do somebody know to configure python site-package run on the web browser?
On my local machine i have installed PHP running on port 80, and how do i configure python run the other port??
Please kindly help me as possible.
Thanks,
ChanHan Hy
May 15th, 2009 at 1:31 pm
Ha. I Googled for “developing web apps in python” and your blog entry was the third result. Rock on Paul!
November 19th, 2009 at 10:12 pm
Apart from the obvious bugs in your code [ url=util.request_url(environ) should be url=util.request_uri(environment) ] this is not a bad article.
January 14th, 2010 at 7:34 am
Nice article Paul – are you ever going to write “Part 2″? I’d like to see it, as this was a useful intro for a new Python programmer like me trying to make some headway into writing a web application. I have a whole list of apps I want to work on, and I’d like to get the “under the hood” understanding that will let me integrate the components I want to use with the least amount of pain required when debugging, scaling up, and writing version 2, outsourcing maintenance, etc… Thanks again for this intro, it has pointed in me in the right direction (I think.)
June 5th, 2010 at 4:26 pm
Exellent,thank you for giving such content.