59 votes

Comment distribuer facilement un logiciel Python qui a des dépendances de modules Python ? Frustrations dans l'installation des paquets Python sous Unix

Mon objectif est de distribuer un paquet Python qui a plusieurs autres paquets Python largement utilisés comme dépendances. Mon paquet dépend de paquets bien écrits et indexés par Python comme pandas, scipy et numpy, et spécifie dans le setup.py que certaines versions ou plus de ceux-ci sont nécessaires, par exemple "numpy >= 1.5".

J'ai découvert que c'est immensément frustrant et presque impossible pour les utilisateurs qui connaissent Unix et qui sont no experts en packaging Python (même s'ils savent écrire Python) pour installer un paquet comme le mien, même en utilisant ce qui est censé être des gestionnaires de paquets faciles à utiliser. Je me demande s'il existe une alternative à ce processus douloureux que quelqu'un peut proposer, ou si mon expérience reflète simplement l'état actuel très difficile du packaging et de la distribution de Python.

Supposons que les utilisateurs téléchargent votre paquet sur leur système. La plupart essaieront de l'installer "naïvement", en utilisant quelque chose comme :

$ python setup.py install

Si vous recherchez des instructions sur l'installation de paquets Python sur Google, c'est généralement ce qui est proposé. Cette méthode échouera pour la grande majorité des utilisateurs, car la plupart d'entre eux n'ont pas d'accès Root sur leurs serveurs Unix/Linux. En cherchant davantage, ils découvriront l'option "--prefix" et essaieront :

$ python setup.py install --prefix=/some/local/dir

Comme les utilisateurs ne sont pas au courant des subtilités du packaging Python, ils choisiront un répertoire arbitraire comme argument de la commande --prefix par exemple "~/software/mypackage/" . Il ne s'agira pas d'un répertoire propre où se trouvent tous les autres paquets Python, car là encore, la plupart des utilisateurs ne sont pas au courant de ces détails. S'ils installent un autre paquet "monautrepaquet", ils pourraient lui transmettre "~/software/myotherpackage" et vous pouvez imaginer comment, plus tard, cela conduira à un piratage frustrant de l'Internet. PYTHONPATH et d'autres complications.

En continuant avec le processus d'installation, l'appel à "setup.py install" avec "--prefix" échouera également lorsque les utilisateurs tenteront d'utiliser le paquet, même s'il semble avoir été installé correctement, car l'une des dépendances peut être manquante (par exemple pandas, scipy ou numpy) et un gestionnaire de paquets n'est pas utilisé. Ils essaieront d'installer ces paquets individuellement. Même s'ils réussissent, les paquets ne seront inévitablement pas dans le fichier PYTHONPATH en raison des répertoires non standard donnés à "--prefix" et les utilisateurs patients s'adonneront à des modifications de leur PYTHONPATH pour que les dépendances soient visibles.

À ce stade, les utilisateurs peuvent se faire dire par un ami connaissant Python qu'ils doivent utiliser un gestionnaire de paquets comme "easy_install" le gestionnaire du courant principal, pour installer le logiciel et s'occuper des dépendances. Après avoir installé "easy_install" ce qui pourrait être difficile, ils essaieront :

$ easy_install setup.py 

Cette opération échouera également, car les utilisateurs n'ont généralement pas l'autorisation d'installer des logiciels de manière globale sur les serveurs Unix de production. En lisant davantage, ils apprendront l'existence du "--user" et essayez :

$ easy_install setup.py --user 

Ils obtiendront l'erreur :

usage: easy_install [options] requirement_or_url ...
   or: easy_install --help

error: option --user not recognized

Ils seront extrêmement perplexes quant à la raison pour laquelle leur easy_install n'a pas le --user lorsqu'il existe des pages en ligne décrivant clairement cette option. Ils pourraient essayer de mettre à niveau leur easy_install à la dernière version et constate qu'il échoue toujours.

S'ils continuent et consultent un expert en emballage Python, ils découvriront qu'il y a deux versions de easy_install tous deux nommés " easy_install" afin de maximiser la confusion, mais une partie de "distribute" et l'autre partie de "setuptools". Il se trouve que seule la partie "easy_install" de "distribute" soutient "--user" et la grande majorité des serveurs/administrateurs système installent "setuptools" 's easy_install et donc l'installation locale ne sera pas possible. Gardez à l'esprit que ces distinctions entre "distribute" y "setuptools" n'ont aucun sens et sont difficiles à comprendre pour les personnes qui ne sont pas expertes en gestion des paquets Python.

À ce stade, j'aurais perdu 90 % des utilisateurs les plus déterminés, les plus avisés et les plus patients qui essaient d'installer mon progiciel - et à juste titre ! Ils voulaient installer un logiciel écrit en Python, pas devenir des experts de la distribution de paquets Python, et ceci est bien trop confus et complexe. Ils abandonneront et seront frustrés par la perte de temps.

L'infime minorité d'utilisateurs qui continue et demande à d'autres experts Python se verra répondre qu'ils doivent utiliser pip/virtualenv au lieu de easy_install . Installation de pip y virtualenv et comprendre comment ces outils fonctionnent et en quoi ils sont différents des outils conventionnels. "python setup.py" o "easy_install" Les appels sont en soi longs et difficiles, et c'est encore trop demander aux utilisateurs qui veulent simplement installer un simple logiciel Python et l'utiliser. Même ceux qui suivent cette voie seront confus quant à savoir si les dépendances qu'ils ont installées avec easy_install o setup.py install --prefix sont toujours utilisables avec pip/virtualenv ou si tout doit être réinstallé depuis le début.

Ce problème est exacerbé si un ou plusieurs des paquets en question dépendent de l'installation d'une version de Python différente de celle qui est utilisée par défaut. La difficulté de s'assurer que votre gestionnaire de paquets Python utilise la version de Python que vous souhaitez, et que les dépendances requises sont installées dans le répertoire Python 2.x approprié et non Python 2.y, sera si frustrante pour les utilisateurs qu'ils abandonneront certainement à ce stade.

Existe-t-il un moyen plus simple d'installer un logiciel Python sans que les utilisateurs aient à se plonger dans tous ces détails techniques concernant les paquets Python, les chemins et les emplacements ? Par exemple, je ne suis pas un grand utilisateur de Java, mais j'utilise certains outils Java à l'occasion, et je ne me souviens pas avoir jamais eu à me préoccuper des dépendances X et Y du logiciel Java que j'installais, et je n'ai aucune idée de la façon dont fonctionne la gestion des paquets Java (et je suis heureux de ne pas en avoir - je voulais simplement utiliser un outil qui se trouvait être écrit en Java). Si je me souviens bien, si vous téléchargez un Jar, vous l'obtenez simplement et il a tendance à fonctionner.

Existe-t-il un équivalent pour Python ? Un moyen de distribuer des logiciels sans que les utilisateurs aient à rechercher toutes ces dépendances et versions ? Un moyen de compiler tous les paquets pertinents en quelque chose d'autonome qui peut simplement être téléchargé et utilisé comme un binaire ?

Je tiens à souligner que cette frustration se produit même avec l'objectif restreint de distribuer un paquet aux utilisateurs avertis d'Unix, ce qui simplifie le problème en ne se préoccupant pas des problèmes de plates-formes croisées, etc. Je suppose que les utilisateurs sont des utilisateurs Unix avertis, qu'ils connaissent peut-être même Python, mais qu'ils ne sont tout simplement pas au courant (et ne veulent pas être sensibilisés) des tenants et aboutissants du packaging Python et de la myriade de complications internes/rivalités des différents gestionnaires de paquets. Une caractéristique inquiétante de ce problème est qu'il se produit même lorsque toutes les dépendances de votre paquetage Python sont des paquets bien connus, bien écrits et bien maintenus, disponibles sur Python, comme Pandas, Scipy et Numpy. Ce n'est pas comme si je m'appuyais sur des dépendances obscures qui ne sont pas des paquets correctement formés : j'utilisais plutôt les paquets les plus courants sur lesquels beaucoup de gens peuvent compter.

Toute aide ou tout conseil à ce sujet sera grandement apprécié. Je pense que Python est un excellent langage avec d'excellentes bibliothèques, mais je trouve qu'il est pratiquement impossible de distribuer le logiciel que j'écris dedans (une fois qu'il a des dépendances) d'une manière qui soit facile pour les gens à installer localement et à exécuter. Je tiens à préciser que le logiciel que j'écris n'est pas une bibliothèque Python pour une utilisation programmatique, mais un logiciel qui a des scripts exécutables que les utilisateurs exécutent comme des programmes individuels. Merci.

