Getting started with pip/virtualenv

If you find yourself in a situation where you have to work with multiple Django projects on the same system, where each one requires a specific version of Django(and some other libraries), or even specific version of Python(2.5/2.6..), the combination of virtualenv and pip will make your life easier.

virtualenv is tool to create isolated Python environments.

pip is a Python package installer, much like easy_install. It’s complementary with virtualenv; you’ll use pip to install, upgrade, or uninstall packages in isolated virtualenvs.

In this post, I’ll show a simple workflow that will give you the basics on how to use these tools to manage multiple Django projects.

Installation

First, get these tools installed on your machine. If you have easy_install set up, you can install pip by just issuing the following command

sudo easy_intsall pip

Now install virtualenv, using pip itself

sudo pip install virtualenv

Creating virtualenvs

Now that you have them installed, let’s try creating some virtualenvs. It’s good to have a specific location on your machine where you would have all the virtualenvs. I personally like to have them under ~/.virtualenvs directory.

Create the directory

mkdir -p ~/.virtualenvs

Navigate into it

cd ~/.virtualenvs

Create a virtualenv

virtualenv -p python2.5 --no-site-packages projectA

The ‘-p’ option specifies which version of the Python interpreter you want to use for the virtualenv(In case you have multiple in your system). If not specified, the default interpreter will be used.

The ‘–no-site-packages’ option means do NOT inherit any packages from /usr/lib/python2.5/site-packages (or wherever your global site-packages directory is). Use this if you don’t want depend on the global packages and want more isolation.

Finally ‘projectA’ is the name of the virtualenv, named after the project itself(not a rule, just a good convention).

You’ll see the directory projectA created once the command prompt returns. This is the virtualenv, feel free to explore it.

Activating/Deactivating the virtualenv

Once pip have finished downloading and installing the packages, hopefully without any glitches, activate the virtualenv

source ~/virtualenvs/projectA/bin/activate

You should see “(projectA)” in your command prompt.

To deactivate it type ‘deactivate’ in your prompt and hit enter. The “(projectA)” should disappear.

So now you have an isolated and functional environment for your Django project. You should go ahead and create a new virtualenv with more recent versions of Python/Django as your homework.

I hope you’ve got the basics properly. Check out the online docs to learn more advanced usages of these tools.

In the next post, I’ll talk about virtualenvwrapper, a tool that makes managing multiple virtualenvs a little easier.

Django: How to make a variable available in all templates

Sometimes when building a web application with Django, you have a common piece of information that is available at all the templates. Foe example, you may have a dynamically built tree menu appearing in multiple templates.  It’s possible to achieve so by adding the data to the context of each template. But that goes against Django’s policy on code reuse. The right way to do that, is to use template context processors and ReuestContext objects.

The sections on Django official documentation are either too short or under misleading headings. So I’m trying to write this in a paint-by-numbers sort of way.

First, the template

Let’s suppose you have the following silly piece of HTML in each of your templates

Hello World! My name is {{name}}

Next, create a custom context processor

Under the directory of your Django application create a new file. Let’s name it ‘custom_context_processors.py’. This is your custom context processor, that will list a number of methods, each of which will have a HttpRequest object as parameter. Suppose you want to have a variable named ‘domain’ available at all template. Let’s add a method to the processor by that name:

define name(request):
   return {'name': 'Django Guru'}

Install the Context Processor

Open settings.py. Add the following line in the TEMPLATE_CONTEXT_PROCESSORS

'myapp.custom_context_processors.domain,'

Add the RequestContext

In your views.py, import the RequestContext module

from django.templates import RequestContext

Now when you render the template using render_to_response() method, a RequestContext object has to be added as the optional context_instance argument. The RequestContext object takes a HttpRequest object as a parameter

def my_view(request):
   #view code
   return redner_to_response('my_template.html', {'foo:bar'}, \
                              context_instance=RequestContext(request))

The variable {{name}} will now be available in my_template.html, without explicitly adding it in the template context. If you need to make it available in some_other_template.html, all you need to do is to pass the RequestContext object as the third parameter to render_to_reponse().

Deploying Django application on mod_python and Mini Mac

Server  : Apache 2.2
OS      : Mac OS X 10.5.4 
Python  : Version 2.5.1
Django  : Version 1.0.2 final
Machine : Mac Mini

mac finder

Mod_python is a loadable Apache module which embeds the Python interpreter, so Python code can be run in-process by Apache. To deploy and run your Django application in an Apache web server you have to

  1. Download and install mod_python
  2. Load it in Apache
  3. Configure Apache to run the Django app.

In this post I’m going to share my experience on how to do all that on a Mac Mini that runs on OS X 10.5.

The Software & Hardware

Here was my system configuration

  • Server  : Apache 2.2
  • OS      : Mac OS X 10.5.4 
  • Python  : Version 2.5.1
  • Django  : Version 1.0.2 final
  • Machine : Mac Mini running on 2.0 GHz Intel Core 2 Duo processor with 2GB RAM

1. Get the mod_python source

Check out the mod_python source code from the remote SVN repository*

$ svn co https://svn.apache.org/repos/asf/quetzalcoatl/mod_python/trunk/ mod_python_src/

*The reason I’m downloading the source from an SVN trunk and not from the Apache website, is because the source available at the later one isn’t properly patched for Mac Mini’s architecture. In my earlier attempts, when I downloaded and built mod_python from stable releases, Apache was failing to start whenever the mod_python module was being loaded using the LoadModule Directive.

2. Build the source

$ cd mod_python_src

$ ./configure --with-apxs=/usr/sbin/apxs

$ make

$ sudo make install

3. Configure Apache to load mod_python when it starts

Open the Apache configuration file

$ sudo vi /etc/apache2/httpd.conf

Add the following line to the file 

LoadModule python_module libexec/apache2/mod_python.so

Now restart Apache

$ sudo /usr/sbin/apachectl restart

4. Configure Apache for Django 

Let’s suppose you have a Django app callled “mysite”. Copy you the directory to the Apache DocumentRoot

$ cp -r /path/to/mysite /Library/WebServer/Document/

Add the following lines to the httpd.conf file

<Location "/mysite">

    SetHandler python-program

PythonPath "['/Library/WebServer/Documents'] + sys.path"

     PythonHandler django.core.handlers.modpython

     SetEnv DJANGO_SETTINGS_MODULE mysite.settings

PythonAutoReload On

PythonDebug On

</Location>

This’ll make Apache to route any requests under URL “/mysite” to the mod_python handler. It passes the value of DJANGO_SETTINGS_MODULE so mod_python knows which settings to use.

Now restart Apache and go to the site http://localhost/mysite

If it works then congratulations! You’ve just deployed your app on Apache!

Troubleshooting tip(s)

If Apache fails to launch after you’ve installed and loaded mod_python, run it in debugging mode

$ sudo /usr/sbin/httpd -X

Look for any error message printed in the terminal, copy it and google it. You may find a solution online.

You should also check out