Nicolas314

All my geeky stuff ends up here. Mostly Unix-related

Fast Python webapp

leave a comment »

Just spent the last few days trying to find the fastest way to put together a Python webapp. Not an easy task, especially since documentation on the topic is really abundant and (I found) rarely self-sufficient. I ended up choosing what I believe is the most straightforward alignment of code to get a Python webapp up and running in minutes, and make it portable to production mode without efforts.

web.py

web.py is the simplest Python framework there is. Straight and to the point: you can program very basic stuff but if you really want to, you can add templates and database and model-view-controller design as you see fit. The basic hello world in web.py would be:

 

!/usr/bin/python
import web

class hello:
    def GET(self):
        return 'Hello world'

urls = ('/', 'hello')
app  = web.application(urls, globals(), True)

if __name__=="__main__":
    app.run()

 

Cannot get simpler than that! URLs are mapped to callables by regexes, which gives you perfect flexibility for URL design. Your classes can implement different methods for GET and POST, keeping closer to the real REST philosophy. Without having to install any further software you can immediately test your app by running:

 

python hello.py

 

web.py is friendly enough to embed its own (pure-Python) web server for test purposes. Debug mode is also automatically activated in that mode so you will be able to get usable messages when things go wrong during development.

lighttpd

I have spent a lot of time with lighttpd now, browsing documentation (I even bought the book!), parsing the source and even participating on their forum. Now is time to get my return on investment. I just found out that lighttpd can launch web.py-based apps directly in fastcgi mode without need to write your own boilerplate code to convert fastcgi to wsgi. Here is a minimal lighttpd configuration that just works:

 

server.port = 8080
server.modules = ("mod_fastcgi", "mod_rewrite")
server.document-root = "/home/www/"
fastcgi.server = ( "hello.py" =>
    (( "socket" => "/tmp/fastcgi.socket",
       "bin-path" => "/home/www/hello.py",
       "max-procs" => 5
    ))
    )
url.rewrite-once = (
    "^/sta/(.*)$" => "/sta/$1",
    "^/(.*)$" => "/hello.py/$1"
)

 

The above specifies a fastcgi handler called ‘hello.py’ that is always called thanks to the last rewrite rule, except for stuff located in /sta which is directly served by lighttpd. /sta is where you are going to store your served static content like images and css.

In production you can launch a bunch of lighttpd front-ends and configure them to talk to a fastcgi app possibly located on another server or farm of servers.

Took me quite a while to converge to this simple solution. Other paths I reviewed where:

  • Apache+mod_wsgi: too heavy
  • cherokee+uwsgi: cherokee is really nice but uwsgi is an ugly duckling
  • lighttpd+SCGI+flup+cherrypy: works but heavy and boilerplate code is ugly and un-maintainable

Not saying the other solutions are bad, they are just not as straightforward.

Advertisements

Written by nicolas314

Thursday 7 October 2010 at 11:24 pm

Posted in python, webapp

Tagged with , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: