In many discussions about “what does Ruby on Rails got that the Python community doesn’t got?”, a growing consensus is that a combination of CherryPy (controller), SQLObject (model), and Cheetah (view/templating) is part of the answer. In fact, a developer from the CherryPy project has started Subway, a Rails clone, using those three packages. Subway hasn’t made an official release yet, and I’m impatient, so I was curious how far I could get with just those three packages alone.
Cool Rails Feature #1: Directory Structure
While viewing the CherryPy tutorials, I noticed one called “bonus-sqlobject.py“. It looks like it has all three pieces of the holy MVC trinity there in one file. I really like the way Rails enforces a solid directory structure on your application, so I went about breaking out bonus-sqlobject.py into a Rails-like folder structure. This was easy to do. (screenshot)So-so Rails Feature #2: Scaffolding
Like everyone else on the planet, I watched the famous 10 minute setup movie and marveled at how database schema changes automatically were reflected in the GUI with a simple browser page refresh. That magic is partly provided by the scaffolding code and generator scripts. The scaffolding code is a surprising “hook” to pique your interest, but I’m not really interested in that. It’s not interesting because very quickly on, you’ll want to and need to replace the scaffolding with your own controller and view code. The rails guys have been saying the same thing for a while.Cool Rails Feature #3: SQL Table Introspection to Define Model
The other piece of magic in the 10 minute setup movie was the SQL introspection in ActiveRecord. It lets you make a change in the database and see those changes instantly reflected in your model’s definition. SQLObject lets you do the same thing. So I modified CherryPy’s SQLObject tutorial to use the database schema to define its structure.
class Contact(SQLObject):
_fromDatabase = True
That looks pretty “Rail-ish” to me.
Cool Rails Feature #4: No “XML sit-ups”
This one must be important, since it is mentioned in bold at the top of the Ruby on Rails site. I have experienced the pain of “XML sit-ups” first hand. Trying to figure out APE’s XML configuration for database mappers and gateways is not easy. ‘Tis a very un-pythonic experience. I fear the Zope 3 and its ZCML is on its way to XML sit-up infamy, as well.However, I think CherryPy has Rails beat on this one… A separate configuration file is totally optional. Sane defaults are stored as a dictionary data structure, but are easy to over-ride either programmatically or with your own configuration file.
Cool Rails Feature #5: Easy Install
Like everyone else in the known universe, after I watched the 10 minute movie, I followed along with O’Reilly’s “Rolling with Ruby on Rails” tutorial.It really was as easy as 1-2-3… (Assuming that the MySQL install was step zero) . :-) 1) Install Ruby via “one-click” self-installer. 2) Install Gems via “one-click” self-installer. 3) c:> gem install rails –remote
Python has a “one-click” installer for the Python language distribution, but everything else took a little more work to get setup. I have hope that Eggs, easy_install, and PyPI will become as useful and productive as Perl’s CPAN and Ruby’s GEMs. But until then, Rails has CherryPy beat on ease-of-install.
Here’s what I installed for my CherryPy app: (most hyperlinks link to .exe installers or tarballs) 1) MySQL 4.1.12 2) MySQL-Front 3.2 3) Python 2.4.1 4) MySQLdb 1.0.0 (driver)* 5) SQLObject 0.6.1 6) Cheetah 0.9.17 7) CherryPy 2.1**
Steps 4 through 7 will someday be replaced by: a) install easyinstall b) c:\easyinstall subway
- I had problems with MySQLdb 1.2.0 on Python 2.4 and SQLObject– saves weren’t getting committed to the database. I downgraded to MySQLdb 1.0.0 and things started working again. So I figured out how to avoid the problem, but I don’t know what caused the problem.
** CherryPy 2.1 is currently only available from /trunk in the subversion repository. I’ll explain below why I took a snapshot of their code instead of an official release.
Cool Rails Feature #6: Live Auto-Reload
This is the real secret sauce. Most dynamic languages do not require a compilation step before you can execute your code. This gives the developer a good boost in productivity compared to languages that do require compiling and linking (C, C++, Java, and C#). However, when you’re making rapid changes to code to web apps in Python, you often have to stop and restart your web server to pick up the new changes you made. I have to do this all the time in Plone, and it’s annoying. Yet another cool feature demo’d in Rails’ Academy Award winning 10 minute setup movie is the ability to make “live” code changes in your running application. Make a change in your code, then click refresh in your browser, and boom– instant gratification.CherryPy 2.1 will provide this same live auto-reload feature by default when it’s released this summer. The code is already available in the subversion repository, and a recipe was posted to the project wiki on how to use the feature.
Since CherryPy 2.1 is still unreleased but available as the /trunk branch in the project’s repository, I fired up my svn client and ran the command: c:/temp/cherrypy21> svn export http://svn.cherrypy.org/trunk
At the time, I picked up revision #386.
I implemented the auto-reload recipe for my CherryPy application without much effort. It’ll be nice when this is done for me in the official release, but it wasn’t hard to do myself. And now that I’ve done it, you can just copy my example. :-)
Summary: Rails has the lead, for now… But I’m not jumping ship from Python, yet.
Ruby on Rails has more finish and polish, but I think I am starting to find proof to refute the claims that “this wouldn’t even be possible without using ruby on rails”. Most of the Rails innovations (packaging, simplicity, and dynamicity) can be implemented in Python without much extra effort.I eagerly look forward to CherryPy 2.1’s release, but oddly, I’m not really feeling the anticipation for whatever is coming from Subway… It looks like Subway is focused on scaffolding code and Paste integration. I would prefer to see a focus on ease of installation and fancy earth-shatteringly beautiful 10 minute setup movies, instead. (And I will sheepishly admit, I still don’t “get” Paste. Sorry, Ian.) In the future, my version of scaffolding would simply be a search-and-replace job in all the text files in my CherryPy app.
Files used
contact.zip 18.6KBScreenshots< /> 1) Directory structure 2) Welcome Page 3) Contact – Index 4) Contact – Edit 5) HelloWorld Form 6) HelloWorld Result



