Installing Python Module Within Code

Installing python module within code

The officially recommended way to install packages from a script is by calling pip's command-line interface via a subprocess. Most other answers presented here are not supported by pip. Furthermore since pip v10, all code has been moved to pip._internal precisely in order to make it clear to users that programmatic use of pip is not allowed.

Use sys.executable to ensure that you will call the same pip associated with the current runtime.

import subprocess
import sys

def install(package):
subprocess.check_call([sys.executable, "-m", "pip", "install", package])

use pip install/uninstall inside a python script

It's not a good idea to install packages inside the python script because it requires root rights. You should ship additional modules alongside with the script you created or check if the module is installed:

try:
import ModuleName
except ImportError:
print 'Error, Module ModuleName is required'

If you insist in installing the package using pip inside your script you'll have to look into call from the subprocess module ("os.system()" is deprecated).

There is no pip module but you could easily create one using the method above.

How to install a missing python package from inside the script that needs it?

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.

Pip Install a List of Packages

You should be getting an error here, because the list items in the call to check_call should be strings, but you're passing packages, which is a list of strings. I think you want:

subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + package)

Here, we're appending the package list to the arguments, so we'll end up with a command line like:

python -m pip install glob2 selenium...

How to call pip from a python script and make it install locally to that script?

It turns out not too hard to use virtualenv directly from the script to manage this problem. I wrote a small helper class.

import sys
import subprocess

class App:
def __init__(self, virtual_dir):
self.virtual_dir = virtual_dir
self.virtual_python = os.path.join(self.virtual_dir, "Scripts", "python.exe")

def install_virtual_env(self):
self.pip_install("virtualenv")
if not os.path.exists(self.virtual_python):
import subprocess
subprocess.call([sys.executable, "-m", "virtualenv", self.virtual_dir])
else:
print("found virtual python: " + self.virtual_python)

def is_venv(self):
return sys.prefix==self.virtual_dir

def restart_under_venv(self):
print("Restarting under virtual environment " + self.virtual_dir)
subprocess.call([self.virtual_python, __file__] + sys.argv[1:])
exit(0)

def pip_install(self, package):
try:
__import__(package)
except:
subprocess.call([sys.executable, "-m", "pip", "install", package, "--upgrade"])

def run(self):
if not self.is_venv():
self.install_virtual_env()
self.restart_under_venv()
else:
print("Running under virtual environment")

And can use it from the top of the main script make_salad.py like so

pathToScriptDir = os.path.dirname(os.path.realpath(__file__))

app = App(os.path.join(pathToScriptDir, "make_salad_virtual_env"))

app.run()

app.install("colorama")
app.install("pathlib")
app.install("iterfzf")
app.install("prompt_toolkit")
app.install("munch")
app.install("appdirs")
app.install("art")
app.install("fire")
app.install("appdirs")

print "making salad"

The first time running it will install the virtual env and all the required packages. Second time it will just run the script under the virtual environment.

found virtual python: C:\workspace\make_salad_virtualenv\Scripts\python.exe
Restarting under virtual environment C:\workspace\make_salad_virtualenv\Scripts
Running under virtual environment
Making Salad

How to check if a module is installed in Python and, if not, install it within the code?

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.

upgrading python module within code

Try pip.main(['install', '--upgrade', package]).

"--upgrade" is a separate command-line argument, so you need to pass it separately to main.

How to run a pip install command from a subproces.run()

I suggest you stick to subprocess.run(['pip', 'install', '-r', 'requirements.txt']). To quote the subprocess docs.

Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).

Avoiding the use of shell=True will save you a lot of trouble if you ever want to run the script on a different system. In general, though, I recommend avoiding reliance on a shell. That is, after all, why you are using Python and not, say, Bash.



Related Topics



Leave a reply



Submit