Installation de packages Python depuis le dossier du système de fichiers local vers virtualenv avec pip


346

Est-il possible d'installer des packages à l'aide de pip à partir du système de fichiers local?

J'ai exécuté python setup.py sdistmon package, qui a créé le fichier tar.gz approprié. Ce fichier est stocké sur mon système à l'adresse /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Maintenant, dans un environnement virtuel, j'aimerais installer des packages provenant de pypi ou de l'emplacement local spécifique /srv/pkg.

Est-ce possible?

PS Je sais que je peux préciser pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. Cela fonctionnera, mais je parle d'utiliser l' /srv/pkgemplacement comme un autre endroit pour que pip recherche si j'ai tapé pip install mypackage.


Je cherchais à installer un package PyPi sans setup.py, à partir de la roue WHL, et il a été installé après avoir téléchargé une version correcte pour ma version Python et exécuté pip install <Path-to-WHL-file>.
Wiktor Stribiżew

Réponses:


136

Je suis sûr que ce que vous cherchez s'appelle --find-links option.

Bien que vous ayez besoin de générer un mannequin index.htmlpour votre index de package local qui répertorie les liens vers tous les packages. Cet outil permet:

https://github.com/wolever/pip2pi


100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackage devrait marcher.
jfs

1
Ça aide. Et nous pouvons utiliser l' option -i de pip pour le traiter comme un PyPI local.
diabloneo

La commande easy_install équivalente esteasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Wilfred Hughes

J'ai dû créer un fichier de distribution source et pas seulement le pointer vers le répertoire du projet ou du package avant qu'il ne fonctionne. Cela m'a fait trébucher. docs.python.org/3.6/distutils/sourcedist.html
Josh

3
Notez que --find-linkscela permettra toujours de rechercher sur PyPI si le package n'est pas trouvé à l'emplacement spécifié ou si une version plus récente est disponible. Sous Windows, je trouve que la combinaison de cela avec --only-binary=packagename(ou --only-binary=:all:) est extrêmement utile. Cela empêche pip d'essayer de télécharger des packages avec des dépendances natives qui n'ont que des distributions sources sur PyPI (et donc nécessitent une compilation), ce qui est la raison la plus courante pour laquelle je dois essayer d'installer à partir d'un répertoire. Contrairement à --no-index, je peux toujours installer d' autres packages à partir de PyPI.
jpmc26

463

Qu'en est-il de::

pip install --help
...
  -e, --editable <path/url>   Install a project in editable mode (i.e. setuptools
                              "develop mode") from a local project path or a VCS url.

par exemple, pip install -e /srv/pkg

où / srv / pkg est le répertoire de niveau supérieur où 'setup.py' peut être trouvé.


49
Cela installera le package en mode développement, ce qui signifie qu'il sera simplement lié à l'emplacement des sources. Si par hasard les sources sont déplacées ou supprimées, l'importation du package échouera.
Trasplazio Garzuglio

3
@MarcoDinacci Ce qui est intéressant, --editablec'est qu'il semble regarder dans le répertoire du package local et définir la source comme un dépôt git s'il en existe un - un peu plus flexible qu'un simple dossier. Je ne trouve cependant pas de documentation pour cela.
NotSimon

3
Bien que cela soit correct pour l'installation d'un package particulier, en particulier un en développement actuel / intensif sur une machine locale ou une URL VCS. Il ne répond pas à la question de la recherche dans un répertoire parent de toutes les sources de package locales par opposition à une source de package particulière . La réponse acceptée fonctionne lorsque vous avez un répertoire ou une URL avec plusieurs packages à partir desquels vous souhaitez installer l'installation.
Gavin

@MarcoDinacci Cependant, supposons qu'un utilisateur télécharge le code. Ils le mettent là où ils veulent que le programme soit, s'ils sont aussi intelligents. Pourquoi voudraient-ils le déplacer?
Zelphir Kaltstahl

1
@Simon existe-t-il un moyen de dire à pip de ne pas chercher un dépôt git? Si je do pip install -evérifie le code de la télécommande git, je voudrais installer le code tel quel (avec des modifications pas encore dans la télécommande).
Pedru

39

J'installe pyfuzzymais n'est pas dans PyPI; il renvoie le message: No matching distribution found for pyfuzzy.

