Installer le module python dans le code

310

J'ai besoin d'installer un package de PyPi directement dans mon script. Peut-être qu'il y a un module ou une fonctionnalité distutils( distribute, pipetc.) qui me permet d'exécuter simplement quelque chose comme pypi.install('requests')et les demandes seront installées dans mon virtualenv.

chuwy
la source
4
Pourquoi ne définissez-vous pas le module associé comme dépendance dans le setup.py de votre propre package?
Andreas Jung
5
vous savez ... la façon dont c'est censé être fait ... mais vous pourriez toujours os.system ("pip install blah") mais vous pourriez avoir besoin d'un accès sudo ... mieux pour en faire une dépendance dans votre configuration. py
Joran Beasley
2
Envisageriez-vous de modifier la réponse acceptée ici? L'importation pipn'est jamais une bonne idée - le simple fait que tout son contenu soit à _internalpartir de la version 10 ...
Antti Haapala
2
@chuwy stackoverflow.com/a/50255019/918959 <= celui-ci. pip._internaln'est pas conçu pour être importable, il peut faire des choses absolument aléatoires lorsqu'il est importé dans un autre programme.
Antti Haapala
3
@AnttiHaapala ok je l'ai changé. Personnellement, je n'aime pas les deux solutions, mais je suis loin de Python ces jours-ci, donc je fais confiance à votre avis.
chuwy

Réponses:

255

La façon officiellement recommandée d'installer des packages à partir d'un script consiste à appeler l'interface de ligne de commande de pip via un sous-processus. La plupart des autres réponses présentées ici ne sont pas prises en charge par pip . De plus, depuis pip v10, tout le code a été déplacé pip._internalprécisément afin de faire comprendre aux utilisateurs que l'utilisation programmatique de pip n'est pas autorisée.

Utilisez sys.executablepour vous assurer que vous appellerez la même chose pipassociée à l'exécution actuelle.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])
Aaron de Windt
la source
Un problème avec cela est que, pour les utilisateurs novices sous Windows, python et pip ne sont pas toujours sur leur PATH, et donc un fichier .py qui pourrait être double-cliqué serait très pratique, alors qu'un commentaire "pip install xxx" peut être assez délicat.
jdpipe
CalledProcessError: La commande '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' a renvoyé un état de sortie différent de zéro 1.
parvij
383

Vous pouvez également utiliser quelque chose comme:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')
Rikard Anglerud
la source
3
@nbro vous passez les options pip.main()comme vous le feriez sur la ligne de commande (mais avec chaque option comme une entrée distincte dans la liste, au lieu d'une seule chaîne). Et pour spécifier la version du package que vous voulez, faites la même chose que sur la ligne de commande. Ex:pip.main(['install', 'pip==7.1.0'])
Kaos
3
Voir aussi stackoverflow.com/questions/6457794/… , qui montre comment gérer le cas où une installation échoue.
P. Myer Nore
25
from pip._internal import main as pipmainalors vous pouvez utiliser pipmain()tout comme le déprécié pip.main()voir stackoverflow.com/questions/43398961/…
ventilateur numéro un de Bjorks
17
son obsolète maintenant.
Morse
6
Il est déconseillé pour une raison et n'est plus recommandé. voir pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK
71

Si vous souhaitez utiliser pippour installer le package requis et l'importer après l'installation, vous pouvez utiliser ce code:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

Si vous avez installé un package en tant qu'utilisateur, vous pouvez rencontrer le problème que vous ne pouvez pas simplement importer le package. Voir Comment actualiser sys.path? pour plus d'informations.

rominf
la source
4
Une idée de comment faire ça sur Python 3? imp.reload(site)me faitRuntimeError: dictionary changed size during iteration
kgadek
où cela installe-t-il le package, après avoir fait cela, je n'ai pas pu le faire pip uninstall <package_name>. Je peux toujours le désinstaller en utilisant pip.mainmais je voulais juste savoir où installer le package?
Ishan Khare
Était curieux. cela fonctionnerait-il correctement si je fais pip install requests[security]:? Je ne savais pas si cela définirait correctement les globales correctement.
Fallenreaper
4
Dépassé. pip.mainne fonctionne plus. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim
22

Cela devrait fonctionner:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])
quantum
la source
1
Oui, ça devrait vraiment marcher. Mais je pensais qu'il y avait une manière plus élégante;) J'attendrai un peu, peut-être qu'il y en a.
chuwy
1
@Downvoter: Qu'est-ce qui ne va pas exactement avec ma réponse? Cette réponse a tout l'OP voulu. Il n'utilise même pas de shell.
quantum
13
Cela dépend de la bonne version de pip étant le premier sur le chemin. Si l'utilisateur exécute une autre installation de python, pip s'installera dans la première au lieu de l'actuelle. L'approche d'importation ci-dessus s'installera au bon endroit. J'ai quand même voté pour contrer le vote négatif.
GaryBishop
6
Selon la façon dont le script s'exécute, vous n'appelerez pas le bon pip.
Natim
5
Appeler [sys.executable, '-m', 'pip', 'install', name]c'est s'assurer d'avoir le "bon" pip ici.
wim
12

j'ai ajouté une gestion des exceptions à la réponse de @ Aaron.

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd
Sohan Das
la source
1
belle implémentation de sous-processus et pip, mieux que la plupart des solutions ici
Shantanu Shady
3
Vous ne vérifiez pas la valeur de retunr subprocess.callpour que le code puisse échouer.
Antti Haapala
5

Vous définissez le module dépendant dans le setup.py de votre propre package avec l'option "install_requires".

Si votre package doit avoir un script de console généré, vous pouvez utiliser le point d'entrée "console_scripts" afin de générer un script wrapper qui sera placé dans le dossier "bin" (par exemple de votre environnement virtualenv).

Andreas Jung
la source
1
C'est la bonne réponse et la seule façon raisonnable de gérer les dépendances d'un projet Python. Cela fonctionnera avec virtualenv, Fabric, buildout, vous l'appelez. La méthode décrite par @xiaomao, même si elle répond exactement à ce que le PO a demandé, est une pure folie.
Lukas Graf
7
bien que ce soit un bon conseil, il ne répond pas à la question posée
Corey Goldberg
2
Bien que l'empaquetage soit un sujet, il existe de nombreux autres cas d'utilisation, par exemple un script de déploiement écrit en python.
hoefling