Pylons Project MiniCon
Last Friday (April 29, 2011) I had the privilege of giving a presentation at the Pylons Project Mini Conference in downtown San Francisco, organized by Whit Morriss from Survey Monkey. The event was a resounding success, especially given that it was put together in all of 2 weeks. The program was strong, featuring talks by Ben Bangert (founder of the Pylons Project) and Chris McDonough (author of the Pyramid web framework, the current centerpiece of Pylons Project software), as well as a number of other Bay Area Python luminaries.
Pylons and Pyramid was at the center of things, but was far from the only focus. In fact, of the 7 pre-scheduled presentations, only 3 (Ben's, Chris's, and mine) were explicitly Pylons-related; the rest touched on topics of general interest to the Python web-dev community such as continuous integration, writing code that is portable across different Python interpreters, and behavior driven development. It was a great time, educational and fun, and it was I think quite valuable in generating more cohesion for the Bay Area Pylons community. My thanks go to all of the speakers and sponsors, but especially to Whit, who planted a seed for the idea at PyCon and put in many hours to see it through to fruition.
The Mini Conf was followed up by two days of sprinting, which I unfortunately was not able to attend. There will also be a similar event held in New York on June 10-12, so if you're interested keep an eye on the pylons-discuss mailing list for details.
My presentation was about my experience at Mochi Media experimenting with porting a large suite of Pylons 0.9.6 applications to Pyramid. The slides are available (in pure HTML format using S5, hooray!), but as is common they're a bit cryptic without the accompanying presentation, so I'll provide an overview of the major takeaways for the hapless reader who didn't happen to make it to the event or watch the webcast. (I've heard a rumor that the videos may eventually be made available for viewing, but as of writing this they are not yet on-line, alas.) So, without further adieu, the takeaways:
Don't port if you don't have to
There are a few good reasons to port your application from the older Pylons framework to Pyramid. Maybe you're trying to build an app for which Pylons isn't a good fit, something that needs the extensibility that Pyramid gives you. Maybe Pylons is a bit too slow for you; Pyramid has a smaller call stack for simple request / response cycles and is designed for performance much more so than Pylons was. Or maybe you've got some extra capacity, and you just want to try it out for fun and to learn about Pyramid.
However, it's important to realize that Pylons, the framework, isn't going anywhere. If you have a Pylons app that works well, it's going to keep working well. In fact, because Pylons is now in maintenance mode, your Pylons app will keep working well much longer than it would have if Pylons was still evolving. The easiest work is the work you don't have to do, so why mess with a good thing?
Most of your code will continue to work
Both Pylons and Pyramid have similar, fairly minimal scopes. They gain functionality from a number of underlying libraries, the same ones in many cases (e.g. WebOb, beaker, Paste, mako). All of the business logic and persistence work in your application is done in your own code, in your own way, and that same code and those same patterns will continue to work. Additionally, the people behind Pyramid have put a lot of effort into making certain Pylons-like idioms available. pyramid_handlers is an add-on package that allows you to register "handlers", which are analogous to "controllers" in Pylons parlance. Akhet is a project that provides a number of other Pylons-like niceties (URL generator, template context variables, etc.), as well as a paster template that will generate a project skeleton organized similarly to how a typical Pylons project is put together.
You'll be able to keep using the same libraries. There's even a clever hack where you can implement a NotFound exception handler view in Pyramid and use it to invoke a Pylons application. This way you can implement part of your app in Pyramid, delegating to the original Pylons code when the user makes a request for which Pyramid has not yet defined a view callable, allowing for a gradual migration.
There will be lots of boring, detail-oriented work
While the overall construction, organization, and logic of your application will remain very similar, there are a lot of small adjustments that need to be made. It's mostly pretty straightforward, it's just tedioius. The URL generation doesn't work identically, so any place you dynamically generate a URL in your code (which should be pretty much every internal link in your application) you'll have to visit by hand to tweak the call. Route definition uses a slightly different syntax that you have to convert by hand. Request, response, and config objects are all imported at Python module scope in Pylons, made available via the black magic of "stacked object proxies". In Pyramid these objects are available via different mechanisms. You can always get to them in one way or another, but you'll have to visit every function that uses these objects and explicitly make them available to your scope. In Pylons, values on which the route is matched are passed as args to the controller methods; in Pyramid, for performance reasons, you to fetch these from request.matchdict. And so on. Nothing mind-bending, but lots that is painstaking.
The internet is your friend:
Again, thanks to Survey Monkey, Whit, and everybody involved for putting together a great event. Look forward to the next one!