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'])