Unfinished Sofware's Blog

Recently I started developing my python applications using virtualenv so that I don’t clutter up the system’s python installation with non-system python packages.

Everything was good until I wanted to use IPython instead of python’s shell…
The issue is that virtualenv creates a different python executable that includes the virtualenv‘s packages into sys.path while IPython stays unaware of the virtualenv‘s packages.

Yet, there’s a solution!!!

In order to solve this issue, IPython comes along to save the day.

IPython provides a way to include additional code to be executed when IPython‘s shell is started.

First, the small script that allows IPython to get virtualenv‘s packages into it’s sys.path.

import site
from os import environ
from os.path import join
from sys import version_info

if 'VIRTUAL_ENV' in environ:
    virtual_env = join(environ.get('VIRTUAL_ENV'),
                       'lib',
                       'python%d.%d' % version_info[:2],
                       'site-packages')
    site.addsitedir(virtual_env)
    print 'VIRTUAL_ENV ->', virtual_env
    del virtual_env
del site, environ, join, version_info

Save the above snippet into your user’s IPython configuration directory ~/.ipython. Save it has, for example, virtualenv.py.

Now, as IPython‘s documentation suggests, edit ~/.ipython/ipy_user_conf.py and somewhere inside the main() function add:

def main():
  execf('~/.ipython/virtualenv.py')

Now, the next time you start IPython‘s shell, if you’ve activated your virtualenv‘s environment, you’ll also get the packages from there too.

Develop:user@machine:~$ ipython
VIRTUAL_ENV -> /home/user/.virtual_python/lib/python2.5/site-packages

In [1]:

And that’s it, there you have your virtualenv aware IPython shell!

 

Comments

  • There’s also the possibility to run:

    easy_install ipython

    from within your virtualenv :)

    Comment by Alexandre Bourget — Apr 23, 2009 1:42:26 PM | # - re

    • Heh, I didn’t tried that one :) Thank!

      Comment by s0undt3ch — Apr 24, 2009 4:31:07 PM | # - re

  • What if you want to use ipython with more than one virtualenv? By default, any ipython egg that is installed will look for config in ~/.ipython, right?

    Comment by Dan Fuchs — Apr 26, 2009 10:16:12 PM | # - re

  • thanks!!!! i was looking exactly for this!!

    Comment by elsonidoq — Sep 6, 2009 3:41:02 PM | # - re

  • Windows version:

    import site
    from os import environ
    from os.path import join
    from sys import version_info

    if ‘VIRTUAL_ENV’ in environ: virtual_env = join(environ.get(’VIRTUAL_ENV’),
    ‘Lib’,
    ‘site-packages’)
    site.addsitedir(virtual_env)
    print ‘VIRTUAL_ENV ->’, virtual_env
    del virtual_env
    del site, environ, join, version_info

    Comment by Randy Syring — Sep 30, 2009 6:31:19 PM | # - re

  • […] and yolk. Everything else (so far) is getting put into a virtual environment. Also, now that I’ve figured out how to get virtualenv and ipython to play nice , isolated development is running smooth as silk. […]

    Pingback by Virtualenv useful on Mac, not so much on PC | insomnihack — Nov 8, 2009 7:59:49 PM | # - re

  • I suggest putting

    sys.path.insert(0, virtual_env)

    before

    site.addsitedir(virtual_env)

    for virtual environments that don’t exclude system-wide Python packages. This way, IPython will always try to import packages from the virtualenv, first, then the system, second, which is the desired behavior. Without the insert, the virtualenv packages may be “overridden” by the system packages.

    Comment by Chris Lasher — Nov 28, 2009 12:00:19 AM | # - re

  • Simpler solution:

    alias ipython=”python -c ‘import IPython; IPython.Shell.IPShell().mainloop()’”

    Comment by Carl Meyer — Feb 10, 2010 9:49:14 PM | # - re

    • Thanks very much, Carl, and the original author. This saved me very much time, and taught me a few more things about how IPython works. Your solution combined with virtualenvwrapper’s hooks have just made my life that much simpler.

      Comment by Keith Solademi — Feb 28, 2010 3:43:04 AM | # - re

    • Update on this method for IPython 0.12 : alias ipython=”python -c ‘import IPython; IPython.embed()’”

      Comment by Michael Ekoka — Jan 13, 2012 9:45:58 PM | # - re

  • Thank you! That’s what I need!

    Comment by Alex — Oct 26, 2010 10:20:53 AM | # - re

  • Typo about ‘execf’ when it should be ‘exec’

    Comment by Jon — Sep 3, 2011 2:46:35 PM | # - re

  • Oops, meant ‘execfile’.

    Comment by Jon — Sep 3, 2011 3:05:45 PM | # - re

  • Hi,

    excellent blog post, but if you’re on IPython>=0.11, the config.py has changed…

    got to first create ~/.ipython/profile_default - steps detailed upon IPython startup - just follow that, so I won’t go through it in this comment.

    add these lines to ipython_config.py instead:

    1. List of files to run at IPython startup.
      import os
      c.InteractiveShellApp.exec_files = [ os.path.expanduser(’~/.ipython/virtualenv.py’) ]

    cheers for the tip again!

    Comment by Lee Wei — Sep 7, 2011 12:17:49 AM | # - re

  • The `ipython` shell command most likely maps to a python script. A quick solution is to just start that script directly with the `python` command, or better yet, alias the `ipython` command with `python /path/to/ipython/script`

    $ which ipython
    /usr/local/bin/ipython

    so in .bashrc enter

    alias ipython=”python /usr/local/bin/ipython”

    Comment by Michael Ekoka — Jan 13, 2012 10:36:36 PM | # - re

  • Hi,

    why not scratch this post and update it with the stuff from the comments, so, the next time people come here, they get it right from the beginning. Otherwise, thanks for blogging about it.

    Comment by the guy — Jul 25, 2012 1:13:36 AM | # - re

  • Thanks for working this out - we ended up adapting this trick and integrating it into IPython for version 0.13.

    You can see our version of the code here:

    https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py#L697

    Comment by Thomas Kluyver — Aug 20, 2012 1:08:03 PM | # - re

    • Sorry for taking so long to reply, still, Thanks!

      Comment by s0undt3ch — Dec 27, 2012 2:06:28 PM | # - re

Leave a Reply