1 votes

À mon avis, la meilleure solution consiste à le distribuer de la manière habituelle, c'est-à-dire.., pip comme easy_install est déprécié (ce qui signifie qu'il faut certaines connaissances, comme vous le dites, pour l'installer), alors laissez les mainteneurs de chaque distro s'occuper de rendre l'installation facile pour cette distro - ce que cela signifiera variera, bien qu'en général cela signifiera une installation en un clic via le gestionnaire de paquets, qui s'occupera des dépôts.

3 votes

Qu'entendez-vous par "mainteneurs de distro" ? Je ne comprends pas ce commentaire. Je ne sais pas non plus ce que je dois dire à mes utilisateurs dans la section Installation du manuel. Doivent-ils tous revoir toute leur installation et utiliser virtualenv/pip avant même de commencer ? Installer distribuer easy_install ? Je ne sais même pas quoi leur dire.

1 votes

Pratiquement toutes les distributions Linux (et OS X sous la forme de homebrew et autres) ont un gestionnaire de paquets. Il s'agit de logiciels qui gèrent l'installation et la maintenance des logiciels installés. Les gestionnaires de paquets maintiennent les paquets qui indiquent au système comment installer les logiciels et les maintenir à jour. En général, les logiciels pour les systèmes d'exploitation Linux sont publiés sous forme de sources, puis un gestionnaire de paquets crée un paquet qui s'occupe de l'installation pour l'utilisateur final, en s'adaptant au style et à la configuration de la distribution. Mainteneurs de paquets sera être capable de gérer les méthodes de distribution de Python.

