How to check if a module is installed in Python and, if not, install it within the code?
Solution 1
EDIT - 2020/02/03
The pip
module has updated quite a lot since the time I posted this answer. I've updated the snippet with the proper way to install a missing dependency, which is to use subprocess
and pkg_resources
, and not pip
.
To hide the output, you can redirect the subprocess output to devnull:
import sys
import subprocess
import pkg_resources
required = {'mutagen', 'gTTS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
python = sys.executable
subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
Like @zwer mentioned, the above works, although it is not seen as a proper way of packaging your project. To look at this in better depth, read the the page How to package a Python App.
Solution 2
you can use simple try/except:
try:
import mutagen
print("module 'mutagen' is installed")
except ModuleNotFoundError:
print("module 'mutagen' is not installed")
# or
install("mutagen") # the install function from the question
Solution 3
If you want to know if a package is installed, you can check it in your terminal using the following command:
pip list | grep <module_name_you_want_to_check>
How this works:
pip list
lists all modules installed in your Python.
The vertical bar | is commonly referred to as a "pipe". It is used to pipe one command into another. That is, it directs the output from the first command into the input for the second command.
grep <module_name_you_want_to_check>
finds the keyword from the list.
Example:
pip list| grep quant
Lists all packages which start with "quant" (for example "quantstrats"). If you do not have any output, this means the library is not installed.
Solution 4
You can check if a package is installed using pkg_resources.get_distribution
:
import pkg_resources
for package in ['mutagen', 'gTTS']:
try:
dist = pkg_resources.get_distribution(package)
print('{} ({}) is installed'.format(dist.key, dist.version))
except pkg_resources.DistributionNotFound:
print('{} is NOT installed'.format(package))
Note: You should not be directly importing the pip
module as it is an unsupported use-case of the pip
command.
The recommended way of using pip
from your program is to execute it using subprocess
:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'my_package'])
Solution 5
Although @girrafish's answer might suffice, you can check package installation via importlib
too:
import importlib
packages = ['mutagen', 'gTTS']
[subprocess.check_call(['pip', 'install', pkg])
for pkg in packages if not importlib.util.find_spec(pkg)]
Foxes
Updated on November 30, 2021Comments
-
Foxes over 2 years
I would like to install the modules 'mutagen' and 'gTTS' for my code, but I want to have it so it will install the modules on every computer that doesn't have them, but it won't try to install them if they're already installed. I currently have:
def install(package): pip.main(['install', package]) install('mutagen') install('gTTS') from gtts import gTTS from mutagen.mp3 import MP3
However, if you already have the modules, this will just add unnecessary clutter to the start of the program whenever you open it.
-
Foxes almost 7 yearsThis works very well, but it gives the output of "requirement already satisfied", adding unnecessary clutter to the start of the code when you open it. Is there anyway to make it so it doesn't echo the "requirement already satisfied"?
-
zwer almost 7 yearsPlease add a disclaimer that a kitten dies whenever somebody uses
import pip
in their code as a workaround for proper packaging. -_- -
Girrafish almost 7 years@Gameskiller01 I added the code for what you're looking for, although it is not my code. Please look at the link as I have no credit for that.
-
Foxes almost 7 years@TheGirrafish, I found that exact code as well in my searches about 5 minutes ago. XD Thanks anyway.
-
aoh almost 7 years
pip.get_installed_distributions()
returns type EggInfoDistribution, so I think if you want to use the lineif package not in pip.get_installed_distributions():
you either change it tostr(pip.get_installed_distributions())
or something else that allows us to make that comparison -
Girrafish almost 7 years@aoh Not sure what you mean,
pip.get_installed_distributions()
returns type list? -
aoh almost 7 years@TheGirrafish Sorry, I meant that the list is comprised of "EggInfoDistribution" (and also DistINfoDistribution") which are part of the pip library. For example in my case, the first item in the list is "xmltodict 0.10.2", but
"xmltodict 0.10.2" in pip.get_installed_distributions()
returns False while"xmltodict 0.10.2" in str(pip.get_installed_distributions())
returns True -
Girrafish almost 7 years@aoh Ohh, yes I see what you mean now, I edited the answer :)
-
Josh Correia almost 6 yearsAs of pip 10.0.0 you must use
import pip._internal
andpip._internal.main
-
live2 about 5 yearsplease add some sescription and not only a code block
-
dcoles over 4 yearsPlease don't import or use any functions from
pip
. It is not a supported use-case and may break at any time: github.com/pypa/pip/issues/5243 -
Girrafish over 4 years@dcoles Thanks for bringing this up, I've changed the code snippet to use
subprocess
overpip
. -
dcoles over 4 yearsAlso rather than using than redirecting
sys.stdout
, I'd recommend just usingsubprocess.check_call(args, stdout=subprocess.DEVNULL)
to ignorepip
's stdout. -
andjelx over 3 yearsFaced with issue that e.g. prompt_toolkit module name returned by pkg_resources.working_set() as prompt-toolkit
-
papiro over 3 yearsThis is totally not the answer because the question is asking how to install as well, and do it all of this from code...
-
matan h over 3 yearsI think the question mean that the Python code will install modules on every computer runs it
-
My Work over 3 yearsHow does this handles versions? Does it update the package to the latest release if it is installed? Does it install the latest version? Can it be specified?
-
aschultz almost 3 years"start with" should technically be "contains" ... grep "\wquant" or grep "^quant" would be more accurate. On Windows I also need grep -E for extended regexes.
-
Prox almost 2 years
[subprocess.check_call([sys.executable, '-m', 'pip', 'install', pkg, '-q']) for pkg in ['datasets'] if not importlib.util.find_spec(pkg)]
sys.executable
should use the python executable, also added-q
for quiet, in case it prints. Great and short answer.