SaltyCrane Blog — Notes on JavaScript and web development

Notes on migrating this blog from SQLite to PostgreSQL using Django

Here are my notes on migrating this blog from SQLite to PostgreSQL. For the parts of my database that were in proper order, the migration was made very easy using Django's ./manage.py dumpdata and ./manage.py loaddata commands. However, the database tables used for storing the comments on this blog were kind of screwed up because I had previously migrated them from my old Blogger blog. So I had to write another (not so pretty) script for that.

Thanks to this article for showing me how to use Django's dumpdata and loaddata for this migration.

Create a new Postgres database

See my previous notes for creating a Postgres database. I named the new database "saltycrane_db" owned by "django_user" with password "my_password".

Clone and modify Django project

  • Clone my SaltyCrane project
    hg clone SaltyCrane SaltyCraneNew
    or
    cp -rp SaltyCrane SaltyCraneNew
  • Edit settings.py:
    DATABASE_ENGINE = 'postgresql_psycopg2'
    DATABASE_NAME = 'saltycrane_db'
    DATABASE_USER = 'django_user'
    DATABASE_PASSWORD = my_password'
  • Create database tables
    python manage.py syncdb

Migrate data

  • Create JSON dumps from the existing SQLite database for my 3 Django apps (myblogapp, comments, and tagging):
    cd /srv/SaltyCrane/iwiwdsmi
    ./manage.py dumpdata myblogapp > dump_myblogapp.json
    ./manage.py dumpdata comments > dump_comments.json
    ./manage.py dumpdata tagging > dump_tagging.json
  • Load the JSON data dumps to the new Postgres database:
    cd /srv/SaltyCraneNew/iwiwdsmi
    ./manage.py loaddata ../../SaltyCrane/iwiwdsmi/dump_tagging.json
    ./manage.py loaddata ../../SaltyCrane/iwiwdsmi/dump_myblogapp.json

However, loading comments didn't work because I had some missing fields so...

Migration script

...I wrote a migration script:

import setup_environment

import simplejson
from pprint import pprint
from django.contrib.comments.models import Comment
from django.contrib.contenttypes.models import ContentType
from iwiwdsmi.myblogapp.models import Post

JSON_FILENAME = "/srv/SaltyCrane/iwiwdsmi/dump_comments.json"
ct = ContentType.objects.get(name='post', app_label='myblogapp')
N_OLD_COMMENTS = 4000

def main():
    delete_all_comments()
    create_dummy_comments()
    pydata = open_json_file(JSON_FILENAME)
    save_items_to_database(pydata)
    delete_dummy_comments()

def delete_all_comments():
    """ Clears the database of all comments.
    """
    comments = Comment.objects.all()
    comments.delete()
    print "All comments deleted."

def create_dummy_comments():
    """ Create a bunch of filler dummy comments
    """
    for i in range(N_OLD_COMMENTS):
        c = Comment()
        c.comment = "Filler comment."
        c.content_type = ct
        c.ip_address = None
        c.is_public = False
        c.is_removed = False
        c.object_pk = 243
        c.site_id = 1
        c.user_email = "[email protected]"
        c.user_name = "Filler"
        c.save()
    print "Filler comments created."

def delete_dummy_comments():
    comments = Comment.objects.filter(is_public=False)
    comments.delete()
    print "Dummy comments deleted."

def open_json_file(filename):
    """ open the json file and return the python data structure
    """
    json_fp = open(filename)
    pydata = simplejson.load(json_fp)
    return pydata

def save_items_to_database(pydata):
    """ Process the python data structure and save to the new database
    """
    for item in pydata:
        pprint(item)
        pk = item['pk']
        item = item['fields']
        if item['is_public'] and not item['is_removed']:
            c = Comment.objects.get(id=pk)
            c.comment = item['comment']
            c.content_type = ct
            c.ip_address = get_ip_address(item['ip_address'])
            c.is_public = item['is_public']
            c.is_removed = item['is_removed']
            c.object_pk = item['object_pk']
            c.site_id = 1
            c.submit_date = item['submit_date']
            c.user_id = item['user']
            c.user_email = item['user_email']
            c.user_name = item['user_name']
            c.user_url = item['user_url']
            c.save()

def get_ip_address(ip):
    """ Handle bad input for IP addresses
    """
    if ip == "" or ip == "unknown":
        return None
    else:
        return ip

if __name__ == '__main__':
    main()

Example of hg convert on Ubuntu

Converting a Subversion repository to a Mercurial repository is very easy. Here's an example that uses hg convert to convert a SVN repository (django-tagging) to Mecurial on Ubuntu. I'm using Mercurial 1.3 on Ubuntu 9.04.

  • Install Subversion Python bindings. (This should solve the "Subversion python bindings could not be loaded" error)
    sudo apt-get install python-subversion
  • Enable the "convert" extension. Add the following to your ~/.hgrc file:
    [extensions]
    hgext.convert =
  • Convert:
    hg convert http://django-tagging.googlecode.com/svn/trunk/ django-tagging-hg
  • Update:
    cd django-tagging-hg
    hg update

Using psycopg2 with virtualenv on Ubuntu JauntyMaverick

Update 2009-11-02: Well I am dumb-- psycopg2 can be installed with pip/easy_install. The reason I got the error before was because I didn't have the required dependencies installed. On Ubuntu, I used apt-get build-dep. So, here's the summary:

Update 2009-11-11: My update doesn't work. See comments #4 and #5 below.

Update 2010-05-17: Here is what finally worked for me using Python 2.6 on Ubuntu 10.04 Lucid Lynx using virtualenv 1.4.8 and pip 0.7.1. Thanks to Daniel for the final piece of the solution.

Update 2011-05-13: Looks like the mx+virtualenv issue has been reported and fixed to be released in 2.4.2. via @psycopg's tweet

Update 2011-11-05: psycopg2 2.4.2 has been released with the mxDateTime fix so the install is very easy now.

Install dependencies

$ sudo apt-get build-dep python-psycopg2

Install pyscopg2 in a virtualenv

$ virtualenv --no-site-packages myenv 
$ source myenv/bin/activate 
$ pip install psycopg2 

No longer needed: $ easy_install -i http://downloads.egenix.com/python/index/ucs4/ egenix-mx-base



*** THE REST OF THIS POST DESCRIBES MY INITIAL OUTDATED SOLUTION. ***

I recently starting using virtualenv for creating isolated Python environments. Virtualenv has made it easy to manage different Python configurations for different websites, but I was slowed down a bit trying to use psycopg2, the Python-PostgreSQL database adapter, with virtualenv after upgrading to Ubuntu 9.04 Jaunty Jackalope.

Currently, virtualenv (1.3.3) doesn't find Ubuntu Jaunty's Python packages. In Ubuntu Jaunty, the default Python version changed from 2.5 to 2.6. More importantly, the site-packages directory was changed to dist-packages. Prior to Ubuntu 9.04, Ubuntu's Python packages, such as python-psycopg2, were installed to /usr/lib/python2.5/site-packages. Now Ubuntu's Python packages are installed to /usr/lib/python2.6/dist-packages. (See this discussion at the virtualenv group for more information.)

As a result of this change, virtualenv (as of 1.3.3) doesn't find Ubuntu's Python packages installed using apt-get. My solution was to create symlinks to the desired packages and egg-info files in site-packages. I'm not sure if this is the proper way to handle this. If there is a better solution, please let me know. One advantage of using this method is that I don't need to clutter my virtualenv with all the packages that have accumulated in my global site-packagesdist-packages.

