Comment utiliser GitHub comme serveur PyPi

Je cherchais un serveur de package PyPi Python privé hébergé, qui utilisait les informations d'identification que l'équipe possède déjà (telles que GitHub).

Je ne voulais pas créer de serveur sur site. Pour nous, il serait impossible d'utiliser des serveurs de build basés sur le cloud, et c'est une autre partie mobile qui peut mal tourner. Il existe également des problèmes potentiels de sécurité et de vitesse à granularité fine. (Nous avons une équipe mondiale, il serait donc utile de diffuser le contenu via un CDN.)

Je ne voulais pas forcer l'équipe à créer des comptes avec un autre fournisseur. Ils ont déjà des comptes Active Directory et GitHub. C'est un ennui pour eux et cela crée un fardeau de gouvernance pour moi.

Malheureusement, je n'ai pas pu trouver un tel service. GemFury est excellent mais ne prend pas en charge l'autorisation GitHub (au niveau de l'équipe / organisation) et Packagr ne prend pas du tout en charge l'autorisation GitHub. MyGet est également excellent, il me permet d'utiliser l'autorisation GitHub, mais n'héberge pas de packages Python. Azure DevOps a quelque chose qui semble prometteur, mais il est actuellement en version bêta privée.

Heureusement, cela est possible en utilisant des référentiels cloud Git tels que GitHub, GitLab et BitBucket.

Pip peut installer des packages depuis Git

J'ai hébergé un package Python sur GitHub (python_world), que vous pouvez installer avec la commande suivante (assurez-vous de me faire confiance avant d'exécuter cette commande et d'installer mon code sur votre ordinateur).

pip install git+//github.com/ceddlyburge/python_world#egg=python_world

Pip fournit des options pour installer à partir de la tête, d'une branche, d'une balise ou d'un commit. Je marque généralement chaque version et j'installe à partir de ces balises. Consultez la documentation d'installation de pip pour plus de détails.

Ce référentiel est public, mais il fonctionne de la même manière avec un référentiel privé, tant que vous en avez l'autorisation. Il n'y a pas de magie spéciale (c'est un package Python vanilla) et Setup.py fait la plupart du travail normalement.

Si vous débutez dans la création de packages Python, le didacticiel Empaquetage de projets Python mérite une lecture rapide.

Setuptools peut également installer des dépendances depuis Git

Setuptools est la manière dont la plupart des gens créent des packages Python.

J'ai hébergé un autre package sur GitHub python_hello, qui dépend de python_world. (Je suis sûr que vous pouvez voir où cela se passe.)

Les bits pertinents de setup.py sont ci-dessous. install_requiresspécifie qu'il python_worlds'agit d'une dépendance requise et indique à Setuptools où la trouver.

install_requires=[ '[email protected]+//github.com/ceddlyburge/python_world#egg=python_world-0.0.1', ]

Vous pouvez installer ce package à l'aide de la commande ci-dessous. Il téléchargera également le python_worldpackage dépendant .

pip install git+//github.com/ceddlyburge/python_hello#egg=python_hello

Cela renvoie à une version spécifique de python_world, ce qui est dommage car cela signifie que pip ne peut pas faire de gestion des dépendances (comme élaborer une version acceptable si plusieurs choses en dépendent). Cependant, à la fin de cet article, nous aurons supprimé le besoin du lien spécifique.

Environnements Python

Comme le savent tous ceux qui ont utilisé Python sans environnement, les environnements économisent beaucoup de frustration et de temps perdu. Nous devons donc les soutenir.

J'ai créé un référentiel (use-hello-world) qui se définit python_hellocomme une dépendance dans requirements.txt pour Virtualenv et environment.yml pour Conda.

Si vous téléchargez le dépôt, vous pouvez installer les dépendances dans un virtualenv avec la commande suivante.

pip install -r requirements.txt

Si vous utilisez conda, vous pouvez utiliser cette commande:

conda env create -n use-hello-world

Index PyPi

Jusqu'à présent, nous sommes en mesure d'installer des packages à partir de nos référentiels Git privés. Ces packages peuvent, à leur tour, définir des dépendances avec d'autres référentiels privés. Il n'y a toujours pas de serveur PyPi en vue.

Nous pourrions nous arrêter à ce stade. Cependant, la syntaxe pour définir les dépendances est un peu mystérieuse. Il serait difficile pour l'équipe de découvrir quels packages sont disponibles, et nous établissons des liens vers des versions spécifiques de packages dépendants, au lieu de laisser pip le gérer.

Pour résoudre ce problème, nous pouvons configurer un index PyPi conforme à Pep 503. Cette spécification est assez simple, et je viens de créer l'index à la main. Si cela devient trop encombrant, je peux le générer à partir de l'API GitHub.

J'ai créé cet index PyPi à l'aide de pages GitHub. Il existe des choses équivalentes pour GitLab et BitBucket. Vous pouvez voir que le code source est très simple. Les sites Pages GitHub sont toujours publics (et il n'y a probablement pas d'informations sensibles dans votre index). Cependant, si vous avez besoin qu'ils soient privés, vous pouvez utiliser un service tel que PrivateHub.

Une chose à surveiller est la normalisation du nom de la spécification. Cela nécessite que les python_helloinformations du package soient présentes à python-hello/index.html(notez le changement d'un trait de soulignement à un tiret).

Maintenant que nous avons un serveur PyPi, nous pouvons installer des packages en utilisant la commande ci-dessous.

pip install python_hello --extra-index-url //ceddlyburge.github.io/python-package-server/

Pour que vous puissiez voir cela fonctionner avec les environnements, j'ai créé un autre référentiel (use_hello_world_from_server) qui définit la python_hellodépendance en utilisant cet index PyPi au lieu de liens directs GitHub. Si vous essayez avec Conda, la version> 4.4 est requise.

À ce stade, nous pouvons revenir en arrière et supprimer le lien direct Git dans install_requires dans setup.py de python_hello (car Setuptools pourra le trouver sur notre serveur).

Conclusions

L'utilisation d'un fournisseur Git hébergé dans le cloud comme serveur PyPi est une option viable. Si vous en utilisez déjà un, cela signifie que vous pouvez réutiliser les informations d'identification et les autorisations dont vous disposez déjà. Il fonctionnera avec les serveurs Cloud Build et sera probablement fourni via un CDN, il sera donc rapide dans le monde entier. La configuration nécessite plus de connaissances qu'un serveur hébergé, mais probablement la même chose ou moins que l'hébergement de votre propre serveur sur site.

Trucs et astuces

Servir l'index localement peut aider à résoudre les problèmes (tels que la normalisation de nom). Il est facile de voir quelles demandes sont faites. Vous pouvez utiliser le serveur HTTP Python intégré pour cela ( python -m Http.Server -8000). Cela m'a amené à découvrir qui pip searchutilise des postrequêtes, donc ne fonctionnera pas avec les pages GitHub.

Vous pouvez exécuter python setup.py -installpour vérifier vos packages pip localement, avant de les pousser vers Git.