I’ve been meaning to write about Commandant for ages. I started it last year because I wanted to write command driven applications with a user experience just like Bazaar. There are several things that I like about Bazaar’s user interface:

  • You only have to know that the program is called bzr to start discovering it, because its default behaviour is to teach you how to use the builtin help system.
  • Each command has a clear name that makes its purpose easy to discern.
  • Each command has a succinct summary and a well written long description, along with clear information about the arguments and options the command accepts.
  • Help topics provide general information about the program that isn’t command-specific. The topics describe conceptual and technical aspects of the program that help the user better understand how to use it.
  • The interface conventions are very simple. It doesn’t take long to figure out how things work.

I wanted, as much as possible, to start writing application logic without having to do much work to get a working user interface. With that in mind, the basic goal for Commandant is to provide a Bazaar-like user interface with the least effort possible. I started by trying to extend Bazaar but I ran into tricky integration problems that made it hard to make progress, so I switched gears and started implementing the logic from scratch. Reinventing the wheel got me further than trying to integrate, but I quickly reached a point where progress slowed down because I had to deal with tricky problems that Bazaar had already solved. In the meantime, Robert landed changes in Bazaar that removed the integration hurdles that I’d run into.

With the integration problems out of the way, I stopped wasting time reinventing the wheel, and Commandant is now a thin layer on top of bzrlib itself. Being able to take advantage of the work that has been done in Bazaar has been a blessing. There’s more that can be done to improve Commandant, but it is very usable in its current state. If you’re interested in learning more, the README file should get you started.


People ask me questions about Storm several times a week, and I’m happy to help where I can, but it would be better if the information our users need was easier to find. Our documentation story is weak and, as a result, Storm is harder to discover than it ought to be. If you do run into problems or have questions, please hop into #storm on Freenode and we’ll do our best to help you. I want to improve the documentation situation, but finding the time to do so hasn’t happened yet. The next best thing is to post some helpful hints here.

First, some advice: if you don’t know what SQL query you want to run, using Storm will probably be hard. When I get asked a question about writing a query using Storm I almost always respond with, “What does the query you want to run look like?” The querying part of Storm is essentially just an expression compiler that takes a list of expressions and converts them to SQL. Once you know what end result you want, working backwards to figure out the Storm parlance is relatively straight forward.

Today I was asked about using COALESCE. The person asking the question found the storm.expr.Coalesce expression but it wasn’t obvious how to use it. He knew he wanted to run a query like:

SELECT * FROM table WHERE COALESCE(col1, col2) = 'foo'

With that knowledge, figuring out how to use Storm was quite easy:

store.find(Table, Coalesce(Table.col1, Table.col2) == "foo")

Furthermore, Coalesce is just a helper expression to aid usability and readability. If we didn’t have a built-in Coalesce expression the query could have been written using the generic storm.expr.Func expression:

           Func("COALESCE", Table.col1, Table.col2) == "foo")

If you want to use a SQL function in a Storm query, and there is no built-in expression for it, you can use Func to call it.

Today I gave a talk about Storm to the fine folks that make up the local Python users group. I think the talk went alright. It wasn’t awesome but I don’t think it was terrible either. It’s the third public talk I’ve given, pretty much ever, and so I have a lot to learn about the process. The group is friendly and I felt comfortable standing up in front of everyone and yammering on about Storm.

In retrospect, I should have come up with much better example code. I didn’t make enough time to prepare and, due to rushing at the end, the topics I covered were rather basic. I did an experiment and wrote a psuedo-doctest to use as slides. The doctest and a script to run it are available at lp:~jkakar/+junk/storm-talk. I used a slightly hacked version of Michael Hudson-Doyle’s very awesome console-presenter, which is available at lp:~jkakar/console-presenter/two-line-separator.

The format was great for getting me to focus on content, even though I didn’t have enough time to do a great job preparing it, but the slides were a bit lackluster being grey text on a black background. Also, a common problem with doctests is that you need to keep track of the state of the program as you read the document. I think this problem made the format awkward for the audience. It was a good experiment, but in the future I’ll use traditional slides, and try to avoid a situation that requires the audience to keep program state in their head as the talk progresses. Funny how these things seem so obvious in hindsight.

Doug Latornell gave a nice talk about his experiences using PyYAML, flickerapi and Tkinter to build an application that displays random photos on his living room TV, both from his personal collection and from his favourite groups on Flickr. I enjoyed the talk and the discussion it spurred.

All in all it was a good experience and from which I’ve learnt some lessons, which I can hopefully use to make the next talk better.

Yesterday I released version 0.16 of Storm. This release fixes some memory leaks and introduces a handful of new features.  The number of changes since 0.15 aren’t vast, but we’re trying to get into the habit of releasing regularly, so hopefully this will become a trend.  The release notes have detailed information about the changes along with links to the MD5 sum and GPG signature for the tarball. I’ve also built official packages for Ubuntu users, available in the Storm PPA.

Unfortunately, the karmic and lucid packages don’t work properly because they install files in /usr/lib/python2.6/site-packages, which is no longer included in sys.path by default. In the next couple of days I’ll build new packages that correctly install files in /usr/lib/python2.6/dist-packages, which should fix the problem. For now, adding the site-packages path to sys.path or including it in PYTHONPATH will workaround the issue.

We’re always interested in hearing about your experiences with Storm.  If you have comments or questions please feel free to hop into #storm on Freenode and chat us up, or post a message to the mailing list.

Hello, world!


For some time I’ve wanted a place to write about nerd-related things. This blog is the designated space for that kind of thing.