Sam & Max » pip http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Comment installer des libs Python externes dans QGIS ? 6 http://sametmax.com/comment-installer-des-libs-externes-dans-qgis/ http://sametmax.com/comment-installer-des-libs-externes-dans-qgis/#comments Tue, 31 Mar 2015 09:16:35 +0000 http://sametmax.com/?p=16016 QGIS vient avec son Python perso, séparé du reste du système. Du coup si vous faites un pip install une_lib, elle s’installera sur le Python du système, et non de QGIS. Si vous voulez utiliser requests ou arrow pour vos scripts, c’est relou, il faut les télécharger, les extraire, et les mettre à la main sur le PYTHONPATH.

Il est pourtant possible de manipuler interpréteur Python de QGIS, c’est juste que ça saute pas aux yeux :) Ca va nous permettre d’installer pip (si ça ne vous parle par, on a un article pour ça), à la mano, à l’ancienne, comme un homme qui fait ses cartes à la main sur des calques avec des lames de rasoirs en guise de gomme.

D’abord, trouver où il est niché. Sur ma machine, il est dans “C:\Program Files\QGIS Wien\bin\python.exe”.

Si vous le démarrer, vous noterez qu’il plante en prétextant qu’il ne trouve pas le module site. Il faut donc lui dire où sont installées les libs en faisant:

set PYTHONHOME=chemin vers l'installation de Python de QGIS.

Chez moi ça donne :

set PYTHONHOME=C:\Program Files\QGIS Wien\apps\Python27\

Ainsi vous pouvez lancer C:\Program Files\QGIS Wien\bin\python.exe dans la console et obtenir le shell Python de QGIS.

Ensuite, il faut télécharger ez_tools.py qui va nous servir à installer setuptools dans le Python voulu. C’est un script Python (meta meta ! \^O^\), qu’on lance avec l’interpréteur qui nous intéresse, dans mon cas:

"C:\Program Files\QGIS Wien\bin\python.exe" C:\Users\sam\Downloads\ez_setup.py

Il va télécharger depuis internet tout un tas de trucs, et installer tout un tas de machins. Parfois, ça va râler parce que vous n’avez pas les droits. Dans ce cas, lancez la console en mode admin, et faites un cd sur le bureau avant de lancer la commande.

Bien, on a setuptools, qui a du rajouter la commande easy_install. Chez moi elle est dans “C:\Program Files\QGIS Wien\apps\Python27\Scripts”.

On va s’en servir pour installer pip.

Que de bordel !

C:\Program Files\QGIS Wien\apps\Python27\Scripts\easy_install.exe pip

Ca remouline, ça re-dl.

Ce qui va nous mettre la comamnde pip dans le même dossier qu’easy_install.

Et pouf, en utilisant le chemin canonique, on peut utiliser pip :

C:\Program Files\QGIS Wien\apps\Python27\Scripts\pip install ipython pyrealine

Faites attention néanmoins, utiliser cet interpréteur hors de QGIS ne vous donne pas accès à des objets comme iface qui n’existent que quand l’UI de QGIS est chargée. Ca reste pratique pour installer des libs externes, faire des tests python rapides dans le même environnement que QGIS sans lancer tout le bouzin et se la péter face à ses collègues géomaticiens qui ont l’air d’une poule avec un canif devant une console.

]]>
http://sametmax.com/comment-installer-des-libs-externes-dans-qgis/feed/ 6
Wheel installs require setuptools >= 0.8 for dist-info support. 2 http://sametmax.com/wheel-installs-require-setuptools-0-8-for-dist-info-support/ http://sametmax.com/wheel-installs-require-setuptools-0-8-for-dist-info-support/#comments Wed, 22 Jan 2014 19:24:51 +0000 http://sametmax.com/?p=8745 Je ne sais pas pourquoi, mais une fois j’ai eu cette erreur en essayant d’installer un truc avec pip.

La solution est de lancer :

sudo pip install setuptools --no-use-wheel --upgrade

Et on peut réutiliser pip sans problème.

Zarb.

]]>
http://sametmax.com/wheel-installs-require-setuptools-0-8-for-dist-info-support/feed/ 2
5 choses à apprendre en priorité en Python 8 http://sametmax.com/5-choses-a-apprendre-en-priorite-en-python/ http://sametmax.com/5-choses-a-apprendre-en-priorite-en-python/#comments Sun, 22 Dec 2013 08:57:17 +0000 http://sametmax.com/?p=8376 Quand on apprend un nouveau langage de programmation, on apprend d’abord les bases. Et pour la plupart des langages, elles sont communes : déclarer une variable, faire des conditions et des boucles, faire des fonctions, importer un code d’un autre fichier, etc.

