67

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
  • 1,137
  • 3
  • 10
  • 19
  • do you want a python script to run commands that execute the installation check and installation? or can you just execute shell commands on all these "computers"? – JacobIRR May 26 '17 at 22:04
  • 4
    While you can technically force module installation from within your script, do not do that, it's a bad practice and people will inevitably hate you if you do it. Instead, learn how to properly package & distribute your Python application: https://www.digitalocean.com/community/tutorials/how-to-package-and-distribute-python-applications – zwer May 26 '17 at 22:04
  • @zwer Is correct. Don't do this. If your package has dependences, let `pip` handle that. – Christian Dean May 26 '17 at 22:13
  • Possible duplicate: [Check if Python Package is installed](https://stackoverflow.com/questions/1051254/check-if-python-package-is-installed) – Herpes Free Engineer Jul 04 '18 at 18:29

12 Answers12

82

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.

Girrafish
  • 2,320
  • 1
  • 19
  • 32
  • This 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"? – Foxes May 26 '17 at 22:11
  • 17
    Please add a disclaimer that a kitten dies whenever somebody uses `import pip` in their code as a workaround for proper packaging. -_- – zwer May 26 '17 at 22:13
  • @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. – Girrafish May 26 '17 at 22:36
  • @TheGirrafish, I found that exact code as well in my searches about 5 minutes ago. XD Thanks anyway. – Foxes May 26 '17 at 22:38
  • `pip.get_installed_distributions()` returns type EggInfoDistribution, so I think if you want to use the line `if package not in pip.get_installed_distributions():` you either change it to `str(pip.get_installed_distributions())` or something else that allows us to make that comparison – aoh Jul 18 '17 at 01:34
  • @aoh Not sure what you mean, `pip.get_installed_distributions()` returns type list? – Girrafish Jul 18 '17 at 22:23
  • 1
    @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 – aoh Jul 18 '17 at 22:43
  • @aoh Ohh, yes I see what you mean now, I edited the answer :) – Girrafish Jul 18 '17 at 22:57
  • As of pip 10.0.0 you must use `import pip._internal` and `pip._internal.main` – Josh Correia Jul 27 '18 at 15:36
  • Please don't import or use any functions from `pip`. It is not a supported use-case and may break at any time: https://github.com/pypa/pip/issues/5243 – dcoles Feb 02 '20 at 18:39
  • 1
    @dcoles Thanks for bringing this up, I've changed the code snippet to use `subprocess` over `pip`. – Girrafish Feb 03 '20 at 19:18
  • 3
    Also rather than using than redirecting `sys.stdout`, I'd recommend just using [`subprocess.check_call(args, stdout=subprocess.DEVNULL)`](https://docs.python.org/3/library/subprocess.html#subprocess.check_call) to ignore `pip`'s stdout. – dcoles Feb 04 '20 at 03:57
  • Faced with issue that e.g. prompt_toolkit module name returned by pkg_resources.working_set() as prompt-toolkit – andjelx Oct 23 '20 at 15:54
  • How 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? – My Work Feb 17 '21 at 06:47
39

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

matan h
  • 900
  • 1
  • 10
  • 19
29

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.

karel
  • 5,489
  • 46
  • 45
  • 50
jack
  • 315
  • 3
  • 3
  • 2
    please add some sescription and not only a code block – live2 Mar 16 '19 at 08:49
  • This is totally not the answer because the question is asking how to install as well, and do it all of this from code... – papiro Nov 11 '20 at 01:29
  • "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. – aschultz May 28 '21 at 01:03
  • This is not an answer that points out how to find whether the package is installed using a Python code. This answer is using a command, thus requires user interaction. – Andrew Aug 10 '23 at 07:28
9

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'])
dcoles
  • 3,785
  • 2
  • 28
  • 26
4

For Python 3.3+ use,

import importlib
spec = importlib.util.find_spec('some_module')
if spec is not None:
    print('module is installed')
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
3

Although @girrafish's answer might suffice, you can check package installation via importlib too:

import importlib

packages = ['mutagen', 'gTTS']
[subprocess.check_call([sys.executable, '-m', 'pip', 'install', pkg]) 
for pkg in packages if not importlib.metadata.distribution(pkg)]
Grisha Levit
  • 8,194
  • 2
  • 38
  • 53
Shayan Amani
  • 5,787
  • 1
  • 39
  • 40
  • 1
    `[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. – Prox May 31 '22 at 17:29
2

You can use the command line :

python -m MyModule

it will say if the module exists

Else you can simply use the best practice :

pip freeze > requirements.txt

That will put the modules you've on you python installation in a file

and :

pip install -r requirements.txt

to load them

It will automatically you purposes

Have fun

D. Peter
  • 487
  • 3
  • 12
1

Another solution it to put an import statement for whatever you're trying to import into a try/except block, so if it works it's installed, but if not it'll throw the exception and you can run the command to install it.

Joseph Long
  • 241
  • 1
  • 3
  • 12
1

You can run pip show package_name or for broad view use pip list Reference

0

If you would like to preview if a specific package (or some) are installed or not maybe you can use the idle in python. Specifically :

  1. Open IDLE
  2. Browse to File > Open Module > Some Module
  3. IDLE will either display the module or will prompt an error message.

Above is tested with python 3.9.0

Andrew
  • 1
  • 1
  • 1
    I think the question mean that the Python code will install modules on every computer runs it – matan h Feb 16 '21 at 08:17
0

You can do either of these things (Simple, really)

pip list | grep <package_name>

This only shows if a package is present or not The other way would be to use show ,which gives more detail:

pip show <package_name>

You can embed these in a bash script; if it doesn't return the package name, you simply pip install --user <package_name> them

0

You can use the command pip list for determine that:

import os

try:
   pip_packages = os.popen("pip list").read()

except Exception:
        print("Error: pip is not installed")

if pip_packages.find("lib one" and "lib two") != -1:
    print("Required libs are alerty installed")

else:
     os.system("pip install lib one lib two")
     print("Required libs are installed")
nonodu88
  • 1
  • 1