Install easy_install, pip, and virtualenv

sudo apt-get install python-setuptools python-dev build-essential
sudo easy_install -U pip
sudo pip install -U virtualenv

Install Ubuntu's psycopg2 package

sudo apt-get install python-psycopg2

Symlink the psycopg2 (and mxDateTime) files

sudo mkdir /usr/lib/python2.6/site-packages
sudo ln -s /usr/lib/python2.6/dist-packages/psycopg2 /usr/lib/python2.6/site-packages
sudo ln -s /usr/lib/python2.6/dist-packages/psycopg2-2.0.8.egg-info /usr/lib/python2.6/site-packages
sudo ln -s /usr/lib/python2.6/dist-packages/mx /usr/lib/python2.6/site-packages

Create a virtualenv

virtualenv myenv

Check what's available

pip freeze -E myenv

Results:

psycopg2==2.0.8
wsgiref==0.1.2


Note: you might wonder why I didn't do a pip install -E myenv psycopg2. I tried this, but got an error. Maybe psycopg2 doesn't support pip/easy_install? Here is my error message:

Downloading/unpacking psycopg2
  Downloading psycopg2-2.0.11.tar.gz (255Kb): 255Kb downloaded
  Running setup.py egg_info for package psycopg2
    error: No such file or directory
    Complete output from command python setup.py egg_info:
    running egg_info

creating pip-egg-info/psycopg2.egg-info

writing pip-egg-info/psycopg2.egg-info/PKG-INFO

writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt

writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt

writing manifest file 'pip-egg-info/psycopg2.egg-info/SOURCES.txt'

warning: manifest_maker: standard file '-c' not found

error: No such file or directory

----------------------------------------
Command python setup.py egg_info failed with error code 1
Storing complete log in ./pip-log.txt
Complete output from command temp/bin/python /usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py install -E temp psycopg2 temp ___VENV_RESTART___:

----------------------------------------
Traceback (most recent call last):
  File "/usr/local/bin/pip", line 3, in 
    pip.main()
  File "/usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py", line 926, in main
    return command.main(initial_args, args[1:], options)
  File "/usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py", line 258, in main
    restart_in_venv(options.venv, site_packages, complete_args)
  File "/usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py", line 1009, in restart_in_venv
    call_subprocess([python, file] + args + [base, '___VENV_RESTART___'])
  File "/usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py", line 3643, in call_subprocess
    % (command_desc, proc.returncode))
pip.InstallationError: Command temp/bin/python /usr/local/lib/python2.6/dist-packages/pip-0.4-py2.6.egg/pip.py install -E temp psycopg2 temp ___VENV_RESTART___ failed with error code 1

Install wmii snapshot 20090703 on Ubuntu Jaunty

On Friday I installed the latest snapshot of wmii, the lightweight, tiling, dynamic, scriptable, keyboard navigatable window manager. (See my wmii tag for more posts about wmii.) Wmii orangizes windows into columns. Traditionally there has been three modes for each column: default, stack, and max. "Default" shows all windows in a column. "Stack" shows only one window at a time with the title bars of the other windows showing. "Max" shows only one window without any other titlebars. I usually use two columns each in stack mode. To navigate windows, I use Mod4+j/k to move among windows in a column and Mod4+h/l to move between columns. This has worked well for me, but sometimes I wanted to display two windows in a column while keeping the rest of the windows hidden. Thankfully, the latest snapshot of wmii now includes a new mode which solves my problem. It is a hybrid of the "default" and "stack" modes. It is called "defalut-max" and it allows for multiple stacks of windows per column. There is also a "default+max" mode which is like a hybrid of the old "default" and "max" modes. Additionally these modes now apply to the floating layer as well.

Another really cool thing about the latest wmii snapshot is that it now includes a Python library to interface with the wmii filesystem and a wmiirc written in Python. This should make it a lot easier to script wmii. This is exciting stuff. Thanks to Kris Maglione and the wmii contributors.

Here are my notes for installing wmii snapshot 20090703 on Ubuntu 9.04 Jaunty.

Install prerequisites

  • $ sudo apt-get install build-essential xorg-dev
    $ sudo apt-get install dwm-tools
  • This is so it can find the freetype headers.
    $ sudo ln -s /usr/include/freetype2/freetype /usr/include/freetype

