I decided to take a bit of a detour from My Crusade for Agility and write about something that has had a huge impact on my Python coding lately. When I first began professionally developing in Python I was in a place where the entire code base was proprietary. Since that time, a lot has changed. The first change was the introduction of jQuery, then came Django, and shortly after South. Then, finally, the greatest single thing since slicing lists, Buildout. Buildout fits into a category of tools that a lot of developers could probably brush off. They may think, “I don’t need Buildout I can use pip, or I can accomplish that with symlinks, or I can manage dependencies manually because they don’t change all that often”. I, personally, can’t see myself ever writing another Python application without using Buildout.
Buildout offers a lot, and I have to give a huge shout out to Joe Kington who first introduced me to Buildout here, and also to Brandon Craig Rhodes who’s PyAtl demo showed me some of Buildout’s capabilities and really got me excited. Buildout is as simple as it is wonderful. Here is a really quick way to start taking advantage of Buildout’s greatness right away.
There are 3 things you need to get started.
bootstrap.py You can grab bootstrap.py from zope’s svn repo. bootstrap.py is a script that will download and set up buildout so there is nothing for you to install.
buildout.cfg buildout.cfg contains configuration for your buildout project. Here is an example of a simple buildout.cfg file. The buildout.cfg file contains parts, each part has a recipe. There are a lot of recipes available to choose from. The recipe is what buildout uses to know what each part does.
setup.py setup.py contains the dependencies that your project requires. Here is an example of a sample setup.py file. You can also, optionally define command line scripts that run within your buildout project.
So now you’ve got everything you need to start using Buildout. I set up my source control just like Brandon did in his example. All of my application code was in a src directory with bootstrap.py, buildout.cfg and setup.py being the only other files in the root of my source tree. After doing that, run the bootstrap.py script. It will generate a few files and directories. Then run bin/buildout (one of the files generated by bootstrap.py). bin/buildout will do all of the heavy lifting. It will fetch the recipes that your buildout.cfg is using, and it will also fetch all of your application’s dependencies. Once all of those things have been downloaded it will place them in a directory called eggs. The great thing about Buildout is that it doesn’t install all of these things on your system Python. It puts everything in your eggs directory and that’s it.
If your buildout.cfg is similar to this one you should end up with a few different things in the bin directory after having run bin/buildout. If you open one of those up and take a look, you should see right away how Buildout is able to download all of the dependencies that your application needs without needing to touch your system’s Python. It is adding everything in the eggs directory to the beginning of your sys.path. The great thing about doing it that way is that if I decide that I want to use Django from SVN or a new release of Django or an older release of Django the only thing I need to do is update the version number in my setup.py file and re-run bin/buildout. My eggs directory will then include two different Django eggs and it will only add the one the matches my setup.py file to sys.path.
In conclusion, Buildout is great because it gives you an extremely simple, consistent and repeatable way to create your entire environment on any number of developer machines, virtual machines, test machines, production machines, or continuous integration machines and you don’t have to worry about saying “DOH! I forgot to install module X on the production box”.