Wednesday, November 16, 2005
Fab Magic
Recently Jamie and I did some fairly major refactoring of fab, our "invented here" Python web framework. I think we made some interesting additions and I'm fairly excited about developing our future web applications with it.
Most of the new features are supported by some pretty magic python hackery, which always evokes strong feelings of pride amongst programmers. I particularly like the uniform handling of HTTP GET/POST and our so-called "path arguments". Path arguments are really just segments of the requested URL that we treat as parameters -- this method usually looks a lot cleaner than GET arguments and can often accomplish the same thing. All of this is facilitated by our favorite HTTP wrapper, CherryPy, but I think the layers we've added on top of CherryPy are significant and helpful.
This is probably best explained by a small example -- a blog. A request to read posts for today might look like this:
http://www.mrshoe.org/blog/2005/11/16Assuming this blog is kept entirely in memory fab can handle this request in a few lines.
class BlogPage(fab.FabPage):
template = blogTemplate
def control(self, page, year, month, day):
page.blogtext = blogdata[year][month][day]Now imagine you want to make a search phrase bold throughout the post. Such a request might look like this:
http://www.mrshoe.org/blog/2005/11/16?bold=pythonTo handle this you could write:
class BlogPage(fab.FabPage):
template = blogTemplate
def control(self, page, year, month, day, bold=''):
text = blogdata[year][month][day]
page.blogtext = text.replace(bold,
'<strong>%s</strong>' % bold)This is a simple example, but it demonstrates the use of both path arguments and GET arguments. The interesting part is how fab passes these arguments to the application. They are passed to the
control method. Path arguments are normal positional arguments (which are a direct analog to segments of the URL, really), and GET/POST arguments are keyword arguments (also a very natural mapping). It gets better. Fab is smart enough to know what you do and don't care about. Any arguments you specify in the control method's signature will get passed along. Anything else will be ignored. Any arguments you expect but are absent in the request are assigned the value of None. Initially this system struck me as being a little too magic, but in practice it's very useful. If someone requestshttp://www.mrshoe.org/blog/2005/11/16?
bold=python&foo=barI don't care about the
foo argument. My control method doesn't use it for anything. If they requesthttp://www.mrshoe.org/blog/2005/11/16/baz?
bold=python&foo=barI don't care about the
baz. Why display an annoying error message? Just give them the blog post they're looking for. If, in the future, I decide to add more fields to the form, all I have to do is add more keyword arguments to the control method and voila, fab will pass along the relevant data -- no more, no less.I've been using this method for a couple weeks now and it has proven to be easier and more elegant than any web development I've done in the past.
I hope I didn't just provide you all with a starting point for hacking MrShoe.org... of course you would never try something so sinister, right?
posted by David Shoemaker @ 4:09 PM 5 comments

5 Comments:
Wahttehhog Admin (Matt) said...
Hey how did you get the Blogger bar at the top of the page to disappear? Is this because your blog is hosted elsewhere??
Oh, also, as you can see from my display name, my name is Matt and I've got a small clan known in the online community as The Wahttehhog. We make movies and films and game modifying for the Halo (among others) communities.
My clan's blog: www.wahttehhog.blogspot.com
I'd really like to know how you made the Blogger bar disappear!!
David Shoemaker said...
Click on the "Template" tab of the Blogger interface to edit the template. There is a drop-down there where you can turn the NavBar off. Also make sure the NavBar isn't in your actual template. My template is pretty bare-bones because my blog is integrated with the rest of my site, so I've forgotten what a default Blogger template looks like, but it's possible that the NavBar is in there (at the top).
schwerwolf said...
What kind of security considerations did you make when starting this fab project? I think it's dangerous to recklessly use arguments appended to the url in code.
Wahttehhog Admin (Matt) said...
Thanks. I'll try it.
Wahttehhog Admin (Matt) said...
There wasn't a button to disable the NavBar at the top of the blog. (Under Templates)
Too bad, then again, I had used a standard default template (which I later modififed)...
Couldn't I just edit the template code? I've tried before but I didn't know what the NavBar code was...
Post a Comment