Comment puis-je faire en sorte que setuptools installe un package qui n'est pas sur PyPI?

142

Je viens de commencer à travailler avec setuptools et virtualenv. Mon paquet nécessite le dernier python-gearman qui n'est disponible que sur GitHub. La version python-gearman qui est sur PyPI est une ancienne. La source Github est compatible avec setuptools, c'est-à-dire a setup.py, etc. Existe-t-il un moyen de faire télécharger et installer la nouvelle version par setuptools au lieu de la rechercher sur PyPI et d'installer l'ancienne?

Pour info, le nouveau python-gearman est http://github.com/mtai/python-gearman

Andrei
la source
1
Y a-t-il une raison pour laquelle vous essayez d'installer un package python directement à partir de Git au lieu de télécharger la source à partir de là et de l'utiliser python setup.py installdans le répertoire source?
Andrew
4
Je souhaite que mon package soit déployé sur plusieurs machines et que toutes ses dépendances soient installées automatiquement.
andrei
2
Vous pouvez l'utiliser easy_installou l' pipinstaller directement depuis Github. Mais il y a aussi une autre solution, avez-vous envisagé d'ajouter le package à PyPI?
Wolph
2
Puisqu'il s'agit simplement d'un déploiement, pourquoi ne pas l'utiliser buildout? Il a quelques plugins Git prêts à l'emploi.
Wolph

Réponses:

156

La clé est d'indiquer à easy_install où le package peut être téléchargé. Dans ce cas particulier, il peut être trouvé à l'url http://github.com/mtai/python-gearman/tarball/master . Cependant, ce lien ne fonctionnera pas en lui-même, car easy_install ne peut pas dire simplement en regardant l'URL ce qu'il va obtenir.

En le remplaçant par http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta , easy_install pourra identifier le nom du paquet et sa version.

La dernière étape consiste à ajouter l'URL aux liens de dépendance de votre package, par exemple:

setup(
   ...
   dependency_links = ['http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta']
)

Maintenant, lorsque VOTRE paquet est en cours d'installation, easy_install découvrira qu'il existe un "gearman 2.0.0beta" disponible au téléchargement à partir de cette URL, et le choisira volontiers par-dessus celui sur PyPI, si vous spécifiez "gearman> = 2.0.0beta" dans vos dépendances ..

(Normalement, la façon dont ce genre de chose est fait est d'inclure un lien sur sa page PyPI vers la source téléchargeable; dans ce cas, si l'auteur du paquet gearman avait inclus un lien comme celui ci-dessus, vous seriez déjà défini . En règle générale, les gens marquent la version de développement avec «myproject-dev», puis les gens utilisent une exigence de «myproject> = somever, == dev», de sorte que s'il n'y a pas de paquet de somever ou plus, easy_install essaiera de consultez ou téléchargez la version.)

Vous devrez spécifier --process-dependency-linkslors de l'utilisation pip. Notez que le traitement des liens de dépendance est obsolète et sera supprimé dans une prochaine version.

PJ Eby
la source
1
J'ai fait ce que vous avez suggéré, mais quand je lance "python setup.py develop", il dit "écrire dependency_links vers foo.egg-info / dependency_links.txt", mais ne télécharge et n'installe pas réellement le paquet. J'utilise un virtualenv basé sur setuptools si cela aide.
andrei
15
Vous devez également avoir install_requires = 'gearman> = 2.0.0beta'; avez-vous inclus cela?
PJ Eby
3
Cela ne fonctionne pas pour moi, avec le betasuffixe sur une version existante sur PyPI, il installera toujours le package de PyPI au lieu de celui défini dans dependency_links. Si vous essayez de définir une version supérieure à ce qui existe sur PyPI avec #egg=package-version, l'outil de configuration se plaindra d'une Could not find a version that satisfies the requirementerreur et d'une liste de toutes les versions disponibles sur PyPI. Notez que j'essaie de créer mon package avec sdist, puis de l'installer avec pip install http://url/to/my/generated/tar.
zazabe
1
ok, en installant mon package avec easy_install http://url/to/my/generated/tar, tout fonctionne comme prévu ... Une idée pourquoi?
zazabe
3
--process-dependency-linksa été supprimé à partir du pip19! Voir: github.com/pypa/pip/issues/6162
phoenix
67

