Learning out Loud in Milwaukee, WI

Flannel: A Python Project

I’m a big fan of learning new things in programming. It’s part of
why I tried running this blog on a static site generator only to get scared back onto WordPress, and why I’ll probably give SSGs another shot before swearing them off completely. I recently had the opportunity to work on a project in Python for work (in addition to a WordPress plugin) and it was an absolute thrill.

The Problem:

My client had a rather large WordPress site that relied on a home cooked theme, a few internally developed plugins, and a few plugins from the WordPress Plugin Repository. We also have a process for upgrading those plugins and WordPress core that is a bit more complicated than just hitting the ‘upgrade’ button in wp-admin. We also have a lot of users, not just registered users, but people who visit our website, too, who do not want the site going down, stop working, or unexpectedly changing dramatically. That is, we’re not facebook, we prepare our users for changes to their user experience. We had to maintain all those things but also make the deployment and upgrade process easier, faster, and less prone to human errors.

Thus was born a project to create a push-button deployment system. A single script that would package the whole site and only deploy if successful. Using a tool called fabric, so was born Flannel.

What the heck is a fabric?

The python project we used for this project is called fabric, a “command line tool for streamlining the use of SSH for application deployment.” It’s extremely powerful and I feel like I’ve only scratched the surface of what this sucker can do. Basically, it lets your remove yourself from this process:

$ ssh user@server

$ cd /path/to/application
$ # sudo ./deployment-script.sh
$ # sudo ./other-deployment-script.sh
$ ^d

Or writing shell scripts that look like this:

if [ ! -d /path/to/wordpress ]; then;
cd /path/to/wordpress
V=wp core version
  if [ V != '3.8.1' ]; then;
    echo 'WordPress is at the wrong version.'
    echo "It expected 3.8.1 but was $V."
    exit 1
if [ ! -d /path/to/plugins ]; then;
cd /path/to/plugins
# other deployment stuff

And replacing it with a process more like this:

$ fab deploy

And a script more like this:

def deploy():
  with cd('/path/to/wordpress/'):
    v = run('wp core version')
    if v != '3.8.1':
  except SystemExit:
      'WordPress is at the wrong version, it should be at ' + cyan('3.8.3') +
      red(' but is %s.' % v))

Much simpler, right? And that’s just for comparing WordPress’s version with what you expect it to be. All the stuff you normally run in the “more deployment stuff” part is stuck inside the fabric script and highly customizable depending on your configuration. You can even have it deploy differently to certain servers.

Flannel currently handles installing WordPress itself, and plugins and themes. More importantly, it allows you to do all management of those things, what version they’re installed at, whether they’re active, etc. from the command line, rather than wp-admin. It uses wp-cli to handle almost all those processes, and a YAML file for storing your configuration. It’s great for highly complex WordPress sites with many plugins grown in house or sourced from outside the WordPress Plugin repository (GitHub, GitHub Enterprise installs, etc.) and which might need to be deployed identically and continually.


My love for PHP has been wavering for a while now. I find even readable code difficult to parse, especially when templating without an engine like Twig (which WordPress should really adopt into core for themes, but that’s a blog for another day). People have told me that Python (and Ruby, too) is a ‘modern’ programming language and I never really bothered to care about the differences. That seemed like the kind of thing real computer scientists cared about: nuanced and esoteric for someone who just makes websites that work. But that was a severe oversimplification. Python is a ‘modern’ language because it does away with a lot of the punctuation required by languages like PHP. Do we really need to end every line with a semicolon? No! says python, just end them with a line break! Deeper than that, I have really appreciated how everything is an object in python. I now find myself wishing I could wrap my PHP variables in dir and have them magically introduce themselves in the debugger. Speaking of, can we get a pdb for PHP yet? Xdebug is getting a bit long in the tooth and var_dump($variable) is so annoying. Long story short, I’m loving python already.


One response to “Flannel: A Python Project”

  1. […] just spent weeks getting the Jenkins jobs to put the pieces in the right places and maintaining a Fabric project that could install plugins, update themes, and manage the version of Core we ran in production. The result was a well-functioning workflow to automate the deployment of […]