Nice work.
I don’t get the point of Paste either, but I do get WSGI. Paste seems to be a repository for some nice WSGI bits, some of which you can attach as middleware in front of CherryPy’s wsgiApp (though some you can’t yet, like paste.errormiddleware because CP traps its internal exceptions.)
Link | June 30th, 2005 at 1:56 pm
What’s your thoughts on all the convenient glue in Rails? Like form generation, automagically mapping form params to a @params hash,
rendermethods, etc.All things that should (since I’m sure one way or another, most anything could be added technically) be added to a Python version eventually, or are they too “magical” and not explicit enough?
I think lots of those utils are a big part of what makes Rails attractive to people and speeds up development. A common Cherry (and others) counter-argument though is repeated claims for a barebones framework: thin, light, etc. I tend to imagine everyone is writing these util methods themselves over and over though… but writing your own version of everything does seem to be the Python-way (yes that’s both a dig and a compliment).
Nice job though, I think you could easily attract more contributors if you wanted to – I get the impression many others are still unclear on paste/subway as you mentioned.
Link | June 30th, 2005 at 2:28 pm
ToddG, CherryPy also automagically maps params from a form into variables you can use in your form… I was pleasantly surprised how straight-forward that is…
However, when I look at things like Tiddlywiki.com, I start to think the server has no business generating forms… The server should only provide a data structure (XML, YAML, JSON, etc.), and let JavaScript in the browser handle building the user interface around that data.
With tools like Selenium (my baby) for cross-browser/cross-platform fucntional testing of my fancy AJAX/Javascript interface, I have less to fear of JavaScript.
I’m not a member of the CherryPy project, but the code is good, and it looks like a well run project… It feels very easy for newcomers like me to plug in and contribute.
The only thing I see most Python projects missing compared to Rails is a bombastic, over-the-top, cheerleader. :-)
Link | June 30th, 2005 at 4:37 pm
> CherryPy also automagically maps params from a form into variables you can use in your form
Right, as keyword args though, yes? I kinda meant like:
@user = User.new(params[:user])
without having to assign each attribute from a keyword arg to a constructor or object. Maybe this is doable by passing kwargs or something, I’m python-rusty.
> The only thing I see most Python projects missing compared to Rails is a bombastic, over-the-top, cheerleader.
Does that mean you’re volunteering? ;-) It’s worked well for Rails!
My very anecodotal observations have been that people from PHP thought Rails was cool and put[ing] together an implementation, people from Perl thought so and put together Catalyst, which looks pretty thorough, and people from Python seem to focus on complaining about DHH and Rails. Well okay it’s getting better, but wow the jealousy in python-land was pretty overwhelming for a while, and there is still some bitterness lingering IMHO… ah competition among geeks… love it.
Link | June 30th, 2005 at 5:32 pm
Great article.
CherryPy stays out of the way so programmers can wire things up anyway they want. A Rails framework gets in the way.
After 3 years with Zope/CMF/Plone, the last thing I want is another framework to fight.
CherryPy taps directly into Python’s power. The only thing I would like to see, is a way for to share utilities/Products, like ToddG mentioned, and like you can in Zope.
Link | June 30th, 2005 at 6:37 pm
Actually, the params are delivered, named, to the function bound to that page. Your example would then turn into:
def create(self, name):
user = User(name=name)
….
Link | June 30th, 2005 at 6:39 pm
> CherryPy stays out of the way so programmers can wire things up anyway they want. A Rails framework gets in the way.
Isn’t this post basically about using SQLObject and Cheetah with CP as a “Rails framework”?
Link | June 30th, 2005 at 9:39 pm
Technium and ToddG, regarding form keywords and param maps, check out the CherryPy FAQ. (They can be keywords or a param map)
http://www.cherrypy.org/wiki/CherryPyFaq
“”"Is there a good way to deal with having a variable number of s on your form / forms in your html page, so you dont have to have every single input parameter in your method argument list as a keyword? Would it be good to have the parameters passed to the method with an python list that holds all the parameters, rather than have separate individual python strings passed to the method? Here is how I’m faking it for now:
“”"
class Website:
def doChanges(self, args, *kwargs):
print cpg.request.paramMap # prints each paramater name with its value
Link | June 30th, 2005 at 10:49 pm
ToddG, Rails gives newbies a nice clean on-ramp. A “Rails-like” CherryPy app could do the same… The nice thing about CherryPy is that you can easily jump the tracks and blaze your own trail if you feel the framework is too stifling.
Link | June 30th, 2005 at 10:54 pm
Jason – Totally, I agree. And I’d love to see a “R-L CP” — despite some [seems to me] inconsistencies in Python, for some reason I just prefer the feel of Python to Ruby; but at this point Rails is pretty compelling. Do you plan on continuing to hack away on this?
As for Rails, some people just use the ORM part; someone recently used the controller package to tie an XUL/Mozilla frontend with XML food recipes as the data with a javascript state machine; there’s a pluggable ZPT-ish template package (amarita?), etc. Plenty of opportunity to pick and choose what you want to use [or not]. I can see CP might be a bit more comfy for using alone as it has kind of grown up on its own… but give poor Rails a fair shake ;-)
I’m gonna look into that paramMap workaround as well, thanks for the pointer. And for stimulating this conversation in the first place.
Link | June 30th, 2005 at 11:59 pm
Oh, I’m willing to give Rails a fair shake. I was pretty jazzed about Rails after going through the O’Reilly tutorial. And even day-dreamed a bit how I could rake in the cash like the 37signals dudes with a simple Rails app and a blog. :-)
I, too, saw that XUL/Mozilla food recipe app. That was cool. This is it, I think: http://www.zedshaw.com/blog/programming/ruby_xul.html
I liked the guys commentary at the end about “Oracle, Oracle, Oracle”… I feel the same way. Most of our “enterprise” apps at ThoughtWorks run on Oracle, and to play nice, I’d prefer my Rails-like CP app to use Oracle as well. Alas, SQLObject doesn’t support Oracle, yet… But, Rails does… Tough choices. I could help with the SQLObject/Oracle effort, use MySQL/PostgreSQL and write an inter-db interface… or just use Rails.
Link | July 1st, 2005 at 1:07 am
I don’t know why it’s been so freakin’ hard to get anyone to write an Oracle backend for SQLObject. It’s not rocket science, but no one ever finishes anything.
Anyway, Paste really is all the bits I can’t find places for. But it’s also all the bits that could apply to more than one framework. You can write reusable code for Zope 2, CMF, Zope 3, etc. And you can write code that is available completely as a library, not participating intimately in the request. But Paste is the only project I know of that even attempts to have code that can apply to anything; it can’t fully fulfill that yet (e.g., Zope isn’t available as a WSGI application), but as WSGI is increasingly adopted it should be nearly free.
But this is only really interesting if people actually use WSGI to make interesting things, and that’s only barely started to happen, which has been a bit frustrating for me.
Link | July 1st, 2005 at 1:48 am
”I had problems with MySQLdb 1.2.0 on Python 2.4 and SQLObject– saves weren’t getting committed to the database. I downgraded to MySQLdb 1.0.0 and things started working again. So I figured out how to avoid the problem, but I don’t know what caused the problem.”
This is caused by an infortunate API change in mysqldb 1.1.6+ (but required to better fit to the DBAPI2 spec). Just upgrade to version SQLObject in trunk or wait for SQLObject 0.7. :)
Link | July 1st, 2005 at 6:37 am
Oh, found what I was poorly trying to explain way above:
http://wiki.sqlobject.org/dictionarymapping.html
from sqlobject import *
class Person(SQLObject):
firstname = StringCol()
lastname = StringCol()
Person.createTable(ifNotExists=True)
name = {'firstname':'Ian', 'lastname':'Bicking'}
Person(**name)
So it’d probably be easy to pull out the person fields from CP as a dict and pass to Person(), rather than explicitly passing all the named args. Also likely want some validity/sanity checks in the Person class… in fact maybe Subway already does this and I’m wasting time. Sorry.
I still think SQLObj and PyDO are a far cry from ActiveRecord, but perhaps someone’s got a secret PyActiveRecord project in the works. Or if I start now, it should be ready in about 5 years. Roughly!
Link | July 1st, 2005 at 2:38 pm
Reading your blog post reminded me once again that Aquarium seems to be the best-kept secret in Python web development. Taking the Rails features you mentioned point by point:
Directory Structure – Aquarium has had that for years due to its FreeEnergy philosophy.
Scaffolding – There was a companion app for Aquarium called Piranha which provided scaffolding but it hasn’t been maintained for years.
SQL Table Introspection to Define Model – Aquarium doesn’t have that, but it does have a DatabaseAssistant helper class that can be used by a developer’s “table classes. I suggested integrating SQLObject with Aquarium to Shannon Behrens the Aquarium Project Leader quite some time ago and had previously mentioned it in wikis and blog comments before then. SQLObject is the most obvious analog to Active Record, while Aquarium with its Python controllers and Cheetah templates is clearly analgous to Action Pack.
No “XML sit-ups” – Aquarium is XML-free. Its config file is basically a Python file declaring various properties.
Easy Install – Aquarium doesn’t bundle Cheetah even though it is dependent on it. Any required database drivers have to be installed separately as well.
Live Auto-Reload – Have to confess I don’t know where Aquarium stands on this front.
I’ve given Shannon some pointers in terms of creating screencasts of the in-house tutorials on Aquarium he gives. And his employer is currently looking to hire another Python web guy to work alongside him in California.
Link | July 1st, 2005 at 3:37 pm
>
> However, when I look at things like Tiddlywiki.com, I
> start to think the server has no business generating
> forms… The server should only provide a data structure > (XML, YAML, JSON, etc.), and let JavaScript in the
> browser handle building the user interface around that > data.
>
Interesting. What are your thoughts on Trimpath’s JavaScript Templates? http://www.trimpath.com/project/wiki/JavaScriptTemplates
Link | July 1st, 2005 at 3:54 pm
>
> I think lots of those utils are a big part of what
> makes Rails attractive to people and speeds up
> development. A common Cherry (and others)
> counter-argument though is repeated claims for a
> barebones framework: thin, light, etc. I tend to
> imagine everyone is writing these util methods
> themselves over and over though… but writing your
> own version of everything does seem to be the
> Python-way
> (yes that’s both a dig and a compliment).
>
You may be interested to know that Remi the CherryPy project leader is hard at work on CherryObject which will provide rich but optional functionality for those using CherryPy.
Link | July 1st, 2005 at 4:01 pm
One last thing, keep an eye out for http://django.sourceforge.net/ from the developer of http://www.chicagocrime.org Currently the best source of information about it is the Python wiki http://wiki.python.org/moin/Django
Link | July 1st, 2005 at 4:04 pm
I think you’ve covered the bases and came to pretty much the same conclusions I have regarding Rails and the CherryPy/SQLObject/Cheetah combo. Rails uses embedded Ruby code in the pages as the template system, and I actually prefer Cheetah to that setup. However, one thing that Rails provides that is not mentioned here is a bit more end-to-end (Browser-to-Server) support since Rails makes an assumption about the template system. CherryPy makes no such assumption and therefore provides no templating-specific features. (The Rails ajax stuff is what comes to mind here.)
Also, regarding Oracle support for SQLObject: I’ve touched both the sqlite and firebird connectors for SQLObject, and it’s pretty straightforward. If you know Oracle pretty well, you could probably write the code from scratch in a very short time.
Link | July 2nd, 2005 at 2:23 pm
Hey folks, I’m on vacation in Fisher’s Island, NY for the next week. My network connection is over pretty limited… will check in and respond to comments when I can… Interesting thread, eh? -Jason
Link | July 3rd, 2005 at 5:10 pm
Vacation? How dare you! ;-)
I dunno, in my short experiments with Aquarium I’ve found it very much like the word it describes — a container with lots of different varieties of things in it all moving around. I’m sure it’s probably pretty powerful if you know it well, but it just doesn’t seem as intuitive as Rails or Cherry as to what’s going on. It’s got the reverse Mason-like templating, creating screens which seems Struts-like, no obvious (included) DB solution, etc. All workable if you’ve got time to learn well and/or it’s your in-house framework – but not a compelling setup for increasing usage.
Django sounds quite promising – since it was developed over time and used/refined within projects, and IMHO, most importantly — developed cohesively, as a whole (i.e. its own MVC, not assembled pieces), it sounds like it has a lot of potential. All my .02 of course. Which is way less valuable than the work all these other people have put into the frameworks.
Link | July 4th, 2005 at 1:14 am
Oh – and Django’s site says July – right around or before Rails is 1.0 – that would be pretty great if a good healthy competition arose between them. I think everyone would benefit a lot, whether you prefer python or ruby flavor…
Link | July 4th, 2005 at 1:24 am
I was at the ChiPy meeting where Adrian Holovaty presented his chicagocrime.org site and the Django framework behind it… (Another cool reason to live in Chicago!)… I look forward to playing with Django when it gets released and seeing how it compares to Rails and CP. Adrian is hard at work getting all the legal ‘i’s dotted and ‘t’s crossed so it can be open sourced cleanly. One interesting story from the ChiPy meeting: when Adrian first saw Ruby on Rails, he thought, “Hey, that’s Django!”
Link | July 6th, 2005 at 8:29 am
Ha, cool. As both Rails and Django seem to have similar growth environments (developed/extracted from a big project) I suppose it’s not surprising they’d be similar.
I like Chi. Second favorite to my home (first city to your second ;-)
Link | July 6th, 2005 at 4:35 pm