Ce qui va différencier le moment où vous savez programmer dans CE langage, ce sont des notions qui lui sont spécifiques et que vous commencez à maitriser.

Voici 5 notions spécifiques au langage qu’il faut apprendre en priorité si vous voulez pouvoir dire “je code en Python” :

Pip

Pip est la moyen le plus utilisé d’installer une bibliothèque externe dans l’environnement Python. Dès qu’on veut faire un projet sérieux, on en a besoin. Tellement qu’il va en fait être inclus par défaut dans Python 3.4.

Lire l’article sur pip.

Virtualenv

Virtualenv permet d’isoler plusieurs installations de Python. A partir du moment où l’on travaille sur plusieurs projets en même temps, il devient vite indispensable. Mais personnellement, je l’utilise même quand je n’ai qu’un projet installé sur une machine car il me permet de le séparer du setup Python du système et d’utiliser des hooks.

Un outil qui a été ajouté dans la lib standard en Python 3.3. J’apprécie que le pragmatisme de l’évolution de Python qui intègre petit à petit les projets qui se sont révélés les outils de facto dans la communauté.

Lire l’article sur virtualenv.

Les listes en intention

J’ai envie de dire l’itération en générale, mais c’est un très vaste sujet, et il est couvert en grande partie par les 3 derniers points.

La liste en intention, ou liste en compréhension, est une manière de boucler sur un itérable (souvent une liste), avec optionellement un filtre, afin de produire une nouvelle liste. En une ligne.

C’est stylistiquement la marque de fabrique de Python (même si c’est piqué à Haskell). C’est également ce qui le rend aussi expressif. On peut presque coder tout un programme en déclaratif avec des enchainements de listes en intention.

C’est beau, propre, efficace et court. IN-DIS-PEN-SA-BLE.

Lire l’article sur les listes en intention.

L’unpacking

L’unpacking est une autre fonctionalité typiquement pythonienne qui permet de prendre un itérable (souvent un tuple), et de mettre ses éléments dans des variables d’une traite.

Cela permet d’augmenter drastiquement la lisibilité des programmes.

Lire les articles sur l’unpacking.

Les générateurs

Les générateurs permettent non seulement un énorme gain en performance, mais en plus ils autorisent le traitement itératif de flux de données dont on ne connait pas la taille en avance, voire de taille infinie. Si vous utilisez des expressions génératrices, vous pourrez le faire en déclaratif. Si vous utilisez yield, vous pourrez cacher un algorithme complet derrière une simple boucle for.

Lire l’article sur yield.

Le reste ?

Tout le reste, c’est du détail. Les décorateurs, la POO, l’opérateur with, les métaclasses, les astuces magiques pour faire ceci ou cela. C’est bien, mais ça peut attendre. Ce sont ces 5 notions, qui, bien utilisées, feront d’un programmeur un dev Python.

]]>
http://sametmax.com/5-choses-a-apprendre-en-priorite-en-python/feed/ 8
Comment tailler une pipe 15 http://sametmax.com/comment-tailler-une-pipe/ http://sametmax.com/comment-tailler-une-pipe/#comments Sat, 16 Nov 2013 18:54:40 +0000 http://sametmax.com/?p=7964 Sur ce blog, l’article qui a le plus cartonné n’a évidement absolument rien à avec Python : c’est le tuto video sur la masturbation féminine (même celui sur la sodomie n’a pas fait mieux). En l’occurrence qui s’adresse aux mecs qui veulent prendre en main leur nana, mais qui je suis sûr a intéressé quelques femmes également. Pour la culture (du point) G.

Malgré l’abondance du matériel pornographique sur le sujet, je suis certain que de nombreuses femmes se demandent comment faire une fellation. En effet, on le souligne rarement, mais il y a autant de mauvais coups femmes que hommes, la différence majeure étant que la plupart des hommes se satisfont de relations sexuelles de piètre qualité (pour des raisons pathétiques, mais ce n’est pas le sujet de l’article).

