Easy as (Cherry)Py

or “Refactoring a tiny web app in 2 hours”

Last fall I wrote a little web app (less than 500 lines) that ran on the wsgi_ref server that comes with Python.

Yes, I know wsgi_ref isn’t exactly intended for production apps, but I had my reasons. First of all, it was a very bare-bones report extractor/generator aimed at fewer than half a dozen users and I didn’t want to mess with any third party libraries, installation, configuration, etc. Also, after using wsgi_ref in some examples in The Quick Python Book, I was curious as to how useful it might be in a real situation.

It worked okay, and the people concerned were quite happy with their new web-based report extraction system. Of course, as often happens, the more I thought about it (and maintained the code), the less happy I was.

For one thing, the code was a little ugly… well, as I think about it, given it’s small size, it was a LOT ugly. URL’s had be mapped to code explicitly, and the the whole thing was no where near as modular nor as readable as it should have been.

So as I thought about refactoring the app, I decided to see how much work it would be to swap wsgi_ref for CherryPy. I’ve always had a soft spot in my heart for CherryPy – I used it for my very first web app some 7 or 8 years ago, and at PyCon 2009 my sprint time was spent on the very early stages of converting it to Python 3.x.

And as it happened my thoughts of refactoring pretty much coincided with Bob Brewer’s talk about “The Zen of CherryPy” at PyCon 2010. I recommend watching the video of his talk when you have the chance, but I’ll give you the first two points – “Common tasks should be fast and easy” and “Doing nothing should be faster and easier”. That matched my app perfectly, since, as Yogi might have said, 90% of my app was doing common tasks, and the other 90% was doing nothing.

So I was looking for three things: first, how easy is it to port an app from the wsgi_ref server to a server like CherryPy? and second, would it help me improve my code? and finally, does CherryPy follow the “Zen” as Bob presented it? Or to put all three in another way, is it worth the effort to use a server package like CherryPy for such a tiny web app?

Shortly after lunch on Friday (March 19) I grabbed CherryPy and installed it on our vTiger server. Following the tutorial, I shortly had a little demo app working. The next step was to move my main web code into a class. After that, each one of the if statements explicitly mapping a URL was recast as an appropriately named method.

Fortunately, I was smart enough to put the code that actually queries the database and massages the data into the desired report into a separate module, so it remained untouched. After adjusting some parameters and making sure things were correctly exposed, the  main report URL’s were working fine.

I had one entry form, and its HTML template needed a few tweaks. Reading the values from the form post (a common task) was dead easy – they just became parameters to the form action method. I also needed to change the response headers in one method to send a PDF instead of HTML, and that was a simple dictionary access of cherrypy.response. Again, a common task, easily done.

Finally, I needed to adjust the port number and make a couple of other minor changes to the configuration – a quick call to cherrypy.config.update took care of that. As to things like sessions, authentication, compression, etc, I didn’t want them, so I didn’t do anything. Doing nothing to do nothing works for me.

As to the answers to my questions, let me put it this way – my code is now much more modular and readable, and I got the whole refactoring done in time to make a three o’clock appointment.

CherryPy. Definitely worth it.


7 Responses to Easy as (Cherry)Py

    • Vern Ceder says:

      vTiger is okay… we chose it 4 years ago as the best completely open source CRM we could find at the time. (Sugar’s license wasn’t that open at the time.)

      We heavily customized it to track our admissions process and it’s done the job. The drawbacks are a somewhat opaque and complex (IMO) database schema, and some limitations in reporting. Since admissions is where a student first enters our sysemt, the vTigre database is pretty important. So most of my time is spent on extracting reports and generating exports from it to send to other packages.

      I’m not really happy with the way we adapted vTiger’s entities to our use, which isn’t vTiger’s fault, of course. Still, if I were doing it today, I’d start from scratch and use django, or maybe web2py.

  1. @vern Ah, interesting. Still would you recommend it for a small company with no IT department (to speak of) as a crm?

    • Vern Ceder says:

      Yeah, if they’re just doing CRM and staying within what vTiger does best, I would think it would be fine – the custom fields, picklists and reports should give enough flexibility in that scenario. I really have no complaints about it in terms of ease of use and basic CRM functionality.

  2. @vern

    Thanks. By the way, I’ve looked at web2py and like it. Don’t care much for django: not the way my brain swings.

    I love cherrypy: so simple.

    Lately looking at fapws. Verrry fast.

    • Vern Ceder says:

      fapws is interesting – on a quick look at the examples it strikes me as one step up from wsgi_ref. You still explicitly set response headers and URL mappings, but in a somewhat more organized and readable way. I see on the recent wsgi server benchmarks (http://nichol.as/benchmark-of-python-web-servers) that it’s a bit faster than CherryPy for what it does.

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.