Install wmii

  • Download wmii+ixp-snap20090703.tgz from the wmii homepage and save it to ~/incoming.
  • Unpack
    $ cd ~/incoming
    $ tar -zxvf wmii+ixp-snap20090703.tgz
  • make config
    $ cd ~/incoming/wmii+ixp-snap20090703
    $ make config
    Accept all defaults except set PREFIX=/home/saltycrane/lib/wmii_20090703

  • make & make install
    $ make 
    $ make install
  • Create links in my ~/bin directory:
    $ cd ~/bin
    $ ln -s ~/lib/wmii_20090703/bin/* .

Use the fun Python wmiirc

  • Copy the Python files to ~/.wmii-hg. This includes the pygmi directory, the pyxp directory, and the two wmiirc files.
    $ cp -r ~/incoming/wmii+ixp-snap20090703/alternative_wmiircs/python/* ~/.wmii-hg/
  • Edit ~/.wmii-hg/wmiirc.py as desired.

Run wmii

  • Create ~/.xsession:
    xmodmap ~/.Xmodmap
    gnome-screensaver&
    gnome-power-manager&
    nm-applet --sm-disable&
    urxvt&
    
    until wmii; do
        true
    done
  • Log out of the current window manager and then select X client script as the session and log in.

Install slock screen locker

  • Download from http://tools.suckless.org/slock
  • $ tar zxvf slock-0.9.tar.gz 
    $ cd slock-0.9 
    $ sudo make clean install 
    
  • Running slock: Simply invoke the 'slock' command. To get out of it, enter your password.

Freetype header error

The first time around, I got the following error:

In file included from /usr/include/X11/Xft/Xft.h:39,
                 from ../include/x11.h:9,
                 from cmd/wmii9menu.c:49:
/usr/include/ft2build.h:56:38: error: freetype/config/ftheader.h: No such file or directory
In file included from ../include/x11.h:9,
                 from cmd/wmii9menu.c:49:
/usr/include/X11/Xft/Xft.h:40:10: error: #include expects "FILENAME" or 
In file included from ../include/x11.h:9,
                 from cmd/wmii9menu.c:49:
/usr/include/X11/Xft/Xft.h:60: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘_XftFTlibrary’
/usr/include/X11/Xft/Xft.h:94: error: expected specifier-qualifier-list before ‘FT_UInt’
/usr/include/X11/Xft/Xft.h:101: error: expected specifier-qualifier-list before ‘FT_UInt’
/usr/include/X11/Xft/Xft.h:198: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
/usr/include/X11/Xft/Xft.h:303: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
/usr/include/X11/Xft/Xft.h:362: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘XftLockFace’
/usr/include/X11/Xft/Xft.h:401: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
/usr/include/X11/Xft/Xft.h:407: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
/usr/include/X11/Xft/Xft.h:416: error: expected declaration specifiers or ‘...’ before ‘FT_UInt’
/usr/include/X11/Xft/Xft.h:417: error: expected declaration specifiers or ‘...’ before ‘FT_UInt’
/usr/include/X11/Xft/Xft.h:426: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘XftCharIndex’
/usr/include/X11/Xft/Xft.h:459: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
make[1]: *** [wmii9menu.o] Error 1
make: *** [dall] Error 2

Per this discussion, I solved the problem by creating a symbolic link:

$ sudo ln -s /usr/include/freetype2/freetype /usr/include/freetype

Notes on C++ development with Emacs on Ubuntu Linux

Here are my notes on setting up an Emacs C++ development environment. I'm using GNU g++ (4.3.3), GNU make (3.81), GNU gdb (3.8-debian), and GNU emacs (23.0.92.1 built from CVS 2009-04-22) on Ubuntu Linux (9.04 Jaunty Jackalope).

Install tools

If you don't already have g++, make, and gdb, install them:

sudo apt-get install g++ make gdb

Create files

  • Create a project directory:
    mkdir helloworld
  • Create a source file helloworld/hello.cpp:
    #include <iostream>
    
    int main(void) 
    {
       char greeting[] = "Hello World!";
       std::cout << greeting << std::endl;
       return 0;
    }
  • Create a makefile helloworld/Makefile:
    # Makefile for GNU g++
    
    CC=g++
    CFLAGS=-g -Wall
    all: hello
    
    hello: hello.cpp
    	$(CC) $(CFLAGS) -o hello hello.cpp
    
    clean:
    	rm hello
    

Compile within Emacs

See also: 32 Compiling and Testing Programs in the GNU Emacs manual.

  • Open hello.cpp in Emacs
  • M-x compile RET
    make -k RET

    Note: The default compile command is make -k. You can change the default command by setting the compile-command variable in your .emacs file.

  • Useful commands in the compilation window:
    • C-x `: Go to next error in the code
    • M-n: Go to next error message
    • M-p: Go to previous error message
    • RET: Go to the source code for the current error message

Run using Emacs shell

  • M-! ./hello RET

    You should see the output in the minibuffer.

Debug with gdb in Emacs

For more information see: 32.6 Running Debuggers Under Emacs in the GNU Emacs manual.

  • To show multiple debugging windows such as breakpoints, locals, etc., set the gdb-many-windows variable in ~/.emacs:
    (setq gdb-many-windows t)
    Restart Emacs.

  • Start the debugger. While visiting helloworld/hello.cpp:
    M-x gdb RET --annotate=3 hello RET
  • Set a breakpoint by clicking in the left margin at the desired location.
  • Run the debugger by typing run at the (gdb) prompt in the *gud-hello* buffer.
  • In the GUD buffer, use the following commands:
    • C-c C-s Step into
    • C-c C-n Stev over
    • C-c C-p Evaluate the expression at point.
    • C-c C-r Continue
    • C-c C-u Continue until current line

  • When finished, type quit at the (gdb) prompt.

Documentation:

References

  • Practical C++ Programming, 2nd Edition by Steve Oualine (2004)
  • Learning GNU Emacs, 3rd Edition by Debra Cameron et al. (2004)
  • Emacs: the Free Software IDE at the Linux Journal (2002)

Free Computer Science courses online

I found out there is a video lecture series to go along with my new book The Algorithm Design Manual. The audio level is really low, but I think it will complement my book reading nicely. There are also lecture notes and homework assignments. It also turns out MIT has a huge collection of free courses online. Not all of them have video though. I listed some interesting Computer Science related courses with video below. After more searching, I found UC Berkeley also has a number of free courses online, including four Computer Science courses with video. The final source I found was ArsDigita University. They have a good number of Computer Science video lectures as well, but I had a hard time connecting. Let me know if I am missing other good sources.

Update 2009-7-8: I've updated the list to include Stanford's online courses. They have 3 Introduction to Computer Science courses with video lectures and 3 Artificial Intelligence courses with video lectures.

Stony Brook University Courses

MIT Courses

UC Berkeley Courses

Stanford Courses


See also: ArsDigita University Courses

Find the N longest lines in a file with Python

Here's a Python problem I attempted recently:

Write a program to read a multiple line text file and write the N longest lines to a new file. Where N and the file to be read are specified on the command line. Optimization is important.

Here's my solution:

import sys

def main(filename=sys.argv[1], 
         N=int(sys.argv[2])):
    """Find the N longest lines in filename and write to filename + ".new"
    """
    lines = open(filename).readlines()
    lines.sort(cmp=lambda x,y: cmp(len(y), len(x)))
    open(filename+".new", "w").write("".join(lines[:N]))

if __name__ == '__main__':
    main()

What do you think? Is there a faster way?

Notes on using pip and virtualenv with Django

I have been using a symlinking method to install Python packages up to this point. To better handle dependencies and multiple versions I have wanted to switch over to pip and virtualenv. Pip is a better alternative to Easy Install and virtualenv is a tool to create isolated Python environments. I have wanted to use pip and virtualenv for a long time now. Finally, today, I took my first steps and created an environment with the Python packages required for this blog. My notes are below. (I am running Ubuntu IntrepidKarmicMaverick and Python 2.52.6.) A lot of my notes on virtualenv are taken from Arthur Koziel's excellent tutorial.

Update 2012-03-14: Updated examples for pip 1.1 and virtualenv 1.7. As of pip 1.1, the -E option is removed. As of virtualenv 1.7, the --no-site-packages has become the default and is deprecated. Use --system-site-packages if you want to include system site packages (the old default behavior). Examples are run on Ubuntu 10.10 Maverick Meerkat.

Install Easy Install

If you don't already have Easy Install, it can be installed as follows:

$ sudo apt-get install python-setuptools python-dev build-essential

Install pip

In most cases it is not necessary to install pip because it is included with virtualenv.

$ sudo easy_install -U pip 
install_dir /usr/local/lib/python2.6/dist-packages/
Searching for pip
Reading http://pypi.python.org/simple/pip/
Reading http://pip.openplans.org
Reading http://www.pip-installer.org
Best match: pip 1.1
Downloading http://pypi.python.org/packages/source/p/pip/pip-1.1.tar.gz#md5=62a9f08dd5dc69d76734568a6c040508
Processing pip-1.1.tar.gz
Running pip-1.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-i_5nEU/pip-1.1/egg-dist-tmp-ytHsCZ
warning: no files found matching '*.html' under directory 'docs'
warning: no previously-included files matching '*.txt' found under directory 'docs/_build'
no previously-included directories found matching 'docs/_build/_sources'
Adding pip 1.1 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip-2.6 script to /usr/local/bin

Installed /usr/local/lib/python2.6/dist-packages/pip-1.1-py2.6.egg
Processing dependencies for pip
Finished processing dependencies for pip

Install virtualenv

$ sudo easy_install -U virtualenv 
install_dir /usr/local/lib/python2.6/dist-packages/
Searching for virtualenv
Reading http://pypi.python.org/simple/virtualenv/
Reading http://www.virtualenv.org
Reading http://virtualenv.openplans.org
Best match: virtualenv 1.7.1.2
Downloading http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.7.1.2.tar.gz#md5=3be8a014c27340f48b56465f9109d9fa
Processing virtualenv-1.7.1.2.tar.gz
Running virtualenv-1.7.1.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-td3AoM/virtualenv-1.7.1.2/egg-dist-tmp-7dJVfO
warning: no previously-included files matching '*.*' found under directory 'docs/_templates'
Adding virtualenv 1.7.1.2 to easy-install.pth file
Installing virtualenv script to /usr/local/bin

Installed /usr/local/lib/python2.6/dist-packages/virtualenv-1.7.1.2-py2.6.egg
Processing dependencies for virtualenv
Finished processing dependencies for virtualenv

Create a virtual environment

This command creates the isolated virtual environment.

Update 2010-04-13: Updated to use distribute because it is the new hotness.

$ cd /tmp
$ virtualenv --distribute myenv
New python executable in myenv/bin/python
Installing distribute.............................................................................................................................................................................................done.
Installing pip...............done.

Create a virtualenv with a different version of Python

This creates a virtualenv that uses Python 2.7 instead of the default Python 2.6.

$ virtualenv --distribute --python=/usr/bin/python2.7 myenv-py27
Running virtualenv with interpreter /usr/bin/python2.7
New python executable in myenv-py27/bin/python2.7
Also creating executable in myenv-py27/bin/python
Installing distribute.............................................................................................................................................................................................done.
Installing pip...............done.

Clear the PYTHONPATH variable

I don't know if this is necessary, but I had a problem with the akismet module when this was set. Maybe I did something wrong, but when I cleared PYTHONPATH, it worked.

$ export PYTHONPATH=

Install a package (Yolk) in the new virtual environment

Activate the virtual environment and install Yolk inside it. (Yolk is a tool that lists Python packages.)

$ source /tmp/myenv/bin/activate 
$ pip install yolk 
Downloading/unpacking yolk
  Downloading yolk-0.4.3.tar.gz (86Kb): 86Kb downloaded
  Running setup.py egg_info for package yolk
    warning: no files found matching '*.txt' under directory 'tests'
    warning: no files found matching '*.conf' under directory 'docs'
    warning: no files found matching '*.css_t' under directory 'docs'
    warning: no files found matching 'indexsidebar.html' under directory 'docs'
    warning: no files found matching 'tests/test_cli.py'
Requirement already satisfied (use --upgrade to upgrade): distribute in ./myenv/lib/python2.6/site-packages/distribute-0.6.24-py2.6.egg (from yolk)
Installing collected packages: yolk
  Running setup.py install for yolk
    warning: no files found matching '*.txt' under directory 'tests'
    warning: no files found matching '*.conf' under directory 'docs'
    warning: no files found matching '*.css_t' under directory 'docs'
    warning: no files found matching 'indexsidebar.html' under directory 'docs'
    warning: no files found matching 'tests/test_cli.py'
    Installing yolk script to /tmp/myenv/bin
Successfully installed yolk
Cleaning up...

Use the virtual environment

  • Activate the virtual environment
    $ source /tmp/myenv/bin/activate
    
  • Run yolk to list your installed packages:
    $ yolk -l
    Python          - 2.6.6        - active development (/usr/lib/python2.6/lib-dynload)
    distribute      - 0.6.24       - active 
    pip             - 1.1          - active 
    wsgiref         - 0.1.2        - active development (/usr/lib/python2.6)
    yolk            - 0.4.3        - active
    
  • Deactivate the environment
    $ deactivate
    
  • Try running yolk
    $ yolk -l
    yolk: command not found
    

Install Django in the virtual environment

$ source /tmp/myenv/bin/activate
$ pip install Django
Downloading/unpacking Django
  Downloading Django-1.3.1.tar.gz (6.5Mb): 6.5Mb downloaded
  Running setup.py egg_info for package Django
Installing collected packages: Django
  Running setup.py install for Django
    changing mode of build/scripts-2.6/django-admin.py from 644 to 755
    changing mode of /tmp/myenv/bin/django-admin.py to 755
Successfully installed Django
Cleaning up...

Create a requirements file from existing library versions using pip freeze


The pip freeze command allows you to take a snapshot of the exact versions of all your Python libraries. For more information, see the documentation on pip freeze.

$ source /tmp/myenv/bin/activate
$ pip freeze > /tmp/requirements.txt
$ cat /tmp/requirements.txt 
Django==1.3.1
distribute==0.6.24
wsgiref==0.1.2
yolk==0.4.3

Uninstall a package

$ source /tmp/myenv/bin/activate
$ pip uninstall Django
Uninstalling Django:
  /tmp/myenv/bin/django-admin.py
  /tmp/myenv/lib/python2.6/site-packages/Django-1.3.1-py2.6.egg-info
  /tmp/myenv/lib/python2.6/site-packages/django
Proceed (y/n)? y
  Successfully uninstalled Django

Install libraries based on a requirements file

Once you have a requirements file, you can use pip to install the exact versions of the libraries specified in your requirements file. For more information, see the documentation on pip requirements files. Here's my requirements file for this blog, /tmp/saltycrane-requirements.txt:

psycopg2==2.4.2
Django==1.3.1
Markdown==2.0
http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.0.7a.tar.gz
Pygments==1.3.1
Twisted==10.0.0

http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz
-e hg+http://bitbucket.org/ubernostrum/django-contact-form/#egg=django-contact-form
-e hg+http://bitbucket.org/jezdez/akismet/#egg=akismet

Fabric==1.3.1

Here's the command to install using my reqirements file:

$ source /tmp/myenv/bin/activate
$ pip install -r /tmp/saltycrane-requirements.txt
Downloading/unpacking http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.0.7a.tar.gz (from -r /tmp/saltycrane-requirements.txt (line 7))
  Downloading BeautifulSoup-3.0.7a.tar.gz
  Running setup.py egg_info for package from http://www.crummy.com/software/BeautifulSoup/download/3.x/Beaut
ifulSoup-3.0.7a.tar.gz                                           
Downloading/unpacking http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz (from -r /tmp/saltycrane-requirements.txt (line 11))
  Downloading django-tagging-0.3.1.tar.gz
  Running setup.py egg_info for package from http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz
Downloading/unpacking psycopg2==2.4.2 (from -r /tmp/saltycrane-requirements.txt (line 1))
  Downloading psycopg2-2.4.2.tar.gz (667Kb): 667Kb downloaded
  Running setup.py egg_info for package psycopg2
    no previously-included directories found matching 'doc/src/_build'
Downloading/unpacking Django==1.3.1 (from -r /tmp/saltycrane-requirements.txt (line 4))
  Downloading Django-1.3.1.tar.gz (6.5Mb): 6.5Mb downloaded
  Running setup.py egg_info for package Django
Downloading/unpacking Markdown==2.0 (from -r /tmp/saltycrane-requirements.txt (line 5))
  Downloading Markdown-2.0.zip (93Kb): 93Kb downloaded
  Running setup.py egg_info for package Markdown
Downloading/unpacking Pygments==1.3.1 (from -r /tmp/saltycrane-requirements.txt (line 8))
  Downloading Pygments-1.3.1.tar.gz (1.1Mb): 1.1Mb downloaded
  Running setup.py egg_info for package Pygments
Downloading/unpacking Twisted==10.0.0 (from -r /tmp/saltycrane-requirements.txt (line 9))
  Downloading Twisted-10.0.0.tar.bz2 (2.6Mb): 2.6Mb downloaded
  Running setup.py egg_info for package Twisted
Obtaining django-contact-form from hg+http://bitbucket.org/ubernostrum/django-contact-form/#egg=django-contact-form (from -r /tmp/saltycrane-requirements.txt (line 12))
  Cloning hg http://bitbucket.org/ubernostrum/django-contact-form/ to ./myenv/src/django-contact-form
  Running setup.py egg_info for package django-contact-form
Obtaining akismet from hg+http://bitbucket.org/jezdez/akismet/#egg=akismet (from -r /tmp/saltycrane-requirements.txt (line 13))
  Cloning hg http://bitbucket.org/jezdez/akismet/ to ./myenv/src/akismet
  Running setup.py egg_info for package akismet
Downloading/unpacking Fabric==1.3.1 (from -r /tmp/saltycrane-requirements.txt (line 15))
  Downloading Fabric-1.3.1.tar.gz (167Kb): 167Kb downloaded
  Running setup.py egg_info for package Fabric
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    warning: no files found matching 'fabfile.py'
Downloading/unpacking zope.interface (from Twisted==10.0.0->-r /tmp/saltycrane-requirements.txt (line 9))
  Downloading zope.interface-3.8.0.tar.gz (111Kb): 111Kb downloaded
  Running setup.py egg_info for package zope.interface
Downloading/unpacking ssh>=1.7.8 (from Fabric==1.3.1->-r /tmp/saltycrane-requirements.txt (line 15))
  Downloading ssh-1.7.13.tar.gz (790Kb): 790Kb downloaded
  Running setup.py egg_info for package ssh
Requirement already satisfied (use --upgrade to upgrade): distribute in ./myenv/lib/python2.6/site-packages/distribute-0.6.24-py2.6.egg (from zope.interface->Twisted==10.0.0->-r /tmp/saltycrane-requirements.txt (line 9))
Downloading/unpacking pycrypto>=2.1,!=2.4 (from ssh>=1.7.8->Fabric==1.3.1->-r /tmp/saltycrane-requirements.txt (line 15))
  Downloading pycrypto-2.5.tar.gz (426Kb): 426Kb downloaded
  Running setup.py egg_info for package pycrypto
Installing collected packages: psycopg2, Django, Markdown, Pygments, Twisted, django-contact-form, akismet, Fabric, BeautifulSoup, django-tagging, zope.interface, ssh, pycrypto
  Running setup.py install for psycopg2
    building 'psycopg2._psycopg' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/psycopgmodule.c -o build/temp.linux-x86_64-2.6/psycopg/psycopgmodule.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/green.c -o build/temp.linux-x86_64-2.6/psycopg/green.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/pqpath.c -o build/temp.linux-x86_64-2.6/psycopg/pqpath.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/utils.c -o build/temp.linux-x86_64-2.6/psycopg/utils.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/bytes_format.c -o build/temp.linux-x86_64-2.6/psycopg/bytes_format.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/connection_int.c -o build/temp.linux-x86_64-2.6/psycopg/connection_int.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/connection_type.c -o build/temp.linux-x86_64-2.6/psycopg/connection_type.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/cursor_int.c -o build/temp.linux-x86_64-2.6/psycopg/cursor_int.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/cursor_type.c -o build/temp.linux-x86_64-2.6/psycopg/cursor_type.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/lobject_int.c -o build/temp.linux-x86_64-2.6/psycopg/lobject_int.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/lobject_type.c -o build/temp.linux-x86_64-2.6/psycopg/lobject_type.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/notify_type.c -o build/temp.linux-x86_64-2.6/psycopg/notify_type.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/xid_type.c -o build/temp.linux-x86_64-2.6/psycopg/xid_type.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_asis.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_asis.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_binary.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_binary.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_datetime.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_datetime.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_list.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_list.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_pboolean.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_pboolean.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_pdecimal.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_pdecimal.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_pint.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_pint.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_pfloat.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_pfloat.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_qstring.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_qstring.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/microprotocols.c -o build/temp.linux-x86_64-2.6/psycopg/microprotocols.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/microprotocols_proto.c -o build/temp.linux-x86_64-2.6/psycopg/microprotocols_proto.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/typecast.c -o build/temp.linux-x86_64-2.6/psycopg/typecast.o -Wdeclaration-after-statement
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_MXDATETIME=1 -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.4.2 (dt dec mx pq3 ext)" -DPG_VERSION_HEX=0x08040B -DPSYCOPG_EXTENSIONS=1 -DPSYCOPG_NEW_BOOLEAN=1 -DHAVE_PQFREEMEM=1 -I/usr/include/python2.6/mx -I/usr/include/python2.6 -I. -I/usr/include/postgresql -I/usr/include/postgresql/8.4/server -c psycopg/adapter_mxdatetime.c -o build/temp.linux-x86_64-2.6/psycopg/adapter_mxdatetime.o -Wdeclaration-after-statement
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/psycopg/psycopgmodule.o build/temp.linux-x86_64-2.6/psycopg/green.o build/temp.linux-x86_64-2.6/psycopg/pqpath.o build/temp.linux-x86_64-2.6/psycopg/utils.o build/temp.linux-x86_64-2.6/psycopg/bytes_format.o build/temp.linux-x86_64-2.6/psycopg/connection_int.o build/temp.linux-x86_64-2.6/psycopg/connection_type.o build/temp.linux-x86_64-2.6/psycopg/cursor_int.o build/temp.linux-x86_64-2.6/psycopg/cursor_type.o build/temp.linux-x86_64-2.6/psycopg/lobject_int.o build/temp.linux-x86_64-2.6/psycopg/lobject_type.o build/temp.linux-x86_64-2.6/psycopg/notify_type.o build/temp.linux-x86_64-2.6/psycopg/xid_type.o build/temp.linux-x86_64-2.6/psycopg/adapter_asis.o build/temp.linux-x86_64-2.6/psycopg/adapter_binary.o build/temp.linux-x86_64-2.6/psycopg/adapter_datetime.o build/temp.linux-x86_64-2.6/psycopg/adapter_list.o build/temp.linux-x86_64-2.6/psycopg/adapter_pboolean.o build/temp.linux-x86_64-2.6/psycopg/adapter_pdecimal.o build/temp.linux-x86_64-2.6/psycopg/adapter_pint.o build/temp.linux-x86_64-2.6/psycopg/adapter_pfloat.o build/temp.linux-x86_64-2.6/psycopg/adapter_qstring.o build/temp.linux-x86_64-2.6/psycopg/microprotocols.o build/temp.linux-x86_64-2.6/psycopg/microprotocols_proto.o build/temp.linux-x86_64-2.6/psycopg/typecast.o build/temp.linux-x86_64-2.6/psycopg/adapter_mxdatetime.o -lpq -o build/lib.linux-x86_64-2.6/psycopg2/_psycopg.so
    no previously-included directories found matching 'doc/src/_build'
  Running setup.py install for Django
    changing mode of build/scripts-2.6/django-admin.py from 644 to 755
    changing mode of /tmp/myenv/bin/django-admin.py to 755
  Running setup.py install for Markdown
    changing mode of build/scripts-2.6/markdown.py from 644 to 755
    changing mode of /tmp/myenv/bin/markdown.py to 755
  Running setup.py install for Pygments
    Installing pygmentize script to /tmp/myenv/bin
  Running setup.py install for Twisted
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c conftest.c -o conftest.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c conftest.c -o conftest.o
    building 'twisted.runner.portmap' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c twisted/runner/portmap.c -o build/temp.linux-x86_64-2.6/twisted/runner/portmap.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/twisted/runner/portmap.o -o build/lib.linux-x86_64-2.6/twisted/runner/portmap.so
    building 'twisted.protocols._c_urlarg' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c twisted/protocols/_c_urlarg.c -o build/temp.linux-x86_64-2.6/twisted/protocols/_c_urlarg.o
    twisted/protocols/_c_urlarg.c: In function ‘unquote’:
    twisted/protocols/_c_urlarg.c:41: warning: ‘tmp’ may be used uninitialized in this function
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/twisted/protocols/_c_urlarg.o -o build/lib.linux-x86_64-2.6/twisted/protocols/_c_urlarg.so
    building 'twisted.test.raiser' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c twisted/test/raiser.c -o build/temp.linux-x86_64-2.6/twisted/test/raiser.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/twisted/test/raiser.o -o build/lib.linux-x86_64-2.6/twisted/test/raiser.so
    building 'twisted.python._epoll' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c twisted/python/_epoll.c -o build/temp.linux-x86_64-2.6/twisted/python/_epoll.o
    twisted/python/_epoll.c: In function ‘__pyx_f_6_epoll_5epoll___dealloc__’:
    twisted/python/_epoll.c:168: warning: label ‘__pyx_L1’ defined but not used
    twisted/python/_epoll.c: In function ‘__pyx_f_6_epoll_5epoll_wait’:
    twisted/python/_epoll.c:432: warning: label ‘__pyx_L7’ defined but not used
    twisted/python/_epoll.c:430: warning: label ‘__pyx_L6’ defined but not used
    twisted/python/_epoll.c: In function ‘__pyx_tp_new_6_epoll_epoll’:
    twisted/python/_epoll.c:508: warning: unused variable ‘p’
    twisted/python/_epoll.c: In function ‘__pyx_tp_dealloc_6_epoll_epoll’:
    twisted/python/_epoll.c:513: warning: unused variable ‘p’
    twisted/python/_epoll.c: In function ‘__pyx_tp_traverse_6_epoll_epoll’:
    twisted/python/_epoll.c:528: warning: unused variable ‘p’
    twisted/python/_epoll.c:527: warning: unused variable ‘e’
    twisted/python/_epoll.c: In function ‘__pyx_tp_clear_6_epoll_epoll’:
    twisted/python/_epoll.c:533: warning: unused variable ‘p’
    twisted/python/_epoll.c: At top level:
    twisted/python/_epoll.c:32: warning: ‘__Pyx_UnpackItem’ declared ‘static’ but never defined
    twisted/python/_epoll.c:33: warning: ‘__Pyx_EndUnpack’ declared ‘static’ but never defined
    twisted/python/_epoll.c:34: warning: ‘__Pyx_PrintItem’ declared ‘static’ but never defined
    twisted/python/_epoll.c:35: warning: ‘__Pyx_PrintNewline’ declared ‘static’ but never defined
    twisted/python/_epoll.c:37: warning: ‘__Pyx_ReRaise’ declared ‘static’ but never defined
    twisted/python/_epoll.c:38: warning: ‘__Pyx_Import’ declared ‘static’ but never defined
    twisted/python/_epoll.c:39: warning: ‘__Pyx_GetExcValue’ declared ‘static’ but never defined
    twisted/python/_epoll.c:40: warning: ‘__Pyx_ArgTypeTest’ declared ‘static’ but never defined
    twisted/python/_epoll.c:41: warning: ‘__Pyx_TypeTest’ declared ‘static’ but never defined
    twisted/python/_epoll.c:42: warning: ‘__Pyx_GetStarArgs’ declared ‘static’ but never defined
    twisted/python/_epoll.c:43: warning: ‘__Pyx_WriteUnraisable’ declared ‘static’ but never defined
    twisted/python/_epoll.c:45: warning: ‘__Pyx_ImportType’ declared ‘static’ but never defined
    twisted/python/_epoll.c:46: warning: ‘__Pyx_SetVtable’ declared ‘static’ but never defined
    twisted/python/_epoll.c:47: warning: ‘__Pyx_GetVtable’ declared ‘static’ but never defined
    twisted/python/_epoll.c:48: warning: ‘__Pyx_CreateClass’ declared ‘static’ but never defined
    twisted/python/_epoll.c:50: warning: ‘__Pyx_InitStrings’ declared ‘static’ but never defined
    twisted/python/_epoll.c:51: warning: ‘__Pyx_InitCApi’ declared ‘static’ but never defined
    twisted/python/_epoll.c:52: warning: ‘__Pyx_ImportModuleCApi’ declared ‘static’ but never defined
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/twisted/python/_epoll.o -o build/lib.linux-x86_64-2.6/twisted/python/_epoll.so
    building 'twisted.python._initgroups' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c twisted/python/_initgroups.c -o build/temp.linux-x86_64-2.6/twisted/python/_initgroups.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/twisted/python/_initgroups.o -o build/lib.linux-x86_64-2.6/twisted/python/_initgroups.so
    changing mode of build/scripts-2.6/mktap from 644 to 755
    changing mode of build/scripts-2.6/tap2deb from 644 to 755
    changing mode of build/scripts-2.6/tap2rpm from 644 to 755
    changing mode of build/scripts-2.6/trial from 644 to 755
    changing mode of build/scripts-2.6/pyhtmlizer from 644 to 755
    changing mode of build/scripts-2.6/tapconvert from 644 to 755
    changing mode of build/scripts-2.6/manhole from 644 to 755
    changing mode of build/scripts-2.6/twistd from 644 to 755
    changing mode of build/scripts-2.6/ckeygen from 644 to 755
    changing mode of build/scripts-2.6/cftp from 644 to 755
    changing mode of build/scripts-2.6/conch from 644 to 755
    changing mode of build/scripts-2.6/tkconch from 644 to 755
    changing mode of build/scripts-2.6/mailmail from 644 to 755
    changing mode of build/scripts-2.6/lore from 644 to 755
    changing mode of /tmp/myenv/bin/mktap to 755
    changing mode of /tmp/myenv/bin/ckeygen to 755
    changing mode of /tmp/myenv/bin/cftp to 755
    changing mode of /tmp/myenv/bin/conch to 755
    changing mode of /tmp/myenv/bin/tap2deb to 755
    changing mode of /tmp/myenv/bin/tap2rpm to 755
    changing mode of /tmp/myenv/bin/lore to 755
    changing mode of /tmp/myenv/bin/trial to 755
    changing mode of /tmp/myenv/bin/pyhtmlizer to 755
    changing mode of /tmp/myenv/bin/tkconch to 755
    changing mode of /tmp/myenv/bin/tapconvert to 755
    changing mode of /tmp/myenv/bin/manhole to 755
    changing mode of /tmp/myenv/bin/twistd to 755
    changing mode of /tmp/myenv/bin/mailmail to 755
  Running setup.py develop for django-contact-form
    Creating /tmp/myenv/lib/python2.6/site-packages/django-contact-form.egg-link (link to .)
    Adding django-contact-form 0.3 to easy-install.pth file
    
    Installed /tmp/myenv/src/django-contact-form
  Running setup.py develop for akismet
    Creating /tmp/myenv/lib/python2.6/site-packages/akismet.egg-link (link to .)
    Adding akismet 0.1.5 to easy-install.pth file
    
    Installed /tmp/myenv/src/akismet
  Running setup.py install for Fabric
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    warning: no files found matching 'fabfile.py'
    Installing fab script to /tmp/myenv/bin
  Running setup.py install for BeautifulSoup
  Running setup.py install for django-tagging
  Running setup.py install for zope.interface
    building 'zope.interface._zope_interface_coptimizations' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c src/zope/interface/_zope_interface_coptimizations.c -o build/temp.linux-x86_64-2.6/src/zope/interface/_zope_interface_coptimizations.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/zope/interface/_zope_interface_coptimizations.o -o build/lib.linux-x86_64-2.6/zope/interface/_zope_interface_coptimizations.so
    Skipping installation of /tmp/myenv/lib/python2.6/site-packages/zope/__init__.py (namespace package)
    Installing /tmp/myenv/lib/python2.6/site-packages/zope.interface-3.8.0-py2.6-nspkg.pth
  Running setup.py install for ssh
  Running setup.py install for pycrypto
    checking for gcc... gcc
    checking whether the C compiler works... yes
    checking for C compiler default output file name... a.out
    checking for suffix of executables...
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C compiler... yes
    checking whether gcc accepts -g... yes
    checking for gcc option to accept ISO C89... none needed
    checking for __gmpz_init in -lgmp... no
    checking for __gmpz_init in -lmpir... no
    checking whether mpz_powm is declared... no
    checking whether mpz_powm_sec is declared... no
    checking how to run the C preprocessor... gcc -E
    checking for grep that handles long lines and -e... /bin/grep
    checking for egrep... /bin/grep -E
    checking for ANSI C header files... yes
    checking for sys/types.h... yes
    checking for sys/stat.h... yes
    checking for stdlib.h... yes
    checking for string.h... yes
    checking for memory.h... yes
    checking for strings.h... yes
    checking for inttypes.h... yes
    checking for stdint.h... yes
    checking for unistd.h... yes
    checking for inttypes.h... (cached) yes
    checking limits.h usability... yes
    checking limits.h presence... yes
    checking for limits.h... yes
    checking stddef.h usability... yes
    checking stddef.h presence... yes
    checking for stddef.h... yes
    checking for stdint.h... (cached) yes
    checking for stdlib.h... (cached) yes
    checking for string.h... (cached) yes
    checking wchar.h usability... yes
    checking wchar.h presence... yes
    checking for wchar.h... yes
    checking for inline... inline
    checking for int16_t... yes
    checking for int32_t... yes
    checking for int64_t... yes
    checking for int8_t... yes
    checking for size_t... yes
    checking for uint16_t... yes
    checking for uint32_t... yes
    checking for uint64_t... yes
    checking for uint8_t... yes
    checking for stdlib.h... (cached) yes
    checking for GNU libc compatible malloc... yes
    checking for memmove... yes
    checking for memset... yes
    configure: creating ./config.status
    config.status: creating src/config.h
    warning: GMP or MPIR library not found; Not building Crypto.PublicKey._fastmath.
    building 'Crypto.Hash._MD2' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/MD2.c -o build/temp.linux-x86_64-2.6/src/MD2.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/MD2.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_MD2.so
    building 'Crypto.Hash._MD4' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/MD4.c -o build/temp.linux-x86_64-2.6/src/MD4.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/MD4.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_MD4.so
    building 'Crypto.Hash._SHA256' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/SHA256.c -o build/temp.linux-x86_64-2.6/src/SHA256.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/SHA256.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_SHA256.so
    building 'Crypto.Hash._SHA224' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/SHA224.c -o build/temp.linux-x86_64-2.6/src/SHA224.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/SHA224.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_SHA224.so
    building 'Crypto.Hash._SHA384' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/SHA384.c -o build/temp.linux-x86_64-2.6/src/SHA384.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/SHA384.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_SHA384.so
    building 'Crypto.Hash._SHA512' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/SHA512.c -o build/temp.linux-x86_64-2.6/src/SHA512.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/SHA512.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_SHA512.so
    building 'Crypto.Hash._RIPEMD160' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -DPCT_LITTLE_ENDIAN=1 -Isrc/ -I/usr/include/python2.6 -c src/RIPEMD160.c -o build/temp.linux-x86_64-2.6/src/RIPEMD160.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/RIPEMD160.o -o build/lib.linux-x86_64-2.6/Crypto/Hash/_RIPEMD160.so
    building 'Crypto.Cipher.AES' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/AES.c -o build/temp.linux-x86_64-2.6/src/AES.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/AES.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/AES.so
    building 'Crypto.Cipher.ARC2' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/ARC2.c -o build/temp.linux-x86_64-2.6/src/ARC2.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/ARC2.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/ARC2.so
    building 'Crypto.Cipher.Blowfish' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/Blowfish.c -o build/temp.linux-x86_64-2.6/src/Blowfish.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/Blowfish.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/Blowfish.so
    building 'Crypto.Cipher.CAST' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/CAST.c -o build/temp.linux-x86_64-2.6/src/CAST.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/CAST.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/CAST.so
    building 'Crypto.Cipher.DES' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -Isrc/libtom/ -I/usr/include/python2.6 -c src/DES.c -o build/temp.linux-x86_64-2.6/src/DES.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/DES.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/DES.so
    building 'Crypto.Cipher.DES3' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -Isrc/libtom/ -I/usr/include/python2.6 -c src/DES3.c -o build/temp.linux-x86_64-2.6/src/DES3.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/DES3.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/DES3.so
    building 'Crypto.Cipher.ARC4' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/ARC4.c -o build/temp.linux-x86_64-2.6/src/ARC4.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/ARC4.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/ARC4.so
    building 'Crypto.Cipher.XOR' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/XOR.c -o build/temp.linux-x86_64-2.6/src/XOR.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/XOR.o -o build/lib.linux-x86_64-2.6/Crypto/Cipher/XOR.so
    building 'Crypto.Util.strxor' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/strxor.c -o build/temp.linux-x86_64-2.6/src/strxor.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/strxor.o -o build/lib.linux-x86_64-2.6/Crypto/Util/strxor.so
    building 'Crypto.Util._counter' extension
    gcc -pthread -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.6 -c src/_counter.c -o build/temp.linux-x86_64-2.6/src/_counter.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/src/_counter.o -o build/lib.linux-x86_64-2.6/Crypto/Util/_counter.so
Successfully installed psycopg2 Django Markdown Pygments Twisted django-contact-form akismet Fabric BeautifulSoup django-tagging zope.interface ssh pycrypto
Cleaning up...

Use virtualenv with Django and mod_python

Here is how to use a virtualenv with mod_python. This is taken from Django, mod_python and virtualenv. For more information, see the virtualenv documentation on using virtualenv without bin/python.

  • Create a file /srv/SaltyCrane/myvirtualdjango.py:
    activate_this = "/srv/python-environments/saltycrane/bin/activate_this.py"
    execfile(activate_this, dict(__file__=activate_this))
    
    from django.core.handlers.modpython import handler
    
  • Edit your httpd.conf
        <Location "/">
            SetHandler python-program
            PythonHandler myvirtualdjango
            SetEnv DJANGO_SETTINGS_MODULE iwiwdsmi.settings
            PythonPath "['/srv/SaltyCrane',] + sys.path"
            PythonDebug Off
        </Location>

Use virtualenv with Django and mod_wsgi

Added 2009-09-27: Here is how I set up my virtualenv with mod_wsgi. To use the the packages in my virtualenv, I used site.addsitedir at the top of my .wsgi application file. You may also want to set the WSGIPythonHome variable in your httpd.conf file (outside of any VirtualHost sections). For detailed information on using mod_wsgi with virtualenv, see the Virtual Environments section of the modwsgi project documentation.

  • /srv/SaltyCrane/saltycrane.wsgi:
    import os
    import sys
    import site
    
    site.addsitedir('/srv/python-environments/saltycrane/lib/python2.5/site-packages')
    
    os.environ['DJANGO_SETTINGS_MODULE'] = 'iwiwdsmi.settings'
    
    sys.path.append('/srv/SaltyCrane')
    
    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()
  • httpd.conf:
        WSGIScriptAlias / /srv/SaltyCrane/saltycrane.wsgi

Background / Discussion

Below are some links to some essential information on pip, virtualenv, and Python packaging (mostly from the creator of pip and virtualenv, Ian Bicking) and some further discussion on the state of Python packaging. (Updated 2012-11-17)

Converting time zones for datetime objects in Python

Install pytz

I am using pytz, which is a time zone definitions package. You can install it using Easy Install. On Ubuntu, do this:

sudo easy_install --upgrade pytz

Add time zone information to a naive datetime object

from datetime import datetime
from pytz import timezone

date_str = "2009-05-05 22:28:15"
datetime_obj = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
datetime_obj_utc = datetime_obj.replace(tzinfo=timezone('UTC'))
print datetime_obj_utc.strftime("%Y-%m-%d %H:%M:%S %Z%z")

Results:

2009-05-05 22:28:15 UTC+0000

Add non-UTC time zone information to a naive datetime object

(Added 2014-05-28)

NOTE: datetime.replace() does not handle daylight savings time correctly. The correct way is to use timezone.localize() instead. Using datetime.replace() is OK when working with UTC as shown above because it does not have daylight savings time transitions to deal with. See the pytz documentation.

from datetime import datetime
from pytz import timezone

date_str = "2014-05-28 22:28:15"
datetime_obj_naive = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")

# Wrong way!
datetime_obj_pacific = datetime_obj_naive.replace(tzinfo=timezone('US/Pacific'))
print datetime_obj_pacific.strftime("%Y-%m-%d %H:%M:%S %Z%z")

# Right way!
datetime_obj_pacific = timezone('US/Pacific').localize(datetime_obj_naive)
print datetime_obj_pacific.strftime("%Y-%m-%d %H:%M:%S %Z%z")

Results:

2014-05-28 22:28:15 PST-0800
2014-05-28 22:28:15 PDT-0700

Convert time zones

from datetime import datetime
from pytz import timezone

fmt = "%Y-%m-%d %H:%M:%S %Z%z"

# Current time in UTC
now_utc = datetime.now(timezone('UTC'))
print now_utc.strftime(fmt)

# Convert to US/Pacific time zone
now_pacific = now_utc.astimezone(timezone('US/Pacific'))
print now_pacific.strftime(fmt)

# Convert to Europe/Berlin time zone
now_berlin = now_pacific.astimezone(timezone('Europe/Berlin'))
print now_berlin.strftime(fmt)

Results:

2009-05-06 03:09:49 UTC+0000
2009-05-05 20:09:49 PDT-0700
2009-05-06 05:09:49 CEST+0200

List time zones

There are 559 time zones included in pytz. Here's how to print the US time zones:

from pytz import all_timezones

print len(all_timezones)
for zone in all_timezones:
    if 'US' in zone:
        print zone

Results:

US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa

See also:

Notes on using nginx with mod_python and Django

Here are my notes on setting up nginx as a reverse proxy with Apache, mod_python, and Django on Ubuntu Intrepid. Nginx is used to serve my static media files while all other requests are passed on to the Apache/mod_python/Django web server.

I realize mod_wsgi has become the preferred way to deploy Django, but I'm a little behind the times and am still using mod_python. I hope to switch to mod_wsgi soon.

I have been using Amazon's CloudFront service for delivering my static media files. As far as I can tell, it has worked well. My main reason for switching to nginx is so I can skip the extra step of uploading to Amazon. Regarding my concern about the memory footprint of nginx, it looks like it is using around 5mb with my two process configuration.

My configuration parameters are shown below. I'm running two sites, SaltyCrane and HandsOnCards on a Slicehost 256mb plan.

DescriptionHandsOnCardsSaltyCrane
Redirectionhttp://www.handsoncards.com is redirected to http://handsoncards.comhttp://saltycrane.com is redirected to http://www.saltycrane.com
Static media filesystem path/srv/HandsOnCards/handsoncards/static//srv/SaltyCrane/iwiwdsmi/media/
Static media web path/site_media//site_media/
Django settings.py file location/srv/HandsOnCards/handsoncards/settings.py/srv/SaltyCrane/iwiwdsmi/settings.py
Additional Python packages path/srv/python-packages/srv/python-packages

Install nginx

Some recommend installing nginx from source, but I took the easier route and used Ubuntu's package manager.

sudo apt-get install nginx

Nginx configuration

Edit /etc/nginx/nginx.conf:

user www-data www-data;
worker_processes  2;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;

    sendfile        on;
    tcp_nopush      on;

    keepalive_timeout  3;
    tcp_nodelay        off;

    gzip  on;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types      text/plain text/html text/css application/x-javascript text/xml
                    application/xml application/xml+rss text/javascript;

    server {
        listen 80;
        server_name  www.handsoncards.com;
        rewrite ^/(.*) http://handsoncards.com/$1 permanent;
    }
    server {
        listen 80;
        server_name handsoncards.com;
      
        access_log /var/log/nginx/handsoncards.com.access.log;
        error_log /var/log/nginx/handsoncards.com.error.log;
      
        location / {
            proxy_pass http://127.0.0.1:8080/;
            include /etc/nginx/proxy.conf;
        }
        location /site_media/ {
            alias /srv/HandsOnCards/handsoncards/static/;
            expires 24h;
        }
    }
    server {
        listen 80;
        server_name saltycrane.com;
        rewrite ^/(.*) http://www.saltycrane.com/$1 permanent;
    }
    server {
        listen 80;
        server_name www.saltycrane.com;
      
        access_log /var/log/nginx/saltycrane.com.access.log;
        error_log /var/log/nginx/saltycrane.com.error.log;
      
        location / {
            proxy_pass http://127.0.0.1:8080/;
            include /etc/nginx/proxy.conf;
        }
        location /site_media/ {
            alias /srv/SaltyCrane/iwidsmi/media/;
            expires 24h;
        }
    }
}

Edit /etc/nginx/proxy.conf:

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;

Restart Nginx

sudo /etc/init.d/nginx restart

Install Apache

I already had Apache and mod_python installed, but in case you don't:

apt-get install apache2 apache2-mpm-prefork
apt-get install libapache2-mod-python

Apache Configuration

Edit /etc/apache2/httpd.conf:

MaxClients 2
MaxRequestsPerChild 350
KeepAlive Off
NameVirtualHost 127.0.0.1:8080
Listen 8080

<VirtualHost 127.0.0.1:8080>
    ServerName www.saltycrane.com
    <Location "/">
        SetHandler python-program
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE iwiwdsmi.settings
        PythonPath "['/srv/SaltyCrane', '/srv/python-packages'] + sys.path"
        PythonDebug Off
    </Location>
</VirtualHost>

<VirtualHost 127.0.0.1:8080>
    ServerName handsoncards.com
    <Location "/">
        SetHandler python-program
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE handsoncards.settings
        PythonPath "['/srv/HandsOnCards', '/srv/python-packages'] + sys.path"
        PythonDebug Off
    </Location>
</VirtualHost>

Edit /etc/apache2/ports.conf and comment out the following two lines:

#NameVirtualHost *:80
#Listen 80

Restart Apache

sudo /etc/init.d/apache2 restart

Add Django's reverse proxy middleware

Edit your settings.py file to include django.middleware.http.SetRemoteAddrFromForwardedFor in MIDDLEWARE_CLASSES. This allows your Django application to use the real IP address of the client instead of 127.0.0.1 from your nginx proxy. It sets Django's request.META['REMOTE_ADDR'] to be request.META['HTTP_X_FORWARDED_FOR'] which we set above in nginx's proxy.conf. For more information, see the Middleware reference in the Django documentation.

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.middleware.http.SetRemoteAddrFromForwardedFor',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

References

Errors

  • A 502 Bad Gateway from Nginx probably means there is something wrong with your Apache setup
  • An Internal Server Error from Apache means something is probably wrong with your Django setup.