Et dans le lot il y en a forcément qui se demandent comment changer cela. Après tout personne n’est né pour mettre la bite de quelqu’un dans sa bouche, c’est forcément une connaissance artificielle. Et puis on a un lectorat gay également, même si je doute qu’on puisse leur apprendre quoique ce soit. Pro-tip : si vous avez des amis LGB extravertis, demandez leurs des conseils, ils sont simplement meilleurs que vous au pieu.

Comme pour le cuni, il n’y a pas de méthode empaquetée, prête à être livrée, mais voici quelques points clés.

Le teaser

Je le répète souvent, le sexe est la dînette des adultes. C’est du théâtre. C’est pour le fun. Et la reproduction, mais bon, la turlute n’est pas indiquée pour ça.

La pipe n’échappe pas à cette règle, elle sera meilleur si vous jouez le jeu.

D’abord il y a le regard. Un regard sûr(e) de soi (faites semblant), coquin ou carrément cochon. Un air qui dit qu’on en a envie.

Et il y a l’approche. Pas trop rapide, un peu joueur ou alors bestial, comme vous voulez, mais faites une mise en scène, c’est plus sympa.

Encore une fois, personne ne baise 5 étoiles tous les jours, ce sont juste des conseils.

La prise en main

Commencez par décalotter, car rien ne sert de sucer un gland recouvert.

Celui-ci est sensible au début, donc gardez la main à la base du pénis. Vous pouvez y aller fermement, la base n’est pas sensible. Les doigts autour de la verge, la paume reposant, et poussant, sur la base. Un micro mouvement de va et vient en appuyant lentement, mais avec un peu de force vers le bas peut être appliqué.

Évitez de remonter la main à plus de quelques centimètres du gland est le plus important au début.

Mais comme pour le broute minou, il y a beaucoup de question de goût dans tout ce que je vais dire, donc souvenez-vous que ce sont des indications pour avoir de bonnes bases, pas des recettes miracles. J’ai rencontré un suisse qui me disait une fois qu’il adorait qu’on lui fasse des genres de brûlure indienne sur la tub. Je sais, j’ai des conversations bizarres. C’était près du lac du Loch Ness, alors la bizarrerie, vous savez…

Si vous savez masturber votre partenaire, vous pouvez alterner sans problème, et même pratiquer une masturbation particulièrement forte sur la fin. Mais attention, branler un mec correctement est généralement plus difficile que de le sucer. Pour vous entraîner, faites le en étant derrière lui d’abord, votre main sera dans le bon sens de la courbure donc se sera plus facile.

La prise en bouche

Je sais qu’on voit beaucoup de pornos où la meuf s’acharnent comme une malade sur le dard de son ou ses partenaires, mais bien que ça puisse être excitant à regarder, c’est rarement aussi agréable physiquement que quelqu’un qui y va à un rythme modéré au départ.

Bien entendu, comme souvent dans le cul, on accélère sur la fin, on y va plus fort, et on peu aussi commencer en mode bête sauvage dès le début, mais c’est contextuel. Pour la plupart des cas, doucement, puis on accélère.

Le plus important est de ne pas sentir les dents et de bien lubrifier.

Ça veut dire notamment saliver abondamment sur la bite. Abondamment. Crachez dessus si c’est trop sec. Si, si. Il faut que ça soit bien mouillé.

Et gardez votre air coquin, ça aide.

Pour les dents, c’est une question d’entraînement. Une copine bi m’a dit qu’avant sa première fois avec un mec, elle n’avait eu que des nanas, et était donc un peu perdu. Elle s’est finalement entraîné sur son pouce.

C’est un très bon conseil pour les dents et la salive. Pour le mouvement et autre, non. Mais il est très facile de voir si on sent ses dents sur son propre pouce, et assez simple de s’apercevoir si ça glisse tout seul ou si c’est un peu sec.

Vous avez déjà du entendre parler ou voir du deept throat ou du bukkake, des pratiques qui consiste essentiellement à traiter la bouche de la femme comme un vagin-auto-tamponneuse. Le plaisir qui en est retiré est purement psychologique et n’apporte aucun agrément physique. Il y a en fait peu d’hommes qui aiment ça, même si ils existent. Ce n’est pas parce que ça vous excite en vidéo que vous le voulez en vrai. Donc renseignez vous avant, et dans le doute, on vit très bien sans.

Le finish

Le finish est très important. Si vous êtes en train de faire quelque chose quand il vient, il aura bien plus de plaisir si vous ne vous arrêtez pas quand il jouit. Que ça soit branler ou sucer.

