Dueling Frameworks

Cue the music

In this corner, the time-tested CherryPy, standing at version 3.2, six years old, enabled for Python 3, sporting an HTTP 1.1-compliant WSGI webserver, support for other WSGI servers or adapters, a plugin mechanism, built-in tools and much more.

In the other corner, the newcomer Flask, at version 0.7.2, about one year old (but with older ancestry), claiming to be a “microframework … with good intentions” and “fun.”

In my post A Funny Thing Happened on the Way to the Webserver I mentioned I took a look at the second contender and liked what I saw. First impressions, as they say, can be deceiving. What may seem appealing is sometimes harder to use or disappointing when you get down to writing code and testing it.

Coincidentally, after I had decided on the “Dueling Banjos” theme, Audrey Roy pointed me1 to Richard Jones’ “Web micro-framework Battle!” which provided additional food for thought.

As you may expect, my selection criteria don’t exactly match Richard’s. Perhaps the most striking difference is how he implemented routing (URL mapping, page 14 of the presentation) for the baseline cgi+wsgiref implementation vs. my choice for doing dispatching in my minimalist WSGI database UI (see in particular, the dispatch methods in dbapp.py and film.py).

Like Richard, I don’t appreciate “magic” in a framework or application. but I’m less concerned with strictly RESTful URLs. Richard appears to prefer the decorator approach to URL mapping (as seen by his Bottle, Flask and Pesto examples, among others), but also used URL mapping tables (seen in the web.py, Werkzeug and baseline examples).

The latter approach reminds me of a generic menu interface I wrote eons ago in C. It may be OK for a vtable in C++, but I usually find it inappropriate for application level code. In fact, the mapping table seems “magical” since it doesn’t encapsulate the code with the corresponding URL.

Although Flask looked attractive due to its URL routing decorator, it now appears limiting because it can only be used on functions but not on class methods. (Note: I haven’t explored all of Flask, e.g., haven’t looked at its Blueprints).

As a result, refactoring the WSGI application to use CherryPy was quite straightforward, whereas changing it to accomodate Flask involved quite a bit of surgery. This is exemplified by these Git stats:

 cherrypy/film.py |   73 ++++++++++++++++-------------------------------------
 1 files changed, 22 insertions(+), 51 deletions(-)

 flask/film.py |  235 ++++++++++++++++++++++++++-------------------------------
 1 files changed, 107 insertions(+), 128 deletions(-)

While many modifications simply involved indentation and removing the self parameter, other changes were necessary. For example, as there can only be one mapping to a function named ‘index’, I had to rename the film.py ‘index’ function/method to ‘list’ to avoid conflict with dbapp.py. This does not bode well for extensibility: a real application would support multiple entities—films, actors, customers, etc.—with similar function/methods. Maybe this is what Blueprints are for, but why invent another wheel when Python classes are available?

There were other minor annoyances with Flask, like how to instantiate its application object without adding a subdirectory, or how to pass the database connection to the film.py functions without using a global variable.

I may continue to explore Flask, although at the moment CherryPy seems more suitable to my purposes. I’m also intrigued by some concepts of Richard’s winners—Pesto and Bottle. A Pesto-like dispatcher with support for class methods on top of CherryPy would probably make my day.

The code implementing the CherryPy database UI interface is on GitHub tagged as version v0.3.0 and the corresponding Flask code is also there tagged as v0.3.1.

1 BTW, +1 for Audrey’s wish list item: Python in the Browser (see pages 16-18 of her presentation).

11 thoughts on “Dueling Frameworks

  1. Yes! Some well deserved CherryPy love.

    Haven’t had the time to articulate something interesting about Richard’s talk but CP is a tad different and as you stressed very mature yet one of the few Python 3 compatible contender!

    If you are interested in using a Redis backend for CherryPy session cherrys (my baby :P).

  2. I found CherryPy works extremely well for multiple interfaces. Especially command line interfaces, web interfaces, and app interfaces. Since a CherryPy app is just an object, it doesn’t have to have an web specific stuff cluttering it up. It also seems to make it very easy to unit test. Again, since they are just python objects it fits in well with standard unittest frameworks. There are no other web frameworks that let me make applications with web interfaces, app interfaces, and command line interfaces using the same object. The simple fact that you can write them just as python objects makes them elegant enough to provide a lot of flexibility.

    Of course, I know many people do not need to make multiple interfaces for their apps. Or they don’t need to use the standard unittest frameworks since they have special test frameworks built into their web framework. It’s just an interesting thing cherrypy gives you from using the python object model at its core.

    • Completely agree! Have you played with the CherryPy webtest class? Not very well documented but pretty cool for functional testing in a web context.

      • Hi EuGeNe, No, I regret to admit that I haven’t yet ventured much into automated web testing except at the web page level, but unit and functional testing are definitely in the near horizon.

  3. Pingback: Joe Abbate: Dueling Frameworks | Python | Syngu

  4. Pingback: Database Redesign and User Interface Refactoring | Taming Serpents and Pachyderms

  5. Pingback: Dueling Frameworks, revisited | Taming Serpents and Pachyderms

  6. Pingback: Database User Interfaces – Pagination | Taming Serpents and Pachyderms

  7. Pingback: The Future of Pyrseas: Part 3 | Taming Serpents and Pachyderms

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.