Votre Python aime les pip 32


A partir des versions 2.7.9 et et 3.4, pip est fournit automatiquement avec Python. Si c’est votre cas, vous pouvez sauter la partie installation et aller directement à la partie usage de cet article.

Pip install par-ci, pip install par là. “Pour installer cette lib, il vous suffit de faire pip install”.

Mais merde, c’est quoi pip ?

Python et les libs externes

La beauté avec Python, c’est qu’on peut prendre une lib, la balancer dans le répertoire courant, et l’importer. Rien à faire, ça marche tout seul.

Mais.

Car oui, il y a toujours un mais (souvent après le mois de mars).

Quand il faut mettre à jour ses libs, c’est chiant. Quand il faut recréer un environnement complet en prod, c’est chiant. Quand il faut trouver la dernière version, avec le bon site Web, et le lien de téléchargement, c’est chiant. Quand on veut installer une lib automatiquement, vous l’avez deviné, c’est chiant.

Mais surtout, quand on a une lib qui a des parties en C à compiler comme les libs de crypto, d’accès à la base de données, de traitement XML, de parsing ou de sérialisation, de calculs scientifiques, etc. ça ne marche tout simplement pas.

Là, il y a deux écoles. Les mecs qui utilisent les packages *.exe ou *.deb precompilés et qui se retrouvent avec d’autres problèmes.

Et les mecs qui utilisent setuptools (et qui se retrouvent avec encore d’autres problèmes, mais c’est mieux parce que je le dis).

Setuptools, la solution de skippy à tous vos soucis

setuptools est une lib et un outil de distribution de code Python, et elle permet notament d’installer des libs externes automatiquement en les téléchargeant depuis le grand InterBoule.

Comme gem install sous ruby, npm pour NodeJs, Python possède sa commande d’installation appelée easy_install, qui va piocher dans le site Web pypi.python.org, un équivalent de Cpan de Perl ou des channels pear pour PHP.

Bien entendu, ça serait trop simple sinon, Python ne vient pas par défaut installé avec cet outil pourtant indispensable.

Sous Ubuntu c’est facile:

sudo apt-get install python-setuptools

Et il existe un paquet similaire sur toutes les distribs.

Sous windows, c’est un exe à installer. Choisissez la bonne version selon votre version de Python (python --version). Généralement, la 2.7.

Sous mac, il faut télécharger l’egg correspondant à sa version puis:

sh setuptools-votre_version.egg --prefix=~

Et vous avez alors accès à la commande magique, easy_install. Par exemple, pour installer Django:

easy_install --user django

(ou easy_install django en mode administrateur – ou avec sudo – pour l’installer pour tout le système et pas juste l’utilisateur courant)

Il faut bien entendu être connecté à internet pour que ça marche. Notez par ailleurs que la recherche est insensible à la casse, et que tout underscore sera automatiquement remplacé par un tiret.

Sous Windows, si la commande n’est pas trouvée, il vous faudra rajouter le répertoire qui contient la commande easy_install (le plus souvent C:\Python27\Scripts) à la main dans le PATH.

Vous avez easy_install ? Oubliez-le !

Vous n’utiliserez normalement easy_install que pour une seule chose: installer pip.

easy_install --user pip

pip est un easy_install en plus court à taper, plus puissant, plus souple, plus mieux.

Il s’utilise comme easy_install :

pip install --user bottle

(ou sudo pip install bottle, ou en root, mais je sauterai ce genre de détails pour la suite)

Grâce à pip, vous allez avoir accès à des milliers de libs Python en quelques frappes, et donc pouvoir beaucoup plus facilement expérimenter avec des nouveaux bidules.

Mais pip va plus loin qu’easy_install, et permet carrément de gérer toutes les dépendances de son projet.

Ce que fait pip que easy_install ne fait pas

Déjà, pip télécharge toutes les dépendances avant de lancer l’installation, ce qui évite une installation partielle.

Mais surtout, pip ajoute des opérations qu’on pourrait attendre de base, notamment, la désinstallation :-)

pip uninstall bottle

Évidement, on peut choisir d’installer une version particulière:

pip install bottle==0.9

Et mettre à jour une lib à la dernière version :

pip install bottle --upgrade

Ou downgrader vers une version précédente:

pip install bottle==0.9 --upgrade

Cependant, le plus intéressant avec pip, c’est sa capacité à recréer tout un environnement de développement en une commande:

$ pip freeze
Axiom==0.6.0
BeautifulSoup==3.2.0
Brlapi==0.5.6
BzrTools==2.5.0
CherryPy==3.2.2
Coherence==0.6.6.2
[...]

pip freeze liste toutes les librairies installées et leurs versions. On peut ensuite les réinstaller sur une autre machine facilement:

pip freeze > requirements.txt

Et sur l’autre machine:

pip install -r requirements.txt

On est garanti d’avoir les mêmes libs, avec les mêmes versions. Ca marche de la même manière sous tous les OS, et comme des milliers de libs ne sont pas disponibles en paquets *.deb, *.rpm ou *.exe, c’est extrêmement pratique.

Si vous vous attendez à être privé de connexion internet ou juste pour accélérer le procédé, pip permet de créer un bundle, c’est à dire un gros zip qui contient toutes les dépendances et qui peut être installé indépendamment :

pip bundle nom_du_projet.pybundle -r requirements.txt

Et sur l’autre machine:

pip install nom_du_projet.pybundle

Quelques astuces pour être productif avec pip

Si vous installez beaucoup de fois les mêmes paquets, par exemple dans de nombreux virtualenvs j’installe toujours ipython + ipdb + requests + clize + peewee, les télécharger à chaque fois est une perte de temps. On peut demander à pip de mettre en cache les paquets déjà installés, pour de futures installations:

export PIP_DOWNLOAD_CACHE='~/.pip/cache'; dans le .bashrc

Pour les windowsiens, je ne sais pas du tout où mettre ça…

Sachez cependant que le cache ne dispense pas d’être connecté à Internet.

Si une bibliothèque n’est pas encore sur pypi, pip est capable, pourvu que le code source vienne avec un fichier setup.py, de l’installer depuis un fichier local, une URL, ou même un simple repo git. Donc si vous trouvez une lib chouette sur github, on peut l’installer ainsi:

pip install git+git://github.com/sametmax/0bin.git

Et elle sera même référencée par le pip freeze !

Remarquez qu’il faut avoir Git installé, et que le protocole doit être changé pour git+git.

Parfois, pypi est indisponible: un problème sur le site, un problème de dns, un problème de votre FAI… Dans ce cas là on est un peu désemparé. Heureusement, pip permet aussi de faire un fallback sur des miroirs:

pip install --use-mirrors requests

Dans ce cas pip essayera de trouver le paquet sur une liste de sites miroirs de pypi qu’il possède en interne. Il va les essayer un par un jusqu’à en trouver un de disponible.

Dans le cas les plus extrêmes, certains vont jusqu’à créer leur propre miroir en local. Mais c’est un article à part entière.

Installer des bibliothèques avec des extensions en C

Les bibliothèques avec des extensions en C sont très courantes dans les domaines qui ont besoin de performances: drivers de base de données (mysql-python), calculs scientifiques (numpy), parsing (lxml), cryptographie (pycrypto), etc.

Pip ne fonctionnera que partiellement pour installer ces libs: il devra en effet lancer la compilation de l’extension. Bien que le processus soit automatique et bien fait, il arrive souvent qu’il manque des dépendances.

Pour ce genre de lib, soit vous utilisez un paquet tout fait (*.deb, *.exe, *.rpm, etc.), soit vous tentez d’installer les dépendances.

La première chose à faire, c’est installer les headers de Python. Sous Ubuntu, c’est:

sudo apt-get install python-dev

(et sous CentOs, c’est un yum install python-devel. Pour Mac, aucune idée.)

Ensuite, on lance l’installation une fois de la lib, et on voit ce qui plante, pour installer les dépendances en conséquence. Par exemple, lxml a besoin des headers de libxml2 et libxslt1. Donc on va installer libxml2-dev et libxslt1-dev. Pour python-mysql, il va falloir installer libmysqlclient-dev.

Quand on est une grosse feignasse, mais que l’on a quand même envie d’installer la lib avec pip (typiquement, dans le cas d’un virtualenv). on peut faire le compromis de l’installer sur le système avec un paquet, et ensuite de l’installer avec pip. Ca évite de faire la chasse aux dépendances, mais ça fait double installation.

Enfin, il y a des libs qui ne s’installeront jamais avec pip. Par exemple, un mastodonte genre PyQT. Oubliez, c’est tout.