J'ai essayé la réponse acceptée

pip install  --no-index --find-links=file:///Users/victor/Downloads/pyfuzzy-0.1.0 pyfuzzy

Mais cela ne fonctionne pas non plus et renvoie l'erreur suivante:

Ignorer les index: https://pypi.python.org/simple Collecter pyfuzzy Impossible de trouver une version qui satisfait à l'exigence pyfuzzy (à partir des versions:) Aucune distribution correspondante trouvée pour pyfuzzy

Enfin, j'ai trouvé un bon moyen simple: https://pip.pypa.io/en/latest/reference/pip_install.html

Install a particular source archive file.
$ pip install ./downloads/SomePackage-1.0.4.tar.gz
$ pip install http://my.package.repo/SomePackage-1.0.4.zip

La commande suivante a donc fonctionné pour moi:

pip install ../pyfuzzy-0.1.0.tar.gz.

J'espère que ça peut t'aider.


4
Cela a fonctionné pour moi. J'ai essayé les autres approches et je suis tombé sur une Could not find a version that satisfieserreur. Merci.
Rair

21

Voici la solution que j'ai finalement utilisée:

import pip


def install(package):
    # Debugging
    # pip.main(["install", "--pre", "--upgrade", "--no-index",
    #         "--find-links=.", package, "--log-file", "log.txt", "-vv"])
    pip.main(["install", "--upgrade", "--no-index", "--find-links=.", package])


if __name__ == "__main__":
    install("mypackagename")
    raw_input("Press Enter to Exit...\n")

J'ai reconstitué cela à partir d' exemples d'installation de pip ainsi que de la réponse de Rikard sur une autre question . L'argument "--pre" vous permet d'installer des versions hors production. L'argument "--no-index" évite de rechercher les index PyPI. Le "--find-links =." recherches d'arguments dans le dossier local (cela peut être relatif ou absolu). J'ai utilisé les arguments "--log-file", "log.txt" et "-vv" pour le débogage. L'argument "--upgrade" vous permet d'installer des versions plus récentes par rapport aux anciennes.

J'ai également trouvé un bon moyen de les désinstaller. Ceci est utile lorsque vous disposez de plusieurs environnements Python différents. C'est le même format de base, en utilisant simplement "désinstaller" au lieu de "installer", avec une mesure de sécurité pour éviter les désinstallations involontaires:

import pip


def uninstall(package):
    response = raw_input("Uninstall '%s'? [y/n]:\n" % package)
    if "y" in response.lower():
        # Debugging
        # pip.main(["uninstall", package, "-vv"])
        pip.main(["uninstall", package])
    pass


if __name__ == "__main__":
    uninstall("mypackagename")
    raw_input("Press Enter to Exit...\n")

Le dossier local contient ces fichiers: install.py, uninstall.py, mypackagename-1.0.zip


1
Merci. Le "--find-links =." et "--no-index", où la clé pour coller un script python à l'intérieur de mon utilitaire-package, qui supprime d'abord l'ancien-version-package de site-packages puis installe un package tar.gz'ed à partir d'un sous-répertoire du dossier package-utilitaire (ne connaissait pas --find-links =.), puis crée la roue et l'installe. Tout automatisé via plumbum et cliquez. Si quelqu'un le veut, je posterai un lien. A voté.
JackLeEmmerdeur

15

Une option --find-links fait le travail et cela fonctionne à partir du requirements.txtfichier!

Vous pouvez placer des archives de packages dans un dossier et prendre le dernier sans modifier le fichier d'exigences, par exemple requirements:

.
└───requirements.txt
└───requirements
    ├───foo_bar-0.1.5-py2.py3-none-any.whl
    ├───foo_bar-0.1.6-py2.py3-none-any.whl
    ├───wiz_bang-0.7-py2.py3-none-any.whl
    ├───wiz_bang-0.8-py2.py3-none-any.whl
    ├───base.txt
    ├───local.txt
    └───production.txt

Maintenant requirements/base.txtmis:

--find-links=requirements
foo_bar
wiz_bang>=0.8

Une façon soignée de mettre à jour les packages propriétaires, il suffit d'en déposer un nouveau dans le dossier

De cette façon, vous pouvez installer des packages à partir de local folderAND pypiavec le même appel unique:pip install -r requirements/production.txt

