Check if module exists, if not install it

I want to check if a module exists, if it doesn't I want to install it.

How should I do this?

So far I have this code which correctly prints f if the module doesn't exist.

try:
    import keyring
except ImportError:
    print 'f'

Solution 1:

import pip

def import_or_install(package):
    try:
        __import__(package)
    except ImportError:
        pip.main(['install', package])       

This code simply attempt to import a package, where package is of type str, and if it is unable to, calls pip and attempt to install it from there.

Solution 2:

Here is how it should be done, and if I am wrong, please correct me. However, Noufal seems to confirm it in another answer to this question, so I guess it's right.

When writing the setup.py script for some scripts I wrote, I was dependent on the package manager of my distribution to install the required library for me.

So, in my setup.py file, I did this:

package = 'package_name'
try:
    return __import__(package)
except ImportError:
    return None

So if package_name was installed, fine, continue. Else, install it via the package manager which I called using subprocess.

Solution 3:

This approach of dynamic import work really well in cases you just want to print a message if module is not installed. Automatically installing a module SHOULDN'T be done like issuing pip via subprocess. That's why we have setuptools (or distribute).

We have some great tutorials on packaging, and the task of dependencies detection/installation is as simple as providing install_requires=[ 'FancyDependency', 'otherFancy>=1.0' ]. That's just it!

But, if you really NEED to do by hand, you can use setuptools to help you.

from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

# Printing all installed modules
print tuple(working_set)

# Detecting if module is installed
try:
    dep = working_set.require('paramiko>=1.0')
except DistributionNotFound:
    pass

# Installing it (anyone knows a better way?)
from setuptools.command.easy_install import main as install
install(['django>=1.2'])