@ wrote... (10 years, 5 months ago)

This was originally the majority of this post: Start a django project the right way but I've decided to put in it's own post instead.

I'm assuming you're on OSX. If you're on Linux most of these steps will be the same. If you're on Windows… Install VMWare and then install Linux.

I've added a tl;dr at the end.

Although I have tweaked this over the years, the original code came from (I think, I've long since lost the bookmark) klymyshyn.com

Get python working properly

Use the newest version of python from homebrew.

brew install python
easy_install pip
pip install virtualenv virtualenvwrapper ipython

This will create your virtualenv directory and setup your environment for the first time.

source `which virtualenvwrapper.sh`

Get your shell working for you

Put the following at the end of your ~/.bashrc

export WORKON_HOME=~/.virtualenvs
source `which virtualenvwrapper.sh`

export PREVPWD=`pwd`
export PREVENV_PATH=

handle_virtualenv(){
    if [ "$PWD" == "$PREVPWD" ]; then
        return;
    fi

    # deactivate virtualenv if applicable
    PREVPWD="$PWD";
    if [ -n "$PREVENV_PATH" ]; then
        if [ "`echo "$PWD" | grep -c $PREVENV_PATH`" = "0"  ]; then
            deactivate
            unset venv_ps1
            PREVENV_PATH=
        fi
    fi

    # activate virtualenv if applicable
    if [ -e "$PWD/.venv" ] && [ "$PWD" != "$PREVENV_PATH" ]; then
        PREVENV_PATH="$PWD"

        # you can put some exports in .venv to setup your environment
        # eg. DJANGO_SETTINGS_MODULE, PYTHONDONTWRITEBYTECODE, PYTHONPATH, PYTHONSTARTUP
        # but they aren't unset when you leave this directory
        #
        # two likely variables to set are VENV and VDIR. VENV is by default
        # the current directory or set VDIR to use regular virtual env and not
        # a wrapper
        source $PWD/.venv

        if [ -e "$VDIR/bin/activate" ]; then
            source $VDIR/bin/activate
            export venv_ps1=" venv:$VDIR"
            return
        fi

        if [ -z $VENV ]; then
            VENV=`basename $PWD`
        fi

        if [ -n $VENV ]; then
            if workon $VENV; then
                export venv_ps1=" venv:$VENV"
            fi
        else
            echo "error: not activating a virtual environment"
        fi

        unset VENV
        unset VDIR
    fi
}

# this function gets called every time the prompt is shown
function prompt_command_collection() {
    handle_virtualenv
    # this will change your prompt so you can see what's going on
    # comment out if you like your current prompt (give this a try though)
    export PS1="[\u@\h \[\e[1;34m\]\w\[\e[0m\]${venv_ps1}]\n\\$ "
}

export PROMPT_COMMAND=prompt_command_collection

run: source ~/.bashrc in all your open terminals or reopen all your terminals.

Make your project directory

I'm assuming that you're going through all this pain to make a django project but in reality this works for any python project.

By default this script will try to activate a virtual environment with the same name as the current directory. ie: if the file is ~/src/youtube_killer/.venv then the script will try to activate a virtual environment called youtube_killer.

If you want to activate a different environment, then put the name in .venv. eg. echo other_name > .venv. This is useful if you have several clones of a git repo that all use the same environment or if you like to use a generic environment with some standard installed packages.

I put all my projects under ~/src/.

The is the actual command to create a virtual environment.

mkvirtualenv --no-site-packages project_name

And here is how to do it with some visual feedback.

mkvirtualenv --no-site-packages project_name
deactivate # this makes it more fun later
cd
mkdir -p src/project_name
touch project_name/.venv
cd src/project_name # you should now be using virtenv automatically
which python
cd .. # stop using virtenv automatically
which python

And that is how you magically use virtual environments.

tl;dr

# copy bash functions into .bashrc
sudo easy_install pip
pip install virtualenv virtualenvwrapper
source `which virtualenvwrapper.sh`
echo "source `which virtualenvwrapper.sh`" >> ~/.bashrc
mkvirtualenv project_name
deactivate
mkdir project_name
touch project_name/.venv
cd project_name # voila
Category: tech, Tags: python, shell
Comments: 10
Comments
1.
Peter @ October 17, 2013 wrote... (9 years, 11 months ago)

Nice solution, thanks a bunch!

2.
Kurt Neufeld @ October 17, 2013 wrote... (9 years, 11 months ago)

Glad somebody found it useful.

3.
WebOrCode @ November 25, 2013 wrote... (9 years, 10 months ago)

You need to make .venv file in your “project_name” directory.

I have lost 20 minutes trying to figure it out. So hope that to someone will this be useful.

4.
Ken @ December 4, 2013 wrote... (9 years, 9 months ago)

Fantastic! This is great, and I like the way that it unloads the environment too, unlike with autoenv.

However, I was wondering what the following line is for:

unalias python 2> /dev/null

Surely deactivate should deal with unloading the loaded virtualenv, without needing to unalias anything?

Thanks for the great solution!

5.
Kurt Neufeld @ December 4, 2013 wrote... (9 years, 9 months ago)

That line was a relic from when I had 'alias python=ipython' as part of my activate function. Making that ipython alias can have unfortunate side effects.

I've deleted the unalias line from the post, thanks for catching that, good eye!

Kurt

6.
Noella @ May 8, 2015 wrote... (8 years, 4 months ago)

Love this, really helps productivity!

7.
kilgore trout @ December 21, 2015 wrote... (7 years, 9 months ago)

I am just learning python, and this is pretty sweet! Glad to find this before getting too far into learning.

I am feeling my way around both virtualenv and virtualenvwrapper, and made a little mistake that took a minute to correct… Being a complete n00b, I first tried:

$ virtualenv --no-site-packages PROJECT_NAME
$ touch PROJECT_NAME/.venv
$ cd PROJECT_NAME

and got a nasty error that the PROJECT_NAME environment did not exist.

So if you're new too, don't mix up virtualenv with mkvirtualenv! mkvirtualenv is a command within virtualenvwrapper, and is the right thing to use to make the automatic activation work properly.

8.
kilgore trout @ December 21, 2015 wrote... (7 years, 9 months ago)

Also for some reason, the automatic activation does not work if I close and re-open my terminal windows. It seems that I must explicitly re-run source ~/.bash_profile or source ~/.bashrc in order to get automatic activation to work.

If anyone else has run into this issue or can easily spot why this doesn't work, please let me know! Kind of annoying to have to run this for every terminal window.

9.
Kurt Neufeld @ December 22, 2015 wrote... (7 years, 9 months ago)

It sounds like bash is not your shell. Try typing echo $SHELL. It should come back with something along the lines of /bin/bash.

If you're using zsh or another shell you need to add

source `which virtualenvwrapper.sh`

to your your shell profile, ~/.zshrc or whatever.

10.
kilgore trout @ December 22, 2015 wrote... (7 years, 9 months ago)

Thanks Kurt! Terminal was set to use sh instead of bash as the default shell. I changed this, and everything works like a charm.

Click here to add a comment