PS. Voir ma fourchette cookiecutter-djangopackage pour voir comment diviser les exigences et utiliser l'organisation des exigences basée sur les dossiers.


Merci, c'est encore mieux que ce que je pensais faire!
FoundNil

11

Depuis la page installation de packages, vous pouvez simplement exécuter:

installation de pip / srv / pkg / mypackage

/ srv / pkg / mypackage est le répertoire contenant setup.py .


De plus 1 , vous pouvez l'installer à partir du fichier d'archive:

pip install ./mypackage-1.0.4.tar.gz

1 Bien que mentionné dans la question, en raison de sa popularité, il est également inclus.


2
Ce devrait être la réponse par défaut. Pas besoin de faire pip pip autour avec --find-links si vous savez exactement où se trouve votre paquet sur la machine locale.
Robert

6

En supposant que vous ayez virtualenv et un requirements.txtfichier, vous pouvez définir à l'intérieur de ce fichier où obtenir les packages:

# Published pypi packages 
PyJWT==1.6.4
email_validator==1.0.3
# Remote GIT repo package, this will install as django-bootstrap-themes
git+https://github.com/marquicus/django-bootstrap-themes#egg=django-bootstrap-themes
# Local GIT repo package, this will install as django-knowledge
git+file:///soft/SANDBOX/python/django/forks/django-knowledge#egg=django-knowledge

5

Avoir des exigences dans requirements.txtet en egg_dirtant que répertoire

vous pouvez créer votre cache local:

$ pip download -r requirements.txt -d eggs_dir

alors, utiliser ce "cache" est simple comme:

$ pip install -r requirements.txt --find-links=eggs_dir


1

Pour installer uniquement depuis local, vous avez besoin de 2 options:

  • --find-links: où chercher les dépendances. Il n'est pas nécessaire pour le file://préfixe mentionné par d'autres.
  • --no-index: ne cherchez pas dans les index pypi les dépendances manquantes (dépendances non installées et pas dans le --find-linkschemin).

Vous pouvez donc exécuter à partir de n'importe quel dossier les éléments suivants:

pip install --no-index --find-links /srv/pkg /path/to/mypackage-0.1.0.tar.gz

Si votre mypackage est correctement configuré, il répertoriera toutes ses dépendances, et si vous avez utilisé pip download pour télécharger la cascade de dépendances (c'est-à-dire les dépendances des dépendances, etc.), tout fonctionnera.

Si vous souhaitez utiliser l'index pypi s'il est accessible, mais que vous pouvez utiliser les roues locales sinon, vous pouvez supprimer --no-indexet ajouter --retries 0. Vous verrez pip s'arrêter un peu pendant qu'il essaie de vérifier pypi pour une dépendance manquante (une non installée) et quand il trouve qu'il ne peut pas l'atteindre, retombera en local. Il ne semble pas y avoir de moyen de dire à pip de "chercher d'abord les locaux, puis l'index".


-1

J'ai essayé de réaliser quelque chose de vraiment simple et j'ai échoué lamentablement, je suis probablement stupide.

Quoi qu'il en soit, si vous avez un script / Dockerfilequi télécharge un fichier zip de package python (par exemple à partir de GitHub) et que vous souhaitez ensuite l'installer, vous pouvez utiliser le file:///préfixe pour l'installer comme indiqué dans l' exemple suivant :

$ wget https://example.com/mypackage.zip
$ echo "${MYPACKAGE_MD5}  mypackage.zip" | md5sum --check -
$ pip install file:///.mypackage.zip

REMARQUE : je sais que vous pouvez installer le package immédiatement en utilisant pip install https://example.com/mypackage.zipmais dans mon cas, je voulais vérifier la somme de contrôle (jamais assez paranoïaque) et j'ai échoué lamentablement en essayant d'utiliser les différentes options fournies par pip / le #md5fragment.

Il a été étonnamment frustrant de faire quelque chose d'aussi simple directement avec pip. Je voulais juste passer une somme de contrôle et avoir pipvérifié que le zip correspondait avant de l' installer.

Je faisais probablement quelque chose de très stupide mais à la fin j'ai abandonné et j'ai opté pour ça. J'espère que cela aide les autres à essayer de faire quelque chose de similaire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.