Vous pouvez utiliser le pip install protocol+location[@tag][#egg=Dependency]format pour installer directement à partir de la source à l'aide de pip.

Git

pip install git+https://github.com/username/repo.git
pip install git+https://github.com/username/repo.git@MyTag
pip install git+https://github.com/username/repo.git@MyTag#egg=ProjectName

Mercuriel

pip install hg+https://hg.myproject.org/MyProject/

SVN

pip install svn+svn://svn.myproject.org/svn/MyProject

Bzr

pip install bzr+http://bzr.myproject.org/MyProject/trunk

Les protocoles suivants sont pris en charge: [+git, +svn, +hg, +bzr]

Versions

@tag vous permet de spécifier une version / balise spécifique à extraire.

#egg=name vous permet de spécifier ce qu'est le projet en tant que dépendance pour les autres.

L'ordre doit toujours être @tag#egg=name.

Dépôts privés

Vous pouvez également installer à partir de référentiels privés en changeant le protocole en SSH ( ssh://) et en ajoutant un utilisateur approprié ( git@):

git+ssh://git@github.com/username/my_private_repo

Vous pouvez également installer à partir de référentiels privés avec un nom d'utilisateur / mot de passe.

git+https://<username>:<password>@github.com/<user>/<repo>.git

Github offre la possibilité de créer des jetons OAuth personnels qui peuvent être cyclés

git+https://<oauth token>:x-oauth-basic@github.com/<user>/<repo>.git

requirements.txt

requirements.txt est utilisé pour spécifier les dépendances du projet:

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

Ceux-ci ne sont pas installés automatiquement avec le package et doivent être installés avec la commande pip -r requirements.txt.

Y compris les fichiers d'exigences

Les fichiers d'exigences peuvent inclure d'autres fichiers d'exigences:

requirements-docs.txt

sphinx
-r requirements-dev.txt

requirements-dev.txt

some-dev-tool
-r requirements.txt

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

setup.py

Les fichiers d'exigences peuvent installer les dépendances spécifiées dans setup.pyavec la commande suivante:

-e .

setup.pypeut également installer à partir de référentiels en utilisant la même syntaxe que ci-dessus, mais en utilisant la dependency_linksvaleur mentionnée dans cette réponse .

Références:

https://pip.pypa.io/en/latest/user_guide.html#installing-packages https://pip.pypa.io/en/latest/reference/pip_install.html

Rebs
la source
2
setup.py peut installer à partir de référentiels. Il suffit de rechercher 'setup.py dependency_links'
TomDotTom
1
@TomDotTom Derp, j'ai même voté pour cette réponse mais je ne l'ai pas assimilée = P Je vais mettre à jour ma réponse. Merci d'avoir fait remarquer cela! Cela m'aidera dans certaines choses que je fais.
Rebs
Je pense que dependency_links est déprécié (?) github.com/pypa/pip/issues/3939 . J'adore cette réponse et je pense que c'est mieux parce que je peux (dans setup.py):extras_require={'all': [repo @ git+https://github.com/username/repo.git]}
Josiah L.
21

Comme je l' ai juste eu à faire la même chose, je l' ai trouvé une autre façon de le faire comme pip« s --process-dependency-linksdevraient être enlevés à pip19,0 selon ce commentaire .

pip 18.1 comprend la fonctionnalité suivante

Autoriser les exigences d'URL PEP 508 à être utilisées comme dépendances.

D'après la description de PEP 508, la syntaxe de ces dépendances d'URL ressemble à:

Une recherche minimale basée sur une URL:

pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686

Donc dans votre setup.pyil ressemblerait à

setup(
   ...
   install_requires = [
   ...
   'python-gearman @ https://github.com/mtai/python-gearman/archive/master.zip'
   ...
   ]
)

Remarquez que le lien est un fichier d'archive et peut également être une version ou une branche spécifique d'un référentiel, comme décrit dans cette réponse . Consultez également cette réponse pour travailler avec d'autres hôtes de référentiel.

À ma connaissance, le moyen le plus simple de mettre à jour la dépendance consiste à utiliser pip install -I .lors de l'installation de votre package à partir de son répertoire.

Phil
la source
Est-ce que cela prend également en charge tout ce qui pip installprend en charge, tels que les URL git, #subdirectory=...etc.? Ou ont-ils proposé une toute nouvelle syntaxe avec différentes fonctionnalités exposées d'une manière différente et incompatible?
remram
Si vous n'utilisez pas setuptools et gérez les dépendances manuellement sur la ligne de commande, il semble que vous deviez toujours utiliser l'approche décrite par la réponse de @Rebs .
Phil
1
Juste pour confirmer que cela fonctionne avec distutils.core.setupetpip 19.1.1
devrait voir
La résultante requirements.txt, cependant, n'est pas compatible avecpip install -r requirments.txt
devrait voir
@voyez requirments.txt-vous de quoi parlez -vous?
Phil
6

Vanilla setuptoolsne prend pas en charge le téléchargement directement à partir d'un référentiel git, mais vous pouvez utiliser l'un des liens Download Source de cette page, comme:

easy_install http://github.com/mtai/python-gearman/tarball/master
Ned Deily
la source
Donc, afin de m'assurer que cette version de python-gearman est installée sur n'importe quel serveur où mon paquet va être, je vais devoir exécuter easy_install manuellement avant d'installer mon paquet?
andrei
Si vous utilisez easy_install, oui. Mais, comme d' autres l' ont souligné, vous pouvez passer à pipou buildoutqui ont la gestion des exigences plus sophistiquées. Voir, par exemple: pip.openplans.org/#requirements-files
Ned Deily
En fait, vous n'avez pas besoin d'exécuter manuellement easy_install; vous pouvez simplement ajouter le lien supplémentaire à votre setup.py. J'écrirai une réponse expliquant les détails.
PJ Eby
2
Comme mentionné dans mon commentaire ci-dessus setup.py fournit dependency_links qui vous permet de télécharger à partir d'un référentiel gti
TomDotTom