Maintenant il y a des tas de meufs qui n’ont pas envie de se prendre une giclée de sperme, ce que je comprends. Demandez au mec de prévenir dans ce cas avant qu’il vienne. Si vous ne dites rien…

La finition en bouche est très agréable, et bien entendu, personne ne vous oblige à avaler. Aller cracher juste après et vous laver les dents et tout à faire normal. Refuser catégoriquement aussi :-)

Sinon, venir sur les nichons n’apporte pas de sensation en plus, mais dans la tête ça turbine, et c’est un bon compromis.

Ne vous mettez pas non plus martèle en tête. Vous lui avez sucé la bite, si en plus il se plaint que la fin lui convient pas, mettez lui un god dans le cul, ça le calmera.

Quelques exemples

Bon, tout ça c’est très théorique, mais ça donne quoi en pratique ?

Voici deux styles un peu différents, et les deux sont de bons exemples :

Et voici un exemple qui peut être excitant en vidéo, mais qui, sauf quelques exceptions (contexte, personnes, alcoolémie, phases de la lune), rend vachement moins bien IRL :

Tips

Il existe quelques moments particulièrement chouettes pour glisser une fellation. Il faut qu’elle vienne de vous dans ce cas là, mais ça fait toujours plaisir :

  • Dans la voiture en conduisant.
  • Sûr le fauteuil pendant un film.
  • Sous le bureau pendant le travail.
  • Sous la douche.
  • Au réveil.

L’idée est que ce soit spontané et imprévu. J’ai une copine une fois qui, juste avant de partir au boulot, au lieu de m’embrasser, m’a sucé en quelques secondes, puis est partie sans dire un mot. Je m’en souviens encore.

Notez que le problème de la pipe surprise (et même sans surprise), c’est que le mec peut avoir la bite sale. Or vous n’allez pas lui demander de se la laver avant, imagez qu’il fasse ça pour un cuni…

L’astuce, c’est d’avoir des lingettes pour bébé. Bien choisir sa marque pour que le goût soit pas dégueu, ça fait briller un braquemart en 5 secondes, remplaçant l’odeur de crevette faisandée par un doux fumet de what-ever-is-inside-the-stuff.

Une fois qu’il est venu, n’hésitez pas à le nettoyer avec un mouchoir ou un lingette. C’est très agréable.

Oh, et si vous avez envie d’un massage ou d’un léchage, demandez le avant la pipe, après c’est foutu :-)

Pour finir, un petit résumé :

]]>
http://sametmax.com/comment-tailler-une-pipe/feed/ 15
Crate.io, une alternative à Pypi 5 http://sametmax.com/create-io-une-alternative-a-pypi/ http://sametmax.com/create-io-une-alternative-a-pypi/#comments Thu, 22 Nov 2012 15:14:49 +0000 http://sametmax.com/?p=3163 pip, vous savez que le listing officiel des libs Python est Pypi, un site for pratique, mais qui commence à dater. ]]> Si vous avez lu l’article sur pip, vous savez que le listing officiel des libs Python est Pypi, un site fort pratique, mais qui commence à dater.

Apparemment certains ont eu envie de changer ça, en créant crate.io, une alternative moderne à Pypi: interface plus léchée et présentant des stats sympathiques, il est un mirroir complet de Pypi et contient donc les mêmes packages.

On peut demander à pip d’utiliser create.io comme source. Par exemple pour installer Django:

pip install --index-url=https://simple.crate.io django

Pratique si Pypi n’est pas disponible, ou juste pour ne pas mettre tous ses oeufs dans le même panier.

Il est important de noter que c’est une initiative privée, alors que Pypi est gérée par la Python fondation, les buts ne sont pas les mêmes. Cela dit, les sources sont disponibles sur github, donc ça met en confiance. On peut d’ailleurs voir que le bouzin tourne avec Django/Postgesql/Redis/Celery.

]]>
http://sametmax.com/create-io-une-alternative-a-pypi/feed/ 5
Créer un setup.py et mettre sa bibliothèque Python en ligne sur Pypi 52 http://sametmax.com/creer-un-setup-py-et-mettre-sa-bibliotheque-python-en-ligne-sur-pypi/ http://sametmax.com/creer-un-setup-py-et-mettre-sa-bibliotheque-python-en-ligne-sur-pypi/#comments Fri, 16 Nov 2012 18:06:09 +0000 http://sametmax.com/?p=3102 Je crois que ce sujet est dans le top 10 des trucs qui paraissent mystiques même après avoir passé des heures sur les docs sur le net. Et si ça prend effectivement un peu de temps CPU neuronale pour s’en sortir, on est loin de la montagne qu’on s’en est fait.

