web-dev-qa-db-fra.com

Comment "installer" un paquet contenant des dépendances Git?

J'ai une bibliothèque privée appelée some-library (les noms réels ont été changés) avec un fichier d'installation ressemblant un peu à ceci:

setup(
    name='some-library',

    // Omitted some less important stuff here...

    install_requires=[
        'some-git-dependency',
        'another-git-dependency',
    ],
    dependency_links=[
        'git+ssh://[email protected]/my-organization/some-git-dependency.git#Egg=some-git-dependency',
        'git+ssh://[email protected]/my-organization/another-git-dependency.git#Egg=another-git-dependency',
    ],
)

Toutes ces dépendances Git peuvent être privées, de sorte que l'installation via HTTP n'est pas une option. Je peux utiliser python setup.py install et python setup.py develop dans le répertoire racine de some-library sans problèmes.

Cependant, installer sur Git ne fonctionne pas:

pip install -vvv -e 'git+ssh://[email protected]/my-organization/[email protected]#Egg=some-library'

La commande échoue lorsqu'elle recherche some-git-dependency, suppose à tort qu'elle doit obtenir la dépendance de PyPI, puis échoue après avoir conclu qu'elle ne dépend pas de PyPI. Ma première hypothèse était d'essayer de réexécuter la commande avec --process-dependency-links, mais c'est ce qui s'est passé:

   Cannot look at git URL git+ssh://[email protected]/my-organization/some-git-dependency.git#Egg=some-git-dependency
   Could not find a version that satisfies the requirement some-git-dependency (from some-library) (from versions: )

Pourquoi produit-il cette vague erreur? Quelle est la bonne façon de pip install un paquet avec des dépendances Git qui pourraient être privées?

19
Pieter

Comment installer correctement un paquet avec des dépendances Git qui pourraient être privées?

Deux options

  1. Utilisez dependency_links comme vous le faites. Voir ci-dessous pour plus de détails.

  2. En plus du dependency_links dans votre setup.py, utilisez un dependency-links.txt spécial qui collecte tous les packages requis. Ajoutez ensuite ce paquet dans exigences.txt. C'est mon option de recommandation, comme expliqué ci-dessous.

    # dependency-links.txt
    git+ssh://...@tag#Egg=package-name1
    git+ssh://...@tag#Egg=package-name2
    # requirements.txt (per deployed application)
    -r dependency-links.txt
    

Bien que l’option 2 alourdisse la gestion des paquets, notamment en maintenant à jour le fichier dependency-links.txt, elle facilite grandement l’installation des paquets car vous pouvez oublier d’ajouter l’option --process-dependency-link à pip install

Peut-être plus important encore, en utilisant dependency-links.txt, vous devez spécifier la version exacte à installer lors du déploiement, ce que vous voulez dans un environnement CI/CD - rien n’est plus risqué que d’installer some version . Du point de vue du mainteneur du paquet, il est courant et considéré comme une bonne pratique de spécifier une version minimale, telle que 

    # setup.py in a package
    ...
       install_requires = [ 'foo>1.0', ... ]

C’est formidable, car cela permet à vos paquets de fonctionner correctement avec d’autres qui possèdent des dépendances similaires, voire éventuellement des versions différentes. Cependant, dans une application déployée, cela peut toujours causer des problèmes en cas de conflit entre les exigences. Par exemple. le paquet A est ok avec foo>1.0, le paquet B veut foo<=1.5 et la version la plus récente est foo==2.0. Avec dependency-links.txt, vous pouvez être spécifique et appliquer une version à tous les packages:

    # dependency-links.txt
    foo==1.5

La commande échoue quand elle cherche une dépendance à git,

Pour que cela fonctionne, vous devez ajouter --process-dependency-links pour que pip reconnaisse la dépendance à github, par exemple.

pip install --process-dependency-links -r private-requirements.txt

Notez que depuis pip 8.1.0 vous pouvez ajouter cette option à Requirements.txt. En revanche, il est appliqué à all packages installés et peut avoir des conséquences inattendues. Cela dit, je trouve que dependency-links.txt est une solution plus sûre et plus facile à gérer.

Toutes ces dépendances Git peuvent être privées

Il y a trois options:

  1. Ajoutez des collaborateurs sur chacun des référentiels des packages requis. Ces collaborateurs doivent avoir leurs clés ssh configurées avec github pour que cela fonctionne. Ensuite, utilisez git+ssh://... 

  2. Ajoutez une clé de déploiement à chacun des référentiels. L'inconvénient est que vous devez distribuer la clé privée correspondante à toutes les machines à déployer. Encore une fois, utilisez git+ssh://...

  3. Ajoutez un jeton d'accès personnel au compte github contenant les référentiels privés. Ensuite, vous pouvez utiliser git+https://[email protected]/.... L’inconvénient est que le jeton d’accès aura un accès en lecture + écriture sur tous les référentiels, publics et privés, sur le compte github correspondant. Du côté positif, la distribution et la gestion de clés privées par référentiel n’est plus nécessaire, et le cycle de la clé est beaucoup plus simple. Dans un environnement entièrement intégré où chaque développeur a accès à tous les référentiels, j'ai trouvé que c'était le moyen le plus efficace et le plus simple pour tout le monde. YMMV

6
miraculixx

Cela devrait également fonctionner pour les référentiels privés:

dependency_links = [
     'git+ssh://[email protected]/my-organization/some-git-dependency.git@master#Egg=some-git-dependency',
     'git+ssh://[email protected]/my-organization/another-git-dependency.git@master#Egg=another-git-dependency'
],
3
RaviTezu

Si je fais référence à " pip install dependency links ", vous ne ferez pas référence au référentiel GitHub lui-même, mais à l'image tarball associée à ce référentiel GitHub:

dependency_links=[
        'git+ssh://[email protected]/my-organization/some-git-dependency/tarball/master/#Egg=some-git-dependency',
        'git+ssh://[email protected]/my-organization/another-git-dependency/tarball/master/#Egg=another-git-dependency',
    ],

avec "some-git-dependency" étant le nom * et la version de la dépendance.

1
VonC

Vous devriez utiliser git + git quand url avec #Egg, comme ceci:

-e [email protected]:foo/my-repo.git#Egg=my-repo

Utilisez git + ssh dans la production sans #Egg, mais vous pouvez spécifier @version ou branch @master

git+ssh://[email protected]/foo/[email protected]

pour travailler avec les versions d'applications, utilisez git tagging Principes de base de Git - Marquage

1
Anton

"Ne peut pas regarder l'URL de git git + ssh: //[email protected]/my-organization/some-git-dependency.git#Egg=some-git-dependency" signifie que pip ne peut pas aller chercher un html page à partir de cette URL pour rechercher des liens de téléchargement direct dans la page, c’est-à-dire que pip ne reconnaît pas l’URL en tant que commande vcs, car il peut y avoir une différence entre le spécificateur d’exigence et la partie fragmentée dans l’URL de vcs.

Dans le cas d'une extraction VCS, vous devez également ajouter #Egg=project-version afin d'identifier le paquet pour lequel cette extraction doit être utilisée. 

Veillez à éviter les tirets dans le nom ou la version en les remplaçant par des traits de soulignement. 

Check Dépendances non présentes dans PyPI

remplacez - par un _ dans le package et la chaîne de version

git+ssh://[email protected]/my-organization/some-git-dependency.git#Egg=some_git_dependency  

et --allow-all-external peut être utile.

0
Nizam Mohamed