Friday, October 2, 2009

Managing Django Dependencies via SVN

One of the things that's been somewhat of a small hassle in working with Django/Python is managing dependencies across multiple developer machines, especially through an SVN managed project. Whenever a new dependency is needed, we've ended up doing 1 of 2 things:

  • Adding the name of the package to a text file which can be "easy_install "
  • Copying the zip/bz/exe to a folder "dependencies"
In both cases, what normally happens is Developer X will add a dependency to the repo. Developer Y at some point does an SVN update, and pulls down the code Developer X committed. Developer Y runs his runserver and BAM! not found! So then Developer Y has to go and look in the "dependencies" folder and try and figure out if he needs to run an easy_install or run an exe or whatever.

Obviously a rather inefficient task. I had heard about systems that will do automatic dependency installing, but the problem I had with that is that sometimes you have dependencies that are just a single file, and other times a whole package, others are in Pypi, etc.. The packages come in a huge crazy mess of ways. I wanted something consistent.

My (somewhat hacky) Soultion
Create a 'dependencies' folder that lives inside the project root (mine is named "_dependencies"). This folder will hold everything needed by Django (except Django itself) that would normally go in 'site-packages'.

When the Django app starts, have this path added to the Python path, so that libraries can be installed to it, instead of ..\Python26\Lib\site-packages. This allows dependencies to be setup in a folder that everyone pulls down via SVN. Bingo!

There are mainly 2 times when we need to make sure that dependency path is available:
  1. When we're doing a management task (including runserver)
  2. When the production site actually handles a task via Apache or whatever
To accomplish both, I came up with the following code:

# manage.py (before Django loads itself)

import os
import sys

def set_dependency_path():
dep_root = os.path.join(os.path.abspath(os.path.dirname(__file__)), '_dependencies')
if not dep_root in sys.path:
sys.path.append(dep_root)

set_dependency_path()


# __init__.py (the main, root init)

from manage import set_dependency_path
set_dependency_path()

0 comments:

  © Blogger template 'Minimalist G' by Ourblogtemplates.com 2008

Back to TOP