Scénario: vous avez écrit une lib. Elle est belle, elle sent bon le sable chaud. Vous voulez la partager.

La première étape, c’est de créer une fichier setup.py qui permettra aux gens de l’installer. La seconde, c’est de la mettre en ligne sur le site Pypi pour que les gens puissent l’installer avec pip.

Nous allons donc créer un setup.py pour une lib incroyable: la “sm_lib”.

Arborescence

Généralement, quand on développe une petite lib au fil de l’eau, on une forte tendance à tout mettre en vrac dans un dossier. Cependant pour créer un paquet installable, il est beaucoup plus simple et propre d’avoir une organisation de fichiers standards. On peut faire sans, mais c’est prise de tête.

Prenons notre lib exceptionnelle…

Pour le moment, elle est composée d’un dossier “sm_lib” avec 3 fichiers:

  • une photo des auteurs (suite aux plaintes reçues, nous avons une nouvelle ligne de conduite concernant les photographies. Demain, les bébés !);
  • l’indispensable __init__.py, qui est vide;
  • un fichier core.py (qui peut avoir n’importe quel nom) qui contient le code de notre lib dont le but est de diffuser un message hautement subversif:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
 
from datetime import datetime
 
 
def proclamer():
    print "[%s] Sam et Max, c'est bien" % datetime.now()
 
 
if __name__ == "__main__":
    proclamer()

Maintenant que nous avons changé de mentalité, nous voulons absolument propager notre nouveau message et ton du blog partout, donc on va distribuer cette bibliothèque.

Premièrement, on va réorganiser les fichiers et en rajouter quelques uns:

On met sm_lib dans un dossier sm_lib

Vous noterez qu’on a mis notre dossier de lib, dans un autre dossier, et que les deux dossiers portent le même nom “sm_lib”. C’est redondant, mais c’est normal. Le dossier qui contient tout est le dossier de distribution, c’est l’emballage de notre lib. Le dossier qui contient notre code, c’est le dossier d’installation, c’est celui qui sera copié sur le système, et qui doit avoir un nom de package importable (uniquement des lettres et des _ dans le nom, ou un chiffre mais pas en premier caractère).

Les noms peuvent être différents, mais généralement on donne le même nom aux deux, car c’est plus simple.

On rajoute 3 fichiers:

  • setup.py: un fichier de code Python qui est notre installeur.
  • MANIFEST.in: un fichier texte qui liste les fichiers non Python qu’on inclura dans l’installation.
  • README.md: un fichier markdown (c’est du texte, juste un peu formaté) contiendra une présentation du package.

Pour le moment nos trois fichiers sont vides.

Choix des outils

Une des difficultés principales dans la distribution d’un code Python, c’est l’abondance de solutions. Pour l’installeur, on peut choisir entre distribute, setuptools, distutils ou Distutils2.

Je vous passe les détails, mais j’ai essayé les 4. distutils est trop vieux. distribute va être remplacé par distutils2 qui lui est encore très jeune. La seule solution qui passe partout pour le moment c’est setuptools. Tarek Ziade va faire la gueule, mais c’est ce que je recommande d’utiliser pour le moment. Je metterai à jour cet article pour utiliser un setup.cfg et des moyens plus modernes quand tout ça sera devenu la solution de facto, mais je ne vais pas pousser à la migration.

Donc vous allez utiliser setuptools.

Ensuite on utilise un fichier MANIFEST.in pour lister les fichiers non Python. On pourrait tout passer en paramètres à la main, mais le manifeste est la solution la plus productive.

Enfin on utilise un fichier markdown. ReST est le standard en Python, mais il est compliqué (je me suis tapé suffisament de doc sphynx pour témoigner), et pas géré par Github par défaut. Markdown ressort bien sur Pypi même sans conversion en HTML, donc on va garder ce format.

Oh, et ça va sans dire, mais ça va mieux en le disant, on va distribuer les fichiers sous forme de source pure, pas sous forme d’exe ou d’egg. C’est installable avec pip sur toutes les plateformes, et ça évite bien des prises de tête.

Rendez votre paquets user friendly

La première chose à faire, avant de mettre en ligne, c’est de rendre votre paquets facile à utiliser. Assurez-vous d’avoir les docstrings qui vont bien, et faciliter les imports.