32 thoughts on “Votre Python aime les pip

  • Sam Post author

    En résumé, distribute aurait du être la solution a tous les problèmes, mais il n’a jamais pris. Maintenant, distutils2 est en route pour être la solution officielle pour Python 3.3.

    Donc en conclusion: si on est en Python 2.x, utiliser setuptools. Si on utilise python 3.3, ou que distutils2 devient suffisament standard pour être backporté, on utilise distutils2.

    setuptools est seulement deprecated, et marchera de toute façon. Donc dans tous les cas, utiliser setuptools est assez sûr, pourvur qu’on soit capable de pallier ses défauts.

    Un article qui résume bien tout ça:

    http://guide.python-distribute.org/introduction.html#current-state-of-packaging

  • Yannick

    Installer une bibliothèque avec le gestionnaire de paquets du système ne te permettra pas d’installer / compiler celle-ci dans ton virtualenv. Ce qu’il faut, c’est installer les dépendances de compilations. Par exemple, pour ton exemple de lxml, il faudra sur Debian faire :

    # apt-get build-dep python-lxml

    Mes 2¢,

    Yannick

  • Sam Post author

    C’est vrai mais la majorité des gens restent sur setuptools, il y a très peu de ressource ou d’aide dispo pour distribute, et en plus il faudra larguer distribute pour distutils2. Alors autant pas se faire chier et rester avec ce qui marche jusqu’à la transition obligatoire.

    Pour le moment, le gain de passage à distribute est très faible, sauf pour certains use cases. Et une fois disutils2 populaires, quel interêt ?

    ditribute est un solution transitoire qui aurait du être géniale, mais qui est se retrouve le cul entre deux chaises.

  • foxmask

    Apres avoir installé les 4 seuls packages (django-registration/profiles/relationships/debug-toolbar) qui me siéent je me retrouve avec un poil long et “freezé” https://gist.github.com/3685455 donc je me dis que pip a trop avalé de cochoneries ;) puiqsue je voulais du support mysql ; boom ; virtualenv re boom … Une suggestion ?

  • Sam Post author

    @gael: la promesse d’être un remplacement drop in n’est pas tenue. D’une part il faut souvent fournir la lib avec le code source, d’autre part il y a des incompatiblités auxquelles je me suis heurtés (des paramètres notamments qui sont changés) alors que ce n’est pas sensé être le cas. Grosse déception de ma part, car j’attendais beaucoup de distribute. Après j’ai peut être mal abordé le truc.

    @foxmask: pip supporte virtualenv de manière transparente. pip freeze dump tous les paquets importables. On peu les limiter au virtualenv en cours avec --local, ou le nettoyer à la main. Quand au support de mysql, je sais pas vraiment ce que tu veux dire, il n’y a rien à faire de particulier pour que ça marche.

  • claus

    en parlant des différences entre python 2.xx et 3.yy : qu’en est-il de l’état d’avancement de la version 3 ? Quelles sont les différences notables entre les deux versions et surtout combien de temps as-t-on avant d’être obligé à désapprendre à coder en 2.xx ?

  • Sam Post author

    @claus: ça mérite un article à soi tout seul mais pour le moment la version de Python 3 la plus répandue est la 3.2, et parmi les changements majeurs on notera l’utilisation de l’unicode par défaut, la fonction print ainsi qu’un renommage et une réorganisation des modules. En gros, si tu sais coder en 2.x, tu sais coder en 3.X. L’inverse n’est pas forcément vrai, car la gestion de l’encoding notament, c’est tout un truc en 2.x.

  • foxmask

    c’est mieux quand on fait un ./bin/pip freeze pour exploiter le bin du virtualenv :P

  • Sam Post author

    pip fonctionne avec virtualenv de manière transparente. Si le virtualenv est activé, il freeze uniquement les lib dispos avec le virtualenv activé

  • Stéphane Klein

    En résumé, distribute aurait du être la solution a tous les problèmes, mais il n’a jamais pris. Maintenant, distutils2 est en route pour être la solution officielle pour Python 3.3.

    Non, distribute est un fork de setuptools…

    Au départ, il était question de patcher setuptools pour corriger un certain nombre de bug. Le mainteneur de setuptools n’était pas très coopératif… après de long mois de discussion… aucun accord n’a été trouvé d’où le fork nommé distribute.

    distutils2 est là pour apporter beaucoup de refactoring… mais ce n’était pas de but de distribute.

    La plupart des personnes utilisent maintenant distribute sans même le savoir.

  • Sam Post author

    Django (distutils): http://pypi.python.org/pypi/Django/1.4.1
    Beautifulsoup (distutils): http://pypi.python.org/pypi/beautifulsoup4/4.1.3
    Lxml (setuptools si dispo mais distutils en fallback): http://pypi.python.org/pypi/lxml/2.3.5
    NumPy (distutils): http://pypi.python.org/pypi/numpy/
    Mercurial (distutils): http://mercurial.selenic.com/release/
    PIL (distribute): http://www.pythonware.com/products/pil/

    Ca, se sont les projets Python les plus utilisés au monde.

    Donc non, la plupart des personnes n’utilisent pas distribute sans le savoir. Distribute n’a jamais rencontré le succès. Je ne dis pas que c’est un mauvais projet, je dis juste qu’il a échoué.

    C’est courant dans le monde du libre de confondre succès technique et succès réel, ou bien fondé d’une idée et réalité du terrain.

    Mais il y a un moment où, quand on veut travailler et produire des trucs utiles, il faut se calmer sur le prosélytisme et observer ce qu’on a sous les yeux. Moi aussi je voudrais que distribute soit utilisé partout. C’est juste pas du tout le cas.

  • Stéphane Klein

    Ca, se sont les projets Python les plus utilisés au monde.

    Tu te bases sur quoi ? sur les stats de téléchargement Pypi ?

    Je pense que distribute est souvent téléchargé sans passer par Pypi : apt-get install, curl…

    Mais je peux me tromper…

  • Sam Post author

    Je me base sur 10 ans de travail en équipe avec des programmeurs de tout poil. Je me base sur les formations demandées qui touchent systématiquement un de ces libs quand ce n’est pas juste Python (bon ok, j’ai oublié zope/plone, là je suis partial). Je me base sur les conversations que j’ai en conf, sur les blogs posts, les tweets, les slide shows.

    Comme pour distribute quoi, je me base sur ce que je vois tous les jours.

  • anthony

    Hello,

    J’aurais besoin de vos lumières.

    J’aimerais pouvoir utiliser pip pour installer des libs pour une version de Python cross-compilé pour Android. J’ai Python 2.7.2 compilé pour Android, et j’aimerais un moyen simple pour y ajouter des libs comme pycrypto etc, sans tout recompiler à la main pour chaque lib. Des idées ?

    Merci

  • Sam Post author

    A moins qu’il y est un compilateur genre gcc accessible sur ta ROM, faudra forcément tout se cross compiler.

  • anthony

    Est-ce que je peux configurer pip pour que sur la machine host il cross-compile tout ça de façon transparente ? Genre une fois que Python est cross-compilé, on choisit quels modules on veut packager et pip s’en charge ?

  • anthony

    J’ai pas trouvé de méthode générique vu qu’on dirait que setuptools/distutils ne gère pas (ou j’ai pas trouvé) la cross-compilation “nativement”.

    Je dois patcher à chaque fois le compiler, e.g. ici pour PyCrypto: https://code.google.com/p/android-python27/source/browse/python-build/patch/pycrypto-2.6-customize_compiler.patch?spec=svn550dbd9a832effd466a6f0ebed9e9c3a1f7e7399&r=550dbd9a832effd466a6f0ebed9e9c3a1f7e7399

    Et ensuite, selon les libs, il y a des modifications à faire (chaque fois) dans les sources C (vu que l’Android libc et le NDK n’expose pas tout ou différement) pour que ça compile. Au final ça fini par marcher, mais c’est vraiment la lutte :/

    Jusque ici j’ai pu ajouter PyCrypto et psutil.

  • Sam Post author

    Merci de ton retour d’expérience, ça aidera d’autres qui passeront par là dans le futur.

  • Teocali

    Ah bah tiens, je continue ma lecture et j’avais une question : au lieu de easy_install django –user ou easy_install pip –user, ca serait pas plutot easy_install –user django ou easy_install –user pip ?

  • Rififi

    Bonjour, petite question. Comment faites vous pour upgrader toutes les libs installées grâce à pip ?

    D’habitude j’utilise ça:
    sudo pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs pip install -U

    Mais ça bloque souvent, avec des erreurs diverses.

  • Sam Post author

    Je ne le fais jamais car tout ce que tu vas gagner c’est tout casser. J’upgrade toujours mes composants un par un, en relançant des tests entre chaque upgrade.

  • Paul

    Bonjour !

    J’espère que aurez l’amabilité de me m’excuser de la naïveté de la question, mais c’est mon premier contact avec un tel environnement, je n’ai jamais programmé ni quoique ce soit.

    J’ai trouvé sur github ce programme qui pourrait m’intéresser : https://github.com/p-e-w/krill

    Étant sous Windows, j’ai tout d’abord téléchargé et installé Python 2.7.11 et j’ai ensuite téléchargé krill que j’ai dézippé dans le dossier “Téléchargements” de mon PC.

    Maintenant, je ne sais que faire. J’ai bien essayé la commande préconisée :

    Code:

    pip install krill

    Mais que ce sois avec IDLE ou la ligne de commande, cela ne fonctionne pas.

    Dois-je déplacer le dossier de krill dézippé et si oui, où ?

    Pardonnez-moi si ces questions vous paraissent du niveau maternelle, mais je le répète c’est mon tout premier contact avec ces instruments de torture intellectuelle.

    D’avance, merci.

  • Sam Post author

    Bonjour Paul,

    Les commentaires du blog sont peu adapter à l’aide. Nous avons mis en place un site exprès pour ça : indexerror.net. Poses-y ta question et nous y répondrons.

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.