Du code, du communisme

Votre Python aime pip

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 InterPouet.
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.