1. Kumar McMillan
  2. velcro

Overview

HTTPS SSH

Velcro is a script that sets up a Python project for local installation.

Velcro is a simple "fastener" for virtualenv and pip (which is optional). All it really does is help with installing modules into the virtualenv and sets forth some conventions for what config files you'll be using. It was designed for the type of Python project that needs to be installed on your machine without disturbing your global environment. The same project might also import a few globally installed packages when they exist, such as psycopg, docutils, etc. Here's Velcro it works ...

Installation

Velcro requires virtualenv to be installed and available for import. At the time of this writing, if you want to share globally installed modules that require command line scripts (e.g. nosetests) then you'll need this temporary fork of virtualenv

Start a new project

Change into the directory of your project and type:

$ velcro
wrote ./velcro.conf
wrote ./requirements.txt
wrote ./setup_local_project.py

Virtualenv fastened!

Next steps:

  1. Edit requirements.txt
  2. [optional] Change paths in velcro.conf
  3. Run python setup_local_project.py and you'll have
     all installed modules and scripts available to
     run in ./env/bin/*

These files are designed to live in your project permanently so go ahead and commit them if you're using version control. If the config files already exist they will not be overwritten. The setup_local_project.py script is always overwritten since you never need to edit that.

Edit requirements

If your project requires other modules, add a specification per line of the requirements file. For example, to require nose greater than or equal to version 0.11.1 add:

nose>=0.11.1

Consult the docs on pip requirement files for details on what specifications are valid.

Setup your project's virtualenv

Your users can now setup the project with:

$ python setup_local_project.py

And a virtualenv will be created in ./env (or whatever location you set in velcro.conf) with all requirements installed. Users of your project do not have to install anything before running this script. You will probably want to set an ignore rule in your version control system so that it does not manage the ./env directory. This script is a standard virtualenv bootstrap script with some custom code.

Running scripts

Now that you have a project setup for use with nose you can run

$ ./env/bin/nosetests --help

And you will be using a custom version of nose isolated from your global Python installation.

Deploying to a web server, etc

virtualenv does all the work from here on out. If you want to deploy your local project using mod_wsgi then just follow the normal instructions for using virtualenv with mod_wsgi.

At the time of this writing, deploying with mod_wsgi is as simple as adding the python-path to your daemon process:

WSGIDaemonProcess yourapp python-path=/path/to/yourapp/env/lib/python2.x/site-packages user=you group=you threads=25
WSGIProcessGroup yourapp

... then creating a WSGI Python script named yourapp/deploy/yourapp.wsgi with code like:

from yourapp.wsgi_app import application

... and configuring Apache to serve requests via the script:

WSGIScriptAlias / /path/to/yourapp/deploy/yourapp.wsgi

Installing requirements with easy_install instead of pip

Until pip supports all features of easy_install (like pre-compiled binary eggs) you may need to tell velcro to use easy_install. You can do that by setting this in velcro.conf:

install-bin = easy_install

Be sure that each line (besides comments) in requirements.txt is a valid easy_install spec

Combining requirements with a setup.py file

If you want to allow users to have the choice between setting up a local project and installing globally, you can write a setup.py file like this that consumes requirements.txt (as long as each line is is a valid easy_install spec)

def gen_install_specs(requirements_file):
    reqfile = open(requirements_file, 'r')
    for line in reqfile:
        line = line.strip()
        if not line:
            continue
        if line.startswith('#'):
            continue
        yield line

from setuptools import setup, find_packages
setup(
    name='YourModule',
    install_requires=[spec for spec in gen_install_specs("./requirements.txt")],
    version="1.0",
    description="",
    long_description="",
    author='You',
    packages=find_packages(exclude=['ez_setup'])
)

Comparing Velcro to Other Tools

zc.Buildout

Since Velcro provides a way to declare dependencies for a project it is a bit like zc.buildout. However, Velcro does not offer as many features, like building non-Python libraries and so on. Velcro's major difference is that it's built on top of virtualenv so it feels more like standard Python. As one specific example, you can globally install low-level packages (like psycopg) to be shared among all projects simply with python setup.py install. In zc.buildout you'd have to create a shared egg directory for this and manage installation either in buildout or by some other means.

Paver

The Python paver tool can probably do everything that Velcro can do and certainly does more. Velcro is meant to be a simple wrapper around virtualenv for local project installation; it's not a build or make tool.

Examples

A Django Web Application

Here's an easy way to get started on a Django application using velcro. First create a directory, cd into it and run velcro:

$ cd ./your-project
$ velcro

Next, open requirements.txt and add a line like this to install Django:

Django>=1.0.2

Now set up your local project:

$ python setup_local_project.py

That will create a virtualenv and install Django. That's it! Now you can start building your project, run the development server or whatever.

$ ./env/bin/django-admin.py startproject yoursite
$ ./env/bin/python yoursite/manage.py runserver

Check the Django docs for more info on Django. The previous section on deploying to a web server explains how to deploy your site with a virtualenv.