14voto

André Anjos Points 699

Nous développons également des projets logiciels qui dépendent de numpy, scipy et d'autres paquets PyPI. Le meilleur outil actuellement disponible pour gérer les installations à distance est sans conteste zc.buildout . Il est très facile à utiliser. Vous téléchargez un script d'amorçage depuis leur site web et le distribuez avec votre paquet. Vous écrivez un fichier de "déploiement local", appelé normalement buildout.cfg qui explique comment installer le paquet localement. Vous envoyez à la fois le bootstrap.py et buildout.cfg avec votre paquet - nous utilisons le MANIFEST.in dans nos paquets python pour forcer l'incorporation de ces deux fichiers avec les boules zip ou tar distribuées par PyPI. Lorsque l'utilisateur le décompresse, il doit exécuter deux commandes :

$ python bootstrap.py # this will download zc.buildout and setuptools
$ ./bin/buildout # this will build and **locally** install your package + deps

Le paquet est compilé et toutes les dépendances sont installées. localement ce qui signifie que l'utilisateur qui installe votre paquet n'a même pas besoin des privilèges Root, ce qui est une fonctionnalité supplémentaire. Les scripts sont (normalement) placés dans le dossier ./bin L'utilisateur peut donc les exécuter après cela. zc.buildout utilise setuptools pour l'interaction avec PyPI afin que tout ce que vous attendez fonctionne dès le départ.

Vous pouvez étendre zc.buildout Si toute cette puissance ne suffit pas, vous pouvez facilement créer des "recettes" qui peuvent aider l'utilisateur à créer des fichiers de configuration supplémentaires, à télécharger d'autres éléments du réseau ou à instancier des programmes personnalisés. zc.buildout contient un tutoriel vidéo qui explique en détail comment utiliser buildout et comment l'étendre. Notre projet Bob fait un usage intensif de buildout pour distribuer des paquets à usage scientifique. Si vous le souhaitez, vous pouvez visitez la page suivante qui contient des instructions détaillées pour nos développeurs sur la façon dont ils peuvent configurer leurs paquets python afin que d'autres personnes puissent les construire et les installer localement en utilisant zc.buildout .

0 votes

Excellente réponse, je vais certainement regarder dans buildout aussi bien. Bien que notre outil Python ne dépende pas encore d'autres paquets Python (exactement pour éviter les problèmes d'installation), il le fera dans un avenir proche, et nous aurons donc besoin d'une solution décente pour permettre aux utilisateurs d'installer facilement notre outil. zc.buildout semble être une bonne solution, mais elle nécessite toujours que l'utilisateur 1) télécharge le paquet, 2) le décompresse, 3) exécute 'python bootstrap.py' et 4) exécute buildout. Pourriez-vous d'une manière ou d'une autre le faire fonctionner avec une commande qui fait tout, par exemple, écrire un setup.py script pour que 'easy_install foo' fonctionne avec buildout) ?

0 votes

Je ne pense pas que ce soit facilement possible ni que vous aimeriez que ce soit quelque chose que vous ayez à maintenir. Buildout dépend de setuptools et no le contraire. D'après mon expérience, le mieux est toujours de s'appuyer sur PyPI pour la distribution des paquets : il est là, ne coûte rien et il est mis en miroir. Nous mettons un lien vers la page du paquet PyPI sur vos publications. L'utilisateur le consulte et voit un beau manuel et un bouton de téléchargement vert. Vous pouvez écrire un script qui fait tout cela en une seule fois, mais vous devrez alors le distribuer et le maintenir séparément.

0 votes

Dans notre cas, nous disposons déjà d'un méta-paquet qui combine les trois paquets qui constituent notre logiciel, cf. pypi.python.org/pypi/easybuild . Le tout-en-un script pourrait faire partie du paquet meta (qui n'a maintenant qu'un setup.py à la base).

6voto

ncoghlan Points 10779

Nous travaillons actuellement à faciliter l'installation des logiciels Python par les utilisateurs, indépendamment de la plateforme (voir notamment https://python-packaging-user-guide.readthedocs.org/en/latest/future.html y http://www.python.org/dev/peps/pep-0453/ )

Pour l'instant, le problème des deux versions concurrentes d'easy_install a été résolu, avec le fork concurrent "distribute" qui a été fusionné dans la ligne de développement principale de setuptools.

Les meilleurs conseils actuellement disponibles sur la distribution et l'installation multiplateforme des logiciels Python sont donnés ici : https://packaging.python.org/

0 votes

Merci pour cet effort. Considérant que l'un des principes Python est "Il devrait y avoir un - et de préférence un seul - moyen évident de le faire." J'ai été étonné (dans le mauvais sens du terme) par toutes les options différentes, mais similaires et interconnectées, permettant d'empaqueter mon code pour faciliter son installation par l'utilisateur.

0 votes

Le "Python Packaging User Guide" (PyPUG) a pour objectif d'être la ressource faisant autorité sur la façon d'empaqueter, de publier et d'installer des distributions Python à l'aide des outils actuels. - packaging.python.org

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X