18

Assuming that you already have pip or easy_install installed on your python distribution, I would like to know how can I installed a required package in the user directory from within the script itself.

From what I know pip is also a python module so the solution should look like:

try:
    import zumba
except ImportError:
    import pip
    # ... do "pip install --user zumba" or throw exception   <-- how?
    import zumba

What I am missing is doing "pip install --user zumba" from inside python, I don't want to do it using os.system() as this may create other problems.

I assume it is possible...

sorin
  • 149,293
  • 163
  • 498
  • 754
  • 1
    How about this solution: http://stackoverflow.com/questions/12332975/installing-python-module-within-code – Andrei Kaigorodov Jun 24 '13 at 09:09
  • 2
    I think this would be a very undesirable coding practice outside of the setup script. I (as I would guess most people) would not like/trust any program that I run that changes my environment. Tools like pip and virtualenv are specifically there so that the "user" has control of what package are installed down to which version. Not an expert on distutils but I know that it has facilities to list prerequisite requirements for any package. If it is only for your own use you could probably munge a bit of that code. – Joop Jun 24 '13 at 09:15
  • Thanks you guys, it works perfectly. As a note, that's a good solution for standalone scripts, not modules/packages. – sorin Jun 24 '13 at 09:52

3 Answers3

26

Updated for newer pip version (>= 10.0):

try:
    import zumba
except ImportError:
    from pip._internal import main as pip
    pip(['install', '--user', 'zumba'])
    import zumba

Thanks to @Joop I was able to come-up with the proper answer.

try:
    import zumba
except ImportError:
    import pip
    pip.main(['install', '--user', 'zumba'])
    import zumba

One important remark is that this will work without requiring root access as it will install the module in user directory.

Not sure if it will work for binary modules or ones that would require compilation, but it clearly works well for pure-python modules.

Now you can write self contained scripts and not worry about dependencies.

Koterpillar
  • 7,690
  • 2
  • 25
  • 39
sorin
  • 149,293
  • 163
  • 498
  • 754
  • 1
    This worked for me to install `boto3` on the PythonAnywhere service. Seems like pip.main() is just a wrapper around the command line tool, rather than offering an API. Kind ugly, but functional I suppose. I was getting an "access denied" message, until I added `--user`. –  Aug 11 '15 at 18:19
  • 2
    I've updated this answer for the newer pip versions. Hopefully it's OK as it doesn't change the spirit of the answer, just the location of the method. – Koterpillar Jul 29 '19 at 06:24
11

As of pip version >= 10.0.0, the above solutions will not work because of internal package restructuring. The new way to use pip inside a script is now as follows:

try: import abc
except ImportError:
    from pip._internal import main as pip
    pip(['install', '--user', 'abc'])
    import abc
Phoenix
  • 315
  • 3
  • 14
3

I wanted to note that the current accepted answer could result in a possible app name collision. Importing from the app namespace doesn't give you the full picture of what's installed on the system.

A better way would be:

import pip

packages = [package.project_name for package in pip.get_installed_distributions()]

if 'package' not in packages:
    pip.main(['install', 'package'])
Casey
  • 353
  • 3
  • 13