Stoppers, change and transition plans

How many blog posts have started with some variation of “It’s been too quiet around here”, followed by an apology? Too many. This might be one of those, but I learned a long time ago not to apologize for creative lulls. The process is inherently too fickle and just can’t be counted upon.

Truth is, I’ve been writing a lot, I just haven’t posted anything. The reasons are kind of dumb, but mostly there are several “big” pieces getting in the way. I’ve somehow convinced myself that those pieces are foundational to putting other pieces in context. It sounds ridiculous, but there it is. Essentially, I’m creatively constipated, there’s lots in the pipe, but nothing’s getting out.

Nice metaphor there.

In my own head I’ve been calling these things “stoppers”. Until said whatever-it-is is completed, I can’t move onto the next one. I have a piece mostly written about this, but, of course, that too is stuck behind a few other pieces. Curiosity doesn’t schedule, and I find myself drifting off and starting numerous new projects before the old ones are completed.

This site is going to change soon, and somewhat radically. I’ve got a piece half-written about that too. I want to strip things down, remove the barrriers (this is a theme) and get back the joy of making for the web– it’s not just about writing.

Welcome to the stopgap.

This is my near-term plan going forward, I’m not setting any time frames or due dates because there are just too many unknowns and outside interruptions. Right now, this is my intent, but things might always change.

I’ve been tired of WordPress for years, but felt stuck and was never quite sure what to do about it. The current plan is to switch to either Octopress or Jekyll. These should allow me the freedom to write when I feel like writing, hack when I feel like hacking, and create whatever crazy half-breed functional post I want– a current near-impossibility without substantially gutting WordPress.

Technically there’s nothing wrong with WordPress, it’s unarguably better than it’s ever been. But, as a full-fledged platform, it brings it’s own innate complexity. I don’t want to have to deal with that extra level of middleware, I just want to make stuff.

But there’s one big stopper: Both Octopress and Jekyll are Ruby projects. A few years back, feeling burnt out and very tired of PHP, I sat down to learn either Ruby or Python. I chose Python.

I do know about the Hyde project, which started as a Python port of Jekyll, but I didn’t have much luck experimenting with it and the Octopress/Jekyll communities are much more active. Sure I could potentially jump in and contribute to Hyde, but I don’t have the personal bandwidth and would rather start out with a mostly-working framework instead of trying to hack around and fix another which doesn’t quite meet my needs.

As a way of tip-toeing into the Ruby garden, I’m rebuilding a friend’s site using Jekyll. It involves some backend hacking and is letting me get my hands dirty with a small data set.

In the meantime, I’ve started writing everything using Markdown. I first tried Markdown a very, very long time ago–2006-ish–but gave it up because I wasn’t sure it would stick. It stuck.

For implementation during the transition, I’m using the Markdown on Save plugin. This was written by one of the lead WordPress devs, so I trust it’ll work without screwing everything up. Also, since I’m dealing with a somewhat large dataset, the conditional formatting checkbox is a smart solution.

Finally, I’m trying to approach all my writing with an exit strategy. Once I’ve got something down, I immediately start thinking about how to finish it and get out. Editing is no longer just about clarity and polish, it’s a means of escaping from a death spiral.

There’s plenty more I’ve been doing which I’ve been remiss in sharing. Lots of research into health, nutrition, movement, anthropology, running, feet and a bunch of other stuff I’m forgetting. I’m looking forward to having my voice back.

Existential note: Just as I clicked publish, Safari decided to crash.

Building Python on Shared Hosting

Why are there so few Google results for “Build Python on Shared Hosting?” Because it’s so ridiculously easy that it took me longer to write this post than it did to download, configure and compile Python 2.7 on two different shared hosting accounts.

These are the steps:

$ mkdir -p ~/opt/python-2.7
$ mkdir ~/src
$ cd ~/src
$ curl -LO
$ tar -xzvf Python-2.7.tgz
$ cd Python-2.7
$ ./configure --prefix=$HOME/opt/python2.7
$ make
$ make install

Next, create ~/opt/bin if it doesn’t exist already and symlink the new Python binary:

$ mkdir -p ~/opt/bin
$ ln -s ~/opt/python-2.7/bin/python2.7 ~/opt/bin/python

Finally, be sure your $SHELL’s $PATH is configured to look for binaries in ~/opt/bin. I use Bash, so I added the following line to ~/.bashrc:

export PATH=$HOME/opt/bin:$PATH

Ok, so why bother?