Par exemple, dans notre __init__.py, on va rajouter:

from core import proclamer

Ainsi, l’utilisateur pourra faire:

from sm_lib import proclamer

au lieu de :

from sm_lib.core import proclamer

Faites cela uniquement pour les fonctions et classes les plus utiles. C’est un détail, mais ça rend l’expérience plus agréable.

Ensuite, si l’utilisateur est dans son shell, il va utiliser l’autocompletion pour découvrir votre lib. Il va se balader, et spammer “tab” pour voir “ce qu’il y a dedans”.

Pour faciliter ce process, limitez ce qui est importable avec __all__:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
 
from datetime import datetime
 
__all__ = ['proclamer']
 
 
def proclamer():
    print "[%s] Sam et Max, c'est bien" % datetime.now()
 
 
if __name__ == "__main__":
    proclamer()

Ainsi, seul proclamer() sera importable depuis le module core si quelqu’un fait un import *. En effet, en important datetime, vous l’insérer dans le namespace de core, et donc il sera importable en faisant from sm_lib.core import datetime, et il apparaîtra dans l’autocompletion. Ici ça parait dérisoire, mais sur les grosses libs, ça fait beaucoup de bruit.

__all__ est une liste strings qui contient les noms de tout ce qu’on autorise à importer depuis ce module. Utilisez le pour rendre votre API d’import propre comme la chatte de… comme un sous neuf pardon. Désolé, par encore habitué à parler la novlang. On s’y met. On s’y met.

Pour finir on met les docstrings qui vont bien:

  • une dans __init__.py pour décrire le package;
  • une au sommet de core.py pour décrire module;
  • une dans proclamer() pour décrire la fonction.

Ainsi l’utilisateur qui va installer votre lib s’y retrouvera très facilement en utilisant la fonction help(). Même sans doc et hors ligne.

__init__.py (on rajoute aussi l’en-tête d’encoding vu que la docstring contient des caractères non-ASCII):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
    Ce module proclame la bonne parole de sieurs Sam et Max. Puissent-t-ils
    retrouver une totale liberté de pensée cosmique vers un nouvel age
    reminiscent.
"""
 
__version__ = "0.0.1"
 
from core import proclamer

On a aussi rajouté la version, car il n’y a rien de plus chiant que d’avoir un bug sur une lib et de ne pas savoir de quelle version il s’agit. Il va falloir maintenir cette variable à jour.

Et core.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
    Implémentation de la proclamation de la bonne parole.
 
    Usage:
 
    >>> from sm_lib import proclamer
    >>> proclamer()
"""
 
from datetime import datetime
 
__all__ = ['proclamer']
 
 
def proclamer():
    """
        Fonction de proclamation de la bonne parole. Aucun paramètre, et
        retourne None, car tout le monde say que "Ex nihilo nihil"
    """
    print "[%s] Sam et Max, c'est bien" % datetime.now()
 
 
if __name__ == "__main__":
    proclamer()

Je vous passe le pamphlet sur les tests, c’est plusieurs articles rien que pour expliquer le pourquoi du comment. C’est mieux si vous en avez, mais si vous n’en avez pas, ne vous empêchez pas de publier, ça peut se rajouter au fur et à mesure.

Petite remarque en passant: je met toute la doc en français pour que vous compreniez le principe, mais si vous publiez un truc, je vous recommande chaudement de tout écrire en anglais de A à Z (variables, fonctions, modules, docstrings, comments, readme, doc, tests, etc). Sans quoi votre audience sera limitée au nombre de francophones qui programment, et en Python, et qui ont le niveau pour intéresser aux libs externes. Autant dire l’équivalent de l’audience ridicule de ce blog.

README

Dans le fichier README.md, qui est un fichier texte ordinnaire, assurez-vous de mettez les choses suivante:

  • A quoi sert la lib.
  • Comment l’installer.
  • Un exempe concret d’utilisation.
  • La licence d’utilisation.
  • Un lien vers la doc si elle existe.

Nous allons mettre le texte au format markdown. C’est un format très simple qui a le double avantage d’être automatiquement transformé en HTML par Github, et qui est bien lisible même quand il reste brut, tel qu’il sera affiché sur Pypi.

Dans notre cas, README.md va ressembler à un mélange des docstrings, un peu amélioré:

SM Lib - Proclame la bonne parole de sieurs Sam et Max
========================================================

Ce module proclame la bonne parole de sieurs Sam et Max. Puissent-t-ils
retrouver une totale liberté de pensée cosmique vers un nouvel age
reminiscent.

Vous pouvez l'installer avec pip:

    pip install sm_lib

Exemple d'usage:

    >>> from sm_lib import proclamer
    >>> proclamer()

Ce code est sous licence WTFPL.

MANIFEST.in

Le fichier va contenir une liste de tous les fichiers non Python qu’on veut inclure dans le package. Dans notre cas, la photo et le README.

include *.md
recursive-include sm_lib *.jpg

La syntaxe est elle aussi très simple, et utilise la notation des globs “*”.

La première ligne dit d’inclure tout fichier dans le nom est “n’importe quoi”.md. Il va inclure le README.
La seconde ligne dit d’inclure récursivement tout fichier dans le dossier sm_lib et ses sous-dossiers qui est nommé “n’importe quoi”.jpg. Il va inclure notre photo.

On peut mettre plusieurs lignes, et plusieurs motifs sur chaque ligne. Il n’est donc pas rare de voir des fichiers qui ressemblent à ça:

include *.txt *.rst
recursive-include dir1 *.txt *.rst
recursive-include dir2 *.png *.jpg *.gif
recursive-include dir2 *.css *.js *.coffee

Setup.py

C’est la partie difficile. Le fichier setup.py contient une fonction qui va magiquement installer votre lib, et il faut lui passer des paramètres et l’appeler. Le problème c’est que cette fonction compte 34 (à ma connaissance) arguments.

Vous pouvez mettre n’importe quel code Python dans le setup.py, mais généralement la fonction setup() suffit.

Je vais mettre dans ce setup.py les paramètres que vous utiliserez les plus souvent:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from setuptools import setup, find_packages
 
# notez qu'on import la lib
# donc assurez-vous que l'importe n'a pas d'effet de bord
import sm_lib
 
# Ceci n'est qu'un appel de fonction. Mais il est trèèèèèèèèèèès long
# et il comporte beaucoup de paramètres
setup(
 
    # le nom de votre bibliothèque, tel qu'il apparaitre sur pypi
    name='sm_lib',
 
    # la version du code
    version=sm_lib.__version__,
 
    # Liste les packages à insérer dans la distribution
    # plutôt que de le faire à la main, on utilise la foncton
    # find_packages() de setuptools qui va cherche tous les packages
    # python recursivement dans le dossier courant.
    # C'est pour cette raison que l'on a tout mis dans un seul dossier:
    # on peut ainsi utiliser cette fonction facilement
    packages=find_packages(),
 
    # votre pti nom
    author="Sam et Max",
 
    # Votre email, sachant qu'il sera publique visible, avec tous les risques
    # que ça implique.
    author_email="lesametlemax@gmail.com",
 
    # Une description courte
    description="Proclame la bonne parole de sieurs Sam et Max",
 
    # Une description longue, sera affichée pour présenter la lib
    # Généralement on dump le README ici
    long_description=open('README.md').read(),
 
    # Vous pouvez rajouter une liste de dépendances pour votre lib
    # et même préciser une version. A l'installation, Python essayera de
    # les télécharger et les installer.
    #
    # Ex: ["gunicorn", "docutils >= 0.3", "lxml==0.5a7"]
    #
    # Dans notre cas on en a pas besoin, donc je le commente, mais je le
    # laisse pour que vous sachiez que ça existe car c'est très utile.
    # install_requires= ,
 
    # Active la prise en compte du fichier MANIFEST.in
    include_package_data=True,
 
    # Une url qui pointe vers la page officielle de votre lib
    url='http://github.com/sametmax/sm_lib',
 
    # Il est d'usage de mettre quelques metadata à propos de sa lib
    # Pour que les robots puissent facilement la classer.
    # La liste des marqueurs autorisées est longue:
    # https://pypi.python.org/pypi?%3Aaction=list_classifiers.
    #
    # Il n'y a pas vraiment de règle pour le contenu. Chacun fait un peu
    # comme il le sent. Il y en a qui ne mettent rien.
    classifiers=[
        "Programming Language :: Python",
        "Development Status :: 1 - Planning",
        "License :: OSI Approved",
        "Natural Language :: French",
        "Operating System :: OS Independent",
        "Programming Language :: Python :: 2.7",
        "Topic :: Communications",
    ],
 
 
    # C'est un système de plugin, mais on s'en sert presque exclusivement
    # Pour créer des commandes, comme "django-admin".
    # Par exemple, si on veut créer la fabuleuse commande "proclame-sm", on
    # va faire pointer ce nom vers la fonction proclamer(). La commande sera
    # créé automatiquement. 
    # La syntaxe est "nom-de-commande-a-creer = package.module:fonction".
    entry_points = {
        'console_scripts': [
            'proclame-sm = sm_lib.core:proclamer',
        ],
    },
 
    # A fournir uniquement si votre licence n'est pas listée dans "classifiers"
    # ce qui est notre cas
    license="WTFPL",
 
    # Il y a encore une chiée de paramètres possibles, mais avec ça vous
    # couvrez 90% des besoins
 
)