I’m lazy. I wanted to save myself a bunch of calls to file.close() by using the more modern with open syntax. Most shared hosts seem to consider Python unimportant, the two I use have Python 2.4.3 installed which is six years old. I couldn’t even import __future__ because __future__ hadn’t been written yet.

Waylan Limberg’s post about installing multiple versions of Python was helpful.

Update: Much has changed in a few years and Python support is finally coming around. A2 Hosting, whose shared servers run cPanel, has a page featuring Python shared hosting. Great to finally see all of this happening.

Django via CGI on shared hosting

Django just isn’t designed to run under CGI.
It won’t run under OS/2, either.*

Well ok, but running Django under CGI is not impossible. It just kind of really sucks. But anyway, to prove it’s possible if not workable, here’s how I got it running on two standard cPanel shared hosts using plain old slow and clunky CGI.


First, install virtualenv. This makes locally managing modules fantastically easy by creating self-contained Python virtual environments. Installing couldn’t be simpler: Get the script, run the script, source your environment.

$ mkdir ~/src && cd ~/src
$ curl -LO
$ tar -xvzf tip.gz
$ python virtualenv/ --distribute ~/python_virtualenv
New python executable in /home/joe/python_virtualenv/bin/python
Installing distribute.............................................

$ source ~/python_virtualenv/bin/activate 

Now, install Django using pip, which was automatically installed by virtualenv. After sourcing the virtual environment, this works from anywhere.

$ pip install Django
Downloading/unpacking Django
  Downloading Django-1.1.1.tar.gz (5.6Mb): 5.6Mb downloaded
  Running egg_info for package Django
Installing collected packages: Django
  Running install for Django
    changing mode of build/scripts-2.4/ from 664 to 775
    changing mode of /home/joe/python_virtualenv/bin/ to 775
Successfully installed Django

If your host doesn’t block GCC, use pip to be sure your MySQL interface (MySQLdb) is up to date:

$ pip install -U MySQL-python
Successfully installed MySQL-python

Django requires MySQLdb version 1.2.1p2 or higher.

Yolk prints a nice, clean list of everything installed in your Python environment, install and run:

$ pip install yolk
$ yolk -l

Django          - 1.1.1        - active 
MySQL-python    - 1.2.3c1      - active 
pip             - 0.6.1        - active 
setuptools      - 0.6c11       - active 
yolk            - 0.4.1        - active 

At this point, I started a new Django project, assigned a database and filled in the necessary values in I put the Django project files into the virtual environment to keep everything in the same place. This might not be the best practice, but it makes sense to me.

$ cd ~/python_virtualenv/
$ startproject testproject

The sane part is finished, now onto the kludgery.


All the CGI shim solutions I found pointed back to a script Paul Sargent uploaded to ticket 2407 back in summer of 2006. It still works: django.cgi

Three lines need editing:

Line 1: Point the CGI’s shebang to the virtualenv Python binary.


Line 95: Add the directory above the Django project directory to Python’s sys.path.


Line 97: Add the project’s settings to os.environ.

os.environ['DJANGO_SETTINGS_MODULE'] = 'testproject.settings'


For Django to respond to URL requests, those urls need to be fed into the django.cgi script. For testing I routed everything from /django to the cgi script by adding the following lines to my top-level htaccess file:

RewriteEngine on
RewriteRule ^cgi-bin/ - [L]
RewriteRule ^django/(.*)$ /cgi-bin/django.cgi/$1 [QSA,L]

The second line isn’t necessary unless pulling Django urls from the webroot, without it, the redirects would loop.

At this point, the Django site should load from /django/… urls.

Finally, as a quick fix for admin media files, I symlinked Django’s admin media directory from my web root:

ln -s ~/python_virtualenv/lib/python2.4/site-packages/django/contrib/admin/media ~/www/media


I spent quite a few hours spread across a couple days researching and figuring out how to get the first install working. The second installation only took about 5 minutes from start until editing Django’s admin pages.

Running Django through CGI is possible, but it is dog slow. There appears to be some caching after the first request, but that first page load often takes an excruciatingly long time.

Further reading, possible improvements

The servers I was working with are both running the almost six year old Python 2.4.3. The wsigref module was introduced with Python 2.5. My goal was to get Django running without compiling anything since some hosts deny access to GCC.


These sites were helpful in figuring this out.

The two hosts I tested on were LiquidWeb and A2Hosting. Both have been excellent, dependable hosts. Neither has any Python support to speak of on their shared plans. A2 blocks access to GCC.