Tester si tout marche bien

Si vous publiez du code, je vais partir du principe que vous utilisez au moins un virtualenv :-)

Donc, activez un environnement de test, et dans le dossier contenant setup.py, faites:

python setup.py install

Normalement votre lib devrait s’insaller dans votre env proprement. Vous devriez pouvoir faire dans un shell Python:

>>> from sm_lib import proclamer
>>> proclamer()
[2012-11-16 13:06:58.128545] Sam et Max, c'est bien

Et comme on a créé une commande, on doit aussi pouvoir faire depuis un terminal:

$ proclame-sm
[2012-11-16 13:08:18.763732] Sam et Max, c'est bien

Si vous regardez dans votre virtualenv, vous verrez que votre package a été ajouté. Sur ma machine il se trouve par exemple à ~/.virtualenvs/test/lib/python2.7/site-packages/sm_lib-0.0.1-py2.7.egg/sm_lib.

La photo doit-être dedans, ainsi que le code Python. La photo est un exemple important à comprendre et à faire marcher car c’est le manifeste que vous utiliserez pour tous les fichiers non Python: CSS, Javascript, Documentation, Images, Xml, Json, etc.

Publier sur Pypi

Cela va vous paraitre étonnant, mais tout le monde peut publier sur Pypi. Pourvu que le nom soit disponible, vous pouvez en fait uploader n’importe quoi. Même une lib de test comme celle-ci.

Entrez la commande (il faut avoir accès à internet):

$ python setup.py register

Ceci va inscrire votre lib dans leur listing. Et donnera une sortie qui ressemble à ça:

running register
running egg_info
writing sm_lib.egg-info/PKG-INFO
writing top-level names to sm_lib.egg-info/top_level.txt
writing dependency_links to sm_lib.egg-info/dependency_links.txt
writing entry points to sm_lib.egg-info/entry_points.txt
reading manifest file 'sm_lib.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'sm_lib.egg-info/SOURCES.txt'
running check
We need to know who you are, so please choose either:
 1. use your existing login,
 2. register as a new user,
 3. have the server generate a new password for you (and email it to you), or
 4. quit
Your selection [default 1]: 

Choissisez 2. Il va vous permettre de créer un compte. Quand il vous demandera de sauvegarder vos identifiants pour un usage future, répondre oui vous permettra de ne pas rentrer votre mot de passe à chaque upload.

La prochaine fois vous pourrez choisir 1, puisque vous aurez un compte.

Si ça se coupe, relancez juste la commande. Le but étant d’obtenir ça:

Registering sm_lib to http://pypi.python.org/pypi
Server response (200): OK

Ce qui signifie que votre lib est inscrite sur Pypi (et que donc le nom était disponible, sinon il vous enverra chier et vous avez plus qu’à renommer votre lib).

Puis, il faut créer une distribution source (sdist) et le mettre en ligne (upload):

python setup.py sdist upload

Et voilà, votre lib est en ligne et installable avec pip !

Voici la page pypi, et la page gitub (ce qui n’a rien à voir, mais si vous voulez le code source…).

C’est finit. Si vous voulez uploader une nouvelle version de votre lib, il faut changer __version__ car Pypi n’accepte pas deux fois la même version.

]]>
http://sametmax.com/creer-un-setup-py-et-mettre-sa-bibliotheque-python-en-ligne-sur-pypi/feed/ 52
Votre Python aime les pip 30 http://sametmax.com/votre-python-aime-les-pip/ http://sametmax.com/votre-python-aime-les-pip/#comments Sat, 08 Sep 2012 13:42:27 +0000 http://sametmax.com/?p=2014 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 ?]]> 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.

]]>
http://sametmax.com/votre-python-aime-les-pip/feed/ 30