Planète AFPy RSS

[Biologeek] Enseignement et acquisition

Publié le 2014-10-22 11:00:00

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

EAFP

J’ai appris qu’il y avait eu une suite à l’intervention de SudWeb au sujet de l’enseignement de l’intégration lors de ParisWeb (merci Boris !). On peut dire que ça tombe au bon moment. Tout cela m’amène à faire un parallèle entre des paradigmes de langages de programmation (EAFP vs. LBYL) et l’opposition pratique vs. théorique que l’on rencontre forcément lorsque l’on souhaite transmettre ses connaissances. À quel point faut-il prévenir plutôt que guérir ? Qu’est-ce qui est le plus formateur ?

J’ai pour l’instant pris l’option très expérimentale : produisez, je vous corrige. Et j’espère bien arriver jusqu’à un point où cela deviendra : produisez, corrigez-vous ! Ce vous correspondant au groupe et aux connaissances accessibles en ligne. Mais je suis tiraillé. Ces étudiants ont la chance d’avoir une formation et je leur propose de devenir autodidactes. Est-ce que je ne les prive pas ainsi d’une théorie qui m’a manquée pour pouvoir progresser plus rapidement il y a 10 ans ? Est-ce que les trentenaires du Web (huhuhu) ne se cachent pas derrière cette mise en pratique car ils n’ont connu que ça ?

Et puis je me raccroche à la permissivité du Web, à cette inconsistence inscrite dans son ADN, à ces paquets qui errent entre 2 continents avec l’espoir d’arriver quelque part. J’imagine ces étudiants qui souhaitent à tout prix être autonomes alors qu’il va leur falloir apprendre à faire ensemble. Qui veulent appliquer de la bonne pratique sans forcément en comprendre le sens et le besoin. Je les observe, perdus mais volontaires, et je garde espoir. Ils ont encore le temps pour faire des erreurs et l’énergie pour se relever.

[afpyro] AFPyro à Lyon - mercredi 22 octobre

Publié le 2014-10-22 00:00:00

Un Afpyro aura lieu le mercredi 22 octobre à partir de 19h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Il n’y aura pas de présentation ce mois ci, mais on va s’organiser un peu pour que tout se passe bien pendant la PyConFr. Donc si jamais vous êtes lyonnais et volontaire, venez y faire un tour !

Si vous n’avez pas la possibilité de venir à l’apéro, mais que vous voulez donner un coup de main pendant PyConFr, faites signe !

L’Antre Autre est un lieu où nous pouvons discuter autour d’un verre, et, pour ceux qui le souhaitent, prendre un repas.

Pour se rendre à l’Antre Autre :

  • en métro : arrêt Hôtel de Ville
  • en bus : lignes C13 et C18 arrêt Mairie du 1er ou lignes 19, C14 et C3 à l’arrêt Terreaux
  • en vélo’v : stations Place Sathonay, Carmélites Burdeau, Place de la paix

[Biologeek] Cours IUT : les bases

Publié le 2014-10-21 11:00:00

The plan is a lie.

Retours sur mon premier cours à l’IUT d’Arles. La journée a assez mal commencée avec l’impossibilité de retrouver mes adaptateurs DVI-miniDVI… ce qui ajoutait une légère contrainte en plus. Du coup après un petit tour de classe où j’ai pu confirmer que les niveaux étaient vraiment disparates ET que le cours précédents sur les bases de HTML/CSS n’avait pas été assimilé, on est partis sur un petit projet qui nous a servi de fil rouge tout au long de la matinée. J’ai retenu 2 volontés fortes de la part des étudiants : devenir plus autonomes et améliorer la qualité de leurs productions. Yay!

Par groupe de 4 ou 5, les étudiants ont créé une page selon le brief précédemment décrit avec pour consigne de se répartir en groupes de niveaux homogènes. Après 45 minutes, l’un des étudiants (pas celui qui était sur le clavier) présente le travail du groupe à toute la classe. On part ensuite sur l’itération suivante avec des contraintes supplémentaires (dont celle permanente d’avoir une rotation au niveau de la personne qui code). On a pu faire 4 itérations sur la matinée avec les contraintes suivantes :

  • démarrage libre ;
  • repartir sur des bases saines comme HTML5Boilerplate avec les avantages/inconvénients associés, rappels sur les reset (connu) et le centrage des éléments ;
  • ne pas utiliser les attributs id/class pour styler la page (merci Vincent !) et donc mieux utiliser les balises HTML 5 et les sélecteurs, introduction aux sélecteurs + et > notamment ;
  • réorganiser sa CSS pour avoir quelque chose de propre et transmissible, introduction aux frameworks CSS.

Les itérations se sont fluidifiées au cours de la matinée avec des rappels et des conseils au fil de l’eau de ma part. Les résultats étaient finalement assez différents en fonction de la priorité du groupe : transmettre et homogénéiser les connaissances (collaboration) ou arriver à un résultat en se répartissant les tâches (coopération). Les deux approches étaient intéressantes car elles sont représentatives de ce qu’ils pourront rencontrer par la suite.

Quelques réflexions en vrac :

  • tous les groupes ont commencé par faire un menu alors qu’une seule page était demandée, assez marrant ;
  • aucun groupe ne s’est préoccupé du contenu sur la première itération, l’attention était entièrement sur les images et la CSS ;
  • aucun échange n’a été fait entre les groupes, ni même un coup d’œil pour se rendre compte qu’ils avaient pris la même image sur Google pour illustrer le site ;
  • j’aurais dû changer l’étudiant qui a initialement pris le clavier (le plus compétent) pour laisser mettre en place les bases par quelqu’un de moins expérimenté ;
  • les étudiants ont maintenant leur propre machine (majoritairement des Macbook) et passent par des bidouilles à base de clés USB et de connexions 3G pour travailler alors qu’il y a des machines connectées en Windows juste à côté, je vais essayer d’apporter mon propre réseau local la prochaine fois car la situation est assez hallucinante.

Globalement les étudiants avaient l’air assez satisfaits. La mini-rétrospective en fin de cours a fait émerger 2 propositions pour le prochain cours :

  • travailler en plus petits groupes (2/3) ;
  • plancher sur un sujet plus proche de leurs intérêts.

Ce sera donc adopté en repartant des bases acquises pour aller vers un peu plus de dynamisme vu qu’ils sont friands d’effets en JavaScript/jQuery, il faut aussi que je leur parle de Flexbox et qu’on prenne le temps de faire une introduction aux différentes méthodes pour initier un site. J’ai reçu 3 emails d’élèves qui souhaitaient me montrer ce qu’ils avaient déjà produit (à mon initiative), c’est peu sur un effectif de 24 mais c’est déjà ça :-).

[AFPy Salt-fr] Annonce : Meetup Salt Paris - Novembre 2014

Publié le 2014-10-20 22:00:00

Oyez, oyez salters, notre prochain meetup se déroulera le mardi 18 novembre à partir de 19h chez tinyclues qui est fier de nous héberger et de pouvoir sponsoriser cet évènement.

Voici la liste des présentations qui seront données :

  • Salt et la gestion d'un parc de postes utilisateurs, homebrew cask pour Mac et chocolatey pour Windows (Aurélien Minet - ENS Cachan)
  • Runners et modules pour générer des statistiques d´écart de l'infrastructure par rapport à sa définition (Arthur Lutz - Logilab)
  • SaltPad, l'interface que votre infrastructure mérite (Boris Feld - tinyclues)

Malheureusement, le nombre de place est limité à 30 personnes, donc dépêchez-vous de vous inscrire ici : http://framadate.org/n8u9e8ib1ffggdmt.

Vous pouvez aussi vous inscrire sur le meetup pour suivre les actualités du groupe : http://www.meetup.com/Paris-Salt-Meetup/.

tinyclues nous offrira de quoi nous désaltérer et Logilab nous fournira de quoi remplir nos estomacs, d'ailleurs si vous voulez autre chose que des pizzas, merci de répondre au sondage sur la mailing-list.

Les locaux de tinyclues c'est au

15, rue du Caire
75002 Paris
France

Métro Réaumur - Sébastopol ou Strasbourg Saint-Denis.

En espérant vous voir nombreux, saltez bien !

[AFPy-Nantes] Barcamp & micro-python

Publié le 2014-10-18 22:00:00

Pour le barcamp Python du 30 Septembre, nous étions 6 à s'être intéressés à cette mystérieuse carte micro-python. C'est donc convivialement installés autour d'une table qu'on a pu en savoir plus.

Compte rendu.

Présentation

Né d'un projet Kick-Starter, micro-python est un microcontrôleur embarquant un interpréteur d'un dialect de Python 3. Après la réussite du financement sur Kick-Starter, un exemplaire a été envoyé à tous les gens y ayant participé. Puis chaque personne s'étant manifestée sur leur newsletter a pu en avoir un. Désormais la boutique Internet est ouverte à tous. Si ça vous fait déjà rêver, c'est par ici.

C'est donc un petit joujou d'open hardware que nous avons pu voir en action. La bestiole est équipée d'un processeur ARM et coûte environ 35€. Pour l'instant on commande depuis le Royaume-Uni, donc c'est en Livres... Concernant le stockage, deux options. Une mémoire flash de 128Ko et un port pour micro-SD. Pour le reste, notre micro-copain intègre des accéléromètres. Il y a une démo sur le site pour le transformer en souris. Par contre, pas de gyroscope, donc exit la position en temps réelle native. En revanche, il existe de nombreux shield (modules additionnels) que l'on peut déjà commander et dont le prix est assez bas. On citera un afficheur LCD, un touch-pad et de quoi supporter le wi-fi. Enfin, la carte présente quatre (4) LEDs. Rouge, jaune, verte et bleue. L'intensité de cette dernière peut être réglée. La question s'est évidemment posée de l'avantage par rapport à son concurrent direct, le Raspberry Pie. Deux arguments principaux sont ressortis. D'abord la consommation électrique bien inférieure de micro-python : l'absence de processeur graphique est l'une des raisons. Il a également été évoqué les fuites de courant des ports USB du Rasberry Pie. De plus, ces derniers ne peuvent pas être désactivés, donc pas d'optimisation de la consommation possible. Second argument en faveur de micro-python, éviter l'over-kill. En effet, pour la pluspart des utilisations d'un microcontrôleur, un Raspberry Pie fait un peu office de bombe nucléaire. Petit plus de la carte, elle présente une documentation électrique fournie et claire, écrite en blanc au dos de celle-ci.

Concernant le logiciel, c'est donc un dialecte de Python 3. Cette variante est disponible et compilable sur de nombreuses architectures autres que ARM. Le code source est disponible sur GitHub. En plus de cela, il existe un repo de différentes bibliothèques adaptées pour micro-python. On peut notamment y trouver pip.

Let's roll

C'est bien mignon tout ça, mais qu'en fait-on ? me direz-vous. Pas d'impatience, voici le moment venu du test !

Que la lumière soit

On commence par sortir en boîte :). Notre démonstrateur nous sort sa plus jolie boucle while pour éclairer les LEDs en séquences. Vidéo du résultat ci-dessous avec en prime le code source en arrière plan.

Ce test est l'occasion de découvrir comment on code et déploie. Le processeur cherche successivement sur la micro-SD ou sur la flash un fichier main.py qui sert de point d'entrée au programme. Lors de l'écriture sur la mémoire flash, la LED rouge s'allume et s'éteint à la fin de l'opération. Un petit reboot et le tour est joué. Il est possible de faire de l'inlining assembleur pour optimiser les chemins critiques et un portage de l'API C de Python est disponible. De quoi s'occuper donc.

Moteur, ça tourne

Seconde démo, utilisation d'un servomoteur. Même logique concernant le code et le déploiement. Concrètement, une classe Servo permet de contrôler le servo :

brain = pyb.Servo(1)

On peut ensuite changer l'angle, en degré :

brain.angle(45)
brain.angle(-60)

Consulter l'angle courant :

servo1.angle()
-60

Et aussi changer l'angle en spécifiant un temps de transition, en millisecondes :

servo1.angle(50, 1000)

Dans le contexte de ce test, comment ne pas parler des drones ? Du coup, nous avons évoqué une conférence TED sur les drones agiles et aussi le projet open-source de drone Paparazzi.

Digression

Beaucoup d'effervescence lors de cette rencontre, et donc quelques digressions. Le sujet le plus complet était sans doute l'opposition entre pip et gestionnaire de paquets (celui du système lorsque présent) pour la gestion des bibliothèques.

pip permet d'installer des paquets Python sans gestion complexe de dépendance non python (compilateur C/C++). Couplé avec les environnements virtuels, il résout de nombreux problèmes mais reste avant tout une solution de contournement. Cependant, faire sans peut s'avérer difficile.

L'alternative beaucoup plus stable reste donc l'utilisation du gestionnaire de paquet du système. Hors toutes les bibliothèques Python ne sont pas packagées... Donc, si l'on souhaite rester rigoureux il faudra sans-doute repackager quelques bibliothèques. Il semble que ce soit la stratégie de Reddit.

Les autres projets évoqués :

[Biologeek] Cours IUT Arles

Publié le 2014-10-18 11:00:00

De toute façon, celui qui donne des conseils cherche d’abord à s’éduquer lui-même. Parler à quelqu’un est une manière détournée de se parler à soi. Ne croyez pas que j’aie une triste vision des rapports humains. Certes, je pense que l’autre nous permet d’accéder à notre propre intimité. Mais se comprendre est le meilleur service qu’on puisse rendre à ceux qu’on aime.

Manuel d’écriture et de survie, Martin Page

Je vais donner des cours à partir de lundi à des étudiants de licence à l’IUT d’Arles. Officiellement, il faut que je leur transmette des connaissances en CSS avancées, JavaScript, jQuery et PHP en 6 demi-journées. J’ai lu avec grand intérêt les témoignages de Romy et Rémi à ce sujet et je me pose encore de trop nombreuses questions. Les participants auront un bagage technique assez hétérogène et auront plutôt une culture design que code d’après ce qui m’a été dit.

Je compte utiliser la première matinée pour prendre la température et m’adapter par la suite. Je souhaiterais avoir le déroulé suivant :

  1. Nous sommes le 20 décembre 2014, cette formation s’est déroulée jusqu’à son terme, imaginez 2 scenarios (l’un positif, l’autre négatif) de ce que vous allez dire à la promotion suivante sur ce cours.
  2. Parcours personnel et compétences transmissibles.
  3. Envoyez-moi une URL dont vous êtes fier/heureuse par email.
  4. Vous allez être évalués (malheureusement requis) sur votre coopération, votre curiosité, votre bienveillance et votre énergie.
  5. Faites des groupes de 4/5 personnes. Vous venez d’intégrer une agence et on vous donne le brief suivant : Nous sommes une association de triathlon/autre qui souhaite montrer ses résultats et son ambiance conviviale sur le net. Vous avez 45 minutes et toutes les ressources que vous voulez pour produire quelque chose ensemble.
  6. Présentation et débriefing groupe par groupe. Discussion et corrections pour la fois suivante.
  7. Qui connait ParisWeb ? Qui a participé au hackathon OpenData ce weekend organisé dans les locaux de l’IUT ?
  8. Culture web et apprentissage.
  9. Quelles améliorations pour la prochaine fois ?
  10. Des liens à consulter/comprendre/discuter d’ici le prochain cours : The End of Design As We Know It, High-level advice and guidelines for writing sane, manageable, scalable CSS, Designer’s guide to DPI, Responsive Web Design Tips, La méthode Daisy, Solved by Flexbox, jQuery, c’est bien, le DOM moderne, c’est mieux !, les vôtres ?

Je vais essayer d’être rigoureux au sujet de mes retours sur cette nouvelle expérience pour les publier ici tout au long du processus. Les commentaires sont évidemment bienvenus.

[logilab] Using Saltstack to limit impact of Poodle SSLv3 vulnerability

Publié le 2014-10-15 13:01:00

Here at Logilab, we're big fans of SaltStack automation. As seen with Heartbleed, controlling your infrastructure and being able to fix your servers in a matter of a few commands as documented in this blog post. Same applies to Shellshock more recently with this blog post.

Yesterday we got the news that a big vulnerability on SSL was going to be released. Code name : Poodle. This morning we got the details and started working on a fix through salt.

So far, we've handled configuration changes and services restart for apache, nginx, postfix and user configuration for iceweasel (debian's firefox) and chromium (adapting to firefox and chrome should be a breeze). Some credit goes to mtpettyp for his answer on askubuntu.

http://www.logilab.org/file/267853/raw/saltstack_poodlebleed.jpg
{% if salt['pkg.version']('apache2') %}
poodle apache server restart:
    service.running:
        - name: apache2
  {% for foundfile in salt['cmd.run']('rgrep -m 1 SSLProtocol /etc/apache*').split('\n') %}
    {% if 'No such file' not in foundfile and 'bak' not in foundfile and foundfile.strip() != ''%}
poodle {{ foundfile.split(':')[0] }}:
    file.replace:
        - name : {{ foundfile.split(':')[0] }}
        - pattern: "SSLProtocol all -SSLv2[ ]*$"
        - repl: "SSLProtocol all -SSLv2 -SSLv3"
        - backup: False
        - show_changes: True
        - watch_in:
            service: apache2
    {% endif %}
  {% endfor %}
{% endif %}

{% if salt['pkg.version']('nginx') %}
poodle nginx server restart:
    service.running:
        - name: nginx
  {% for foundfile in salt['cmd.run']('rgrep -m 1 ssl_protocols /etc/nginx/*').split('\n') %}
    {% if 'No such file' not in foundfile and 'bak' not in foundfile and foundfile.strip() != ''%}
poodle {{ foundfile.split(':')[0] }}:
    file.replace:
        - name : {{ foundfile.split(':')[0] }}
        - pattern: "ssl_protocols .*$"
        - repl: "ssl_protocols TLSv1 TLSv1.1 TLSv1.2;"
        - show_changes: True
        - watch_in:
            service: nginx
    {% endif %}
  {% endfor %}
{% endif %}

{% if salt['pkg.version']('postfix') %}
poodle postfix server restart:
    service.running:
        - name: postfix
poodle /etc/postfix/main.cf:
{% if 'main.cf' in salt['cmd.run']('grep smtpd_tls_mandatory_protocols /etc/postfix/main.cf') %}
    file.replace:
        - pattern: "smtpd_tls_mandatory_protocols=.*"
        - repl: "smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3"
{% else %}
    file.append:
        - text: |
            # poodle fix
            smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
{% endif %}
        - name: /etc/postfix/main.cf
        - watch_in:
            service: postfix
{% endif %}

{% if salt['pkg.version']('chromium') %}
/usr/share/applications/chromium.desktop:
    file.replace:
        - pattern: Exec=/usr/bin/chromium %U
        - repl: Exec=/usr/bin/chromium --ssl-version-min=tls1 %U
{% endif %}

{% if salt['pkg.version']('iceweasel') %}
/etc/iceweasel/pref/poodle.js:
    file.managed:
        - text : pref("security.tls.version.min", "1")
{% endif %}

The code is also published as a gist on github. Feel free to comment and fork the gist. There is room for improvement, and don't forget that by disabling SSLv3 you might prevent some users with "legacy" browsers from accessing your services.

[cubicweb] Exploring the datafeed API in CubicWeb

Publié le 2014-10-14 14:50:00

The datafeed API is one of the nice features of the CubicWeb framework. It makes it possible to easily build such things as a news aggregator (or even a semantic news feed reader), a LDAP importer or an application importing data from another web platform. The underlying API is quite flexible and powerful. Yet, the documentation being quite thin, it may be hard to find one's way through. In this article, we'll describe the basics of the datafeed API and provide guiding examples.

The datafeed API is essentially built around two things: a CWSource entity and a parser, which is a kind of AppObject.

The CWSource entity defines a list of URL from which to fetch data to be imported in the current CubicWeb instance, it is linked to a parser through its __regid__. So something like the following should be enough to create a usable datafeed source [1].

create_entity('CWSource', name=u'some name', type='datafeed', parser=u'myparser')

The parser is usually a subclass of DataFeedParser (from cubicweb.server.sources.datafeed). It should at least implement the two methods process and before_entity_copy. To make it easier, there are specialized parsers such as DataFeedXMLParser that already define process so that subclasses only have to implement the process_item method.

Overview of the datafeed API

Before going into further details about the actual implementation of a DataFeedParser, it's worth having in mind a few details about the datafeed parsing and import process. This involves various players from the CubicWeb server, namely: a DataFeedSource (from cubicweb.server.sources.datafeed), the Repository and the DataFeedParser.

  • Everything starts from the Repository which loops over its sources and pulls data from each of these (this is done using a looping task which is setup upon repository startup). In the case of datafeed sources, Repository sources are instances of the aforementioned DataFeedSource class [2].
  • The DataFeedSource selects the appropriate parser from the registry and loops on each uri defined in the respective CWSource entity by calling the parser's process method with that uri as argument (methods pull_data and process_urls of DataFeedSource).
  • If the result of the parsing step is successful, the DataFeedSource will call the parser's handle_deletion method, with the URI of the previously imported entities.
  • Then, the import log is formatted and the transaction committed. The DataFeedSource and DataFeedParser are connected to an import_log which feeds the CubicWeb instance with a CWDataImport per data pull. This usually contains the number of created and updated entities along with any error/warning message logged by the parser. All this is visible in a table from the CWSource primary view.

So now, you might wonder what actually happens during the parser's process method call. This method takes an URL from which to fetch data and processes further each piece of data (using a process_item method for instance). For each data-item:

  1. the repository is queried to retrieve or create an entity in the system source: this is done using the extid2entity method;
  2. this extid2entity method essentially needs two pieces of information:
    • a so-called extid, which uniquely identifies an item in the distant source
    • any other information needed to create or update the corresponding entity in the system source (this will be later refered to as the sourceparams)
  3. then, given the (new or existing) entity returned by extid2entity, the parser can perform further postprocessing (for instance, updating any relation on this entity).

In step 1 above, the parser method extid2entity in turns calls the repository method extid2eid given the current source and the extid value. If an entry in the entities table matches with the specified extid, the corresponding eid (identifier in the system source) is returned. Otherwise, a new eid is created. It's worth noting that the created entity (in case the entity is to be created) is not complete with respect to the data model at this point. In order the entity to be completed, the source method before_entity_insertion is called. This is where the aforementioned sourceparams are used. More specifically, on the parser side the before_entity_copy method is called: it usually just updates (using entity.cw_set() for instance) the fetched entity with any relevant information.

Case study: a news feeds parser

Now we'll go through a concrete example to illustrate all those fairly abstract concepts and implement a datafeed parser which can be used to import news feeds. Our parser will create entities of type FeedArticle, which minimal data model would be:

class FeedArticle(EntityType):
    title = String(fulltextindexed=True)
    uri = String(unique=True)
    author = String(fulltextindexed=True)
    content = RichString(fulltextindexed=True, default_format='text/html')

Here we'll reuse the DataFeedXMLParser, not because we have XML data to parse, but because its interface fits well with our purpose, namely: it ships an item-based processing (a process_item method) and it relies on a parse method to fetch raw data. The underlying parsing of the news feed resources will be handled by feedparser.

class FeedParser(DataFeedXMLParser):
    __regid__ = 'newsaggregator.feed-parser'

The parse method is called by process, it should return a list tuples with items information.

def parse(self, url):
    """Delegate to feedparser to retrieve feed items"""
    data = feedparser.parse(url)
    return zip(data.entries)

Then the process_item method takes an individual item (i.e. an entry of the result obtained from feedparser in our case). It essentially defines an extid, here the uri of the feed entry (good candidate for unicity) and calls extid2entity with that extid, the entity type to be created / retrieved and any additional data useful for entity completion passed as keyword arguments. (The process_feed method call just transforms the results obtained from feedparser into a dict suitable for entity creation following the data model described above.)

def process_item(self, entry):
    data = self.process_feed(entry)
    extid = data['uri']
    entity = self.extid2entity(extid, 'FeedArticle', feeddata=data)

The before_entity_copy method is called before the entity is actually created (or updated) in order to give the parser a chance to complete it with any other attribute that could be set from source data (namely feedparser data in our case).

def before_entity_copy(self, entity, sourceparams):
    feeddata = sourceparams['feeddata']
    entity.cw_edited.update(feeddata)

And this is all what's essentially needed for a simple parser. Further details could be found in the news aggregator cube. More sophisticated parsers may use other concepts not described here, such as source mappings.

Testing datafeed parsers

Testing a datafeed parser often involves pulling data from the corresponding datafeed source. Here is a minimal test snippet that illustrates how to retrieve the datafeed source from a CWSource entity and to pull data from it.

with self.admin_access.repo_cnx() as cnx:
    # Assuming one knows the URI of a CWSource.
    rset = cnx.execute('CWSource X WHERE X uri %s' % uri)
    # Retrieve the datafeed source instance.
    dfsource = self.repo.sources_by_eid[rset[0][0]]
    # Make sure it's parser matches the expected.
    self.assertEqual(dfsource.parser_id, '<my-parser-id>')
    # Pull data using an internal connection.
    with self.repo.internal_cnx() as icnx:
        stats = dfsource.pull_data(icnx, force=True, raise_on_error=True)
        icnx.commit()

The resulting stats is a dictionnary containing eids of created and updated entities during the pull. In addition all entities created should have the cw_source relation set to the corresponding CWSource entity.

Notes

[1]

It is possible to add some configuration to the CWSource entity in the form a string of configuration items (one per line). Noteworthy items are:

  • the synchronization-interval;
  • use-cwuri-as-url=no, which avoids using external URL inside the CubicWeb instance (leading to any link on an imported entity to point to the external source URI);
  • delete-entities=[yes,no] which controls if entities not found anymore in the distant source should be deleted from the CubicWeb instance.
[2]The mapping between CWSource entities' type (e.g. "datafeed") and DataFeedSource object is quite unusual as it does not rely on the vreg but uses a specific sources registry (defined in cubicweb.server.SOURCE_TYPES).

[Biologeek] Running LEAN

Publié le 2014-10-11 11:00:00

Je suis en train de refaire le site internet de scopyleft, la coopérative web que j’ai co-créée avec des amis. Je réalise une série d’interviews afin de vérifier si mes premières pistes sur cette refonte sont pertinentes sur le public que je me suis fixé… et dont tu as la chance incroyable de faire partie ! Enfin je crois. Je vais te poser quelques questions pour vérifier cela :

Début d’interview rédigée dans le cadre de TrampoLEAN

J’ai eu la chance d’assister à la première édition de TrampoLEAN (la prochaine session est le 24 octobre à Montpellier) qui consiste à mettre en pratique Running LEAN sur un projet personnel en étant accompagné. Je pense que l’approche est intéressante lorsque l’on souhaite concevoir un produit qui réponde vraiment à des besoins utilisateurs. L’utilisation du Lean Canvas et la réalisation d’interviews en amont même de la première ligne de code permet de pivoter à moindres frais pour maximiser la valeur apportée à la cible choisie. Je vous renvoie à l’excellent billet de Lionel pour plus de précisions sur les motivations de la méthode :

Penser pour l’utilisateur c’est garder le confort de ne pas se confronter à lui. On fait de belles théories, les intervenants du projet trouvent que les idées sont bonnes entre eux, alors que la seule préoccupation est d’avoir la certitude que l’idée est bonne pour l’utilisateur.

Pourquoi Running Lean ?

Le problème que j’ai rencontré lors de sa mise en application est que j’ai choisi un projet bien singulier : la refonte du site de scopyleft. Mon objectif était de tester les limites de l’approche et je pense les avoir atteintes. J’ai l’impression qu’il est très difficile d’avoir une approche artistique au sens large avec Running LEAN. Lorsque l’on reste sur des besoins, c’est très pertinent. Dès que l’on va vers du style et de la personnalité ça l’est beaucoup moins car cela devient propre à chaque individu. Je ne pense pas qu’il soit possible d’écrire un livre ou de réaliser un tableau avec une telle approche car la cible se réduit alors à une seule personne : l’auteur.

Il doit être possible d’identifier ces cas aux limites lors de la recherche des hypothèses à tester, lorsque celles-ci sont trop difficiles à formuler c’est qu’il y a une difficulté à cerner le problème ou que le problème n’est pas résoluble par cette méthode. Dans les deux cas il faut se remettre en question avant de passer aux interviews qui apporteront peu d’intérêt si ce n’est la confirmation que chaque personne est singulière :-).

Mais pourtant un site doit bien répondre à un besoin ? Tout à fait. Mais il repose aussi sur du rédactionnel qui a plus ou moins d’importance. La subtilité réside dans ce curseur entre utilité et personnalité. Dans le cadre du site de scopyleft, je pense que l’on est plus proches de la personnalité. Ou plutôt j’ai envie que l’on reste plus proches de ce que l’on est. Peut-être faudrait-il un nom pour cet écueil dans la méthode : Getting personal ?

Malgré ce relatif échec personnel (earn or learn est notre nouveau motto), la méthode a montré de bons résultats avec les autres participants et sur les projets que l’on accompagne. Il y a vraiment du bon dans cette approche si elle arrive suffisamment en amont des projets, lorsque les porteurs ne se sont pas encore enfermés dans leurs propres certitudes. Ou cherchent un retour sur investissement sur l’énergie déjà déployée et l’argent déjà dépensé sans avoir le recul nécessaire pour lâcher prise et revenir aux bases : le besoin utilisateur.

Au détriment de la satisfaction du porteur ? De l’égo de l’auteur ? Oups.

[Biologeek] Rapatriement d’articles

Publié le 2014-10-10 11:00:00

Link to everything you create elsewhere on the web. And if possible, save a copy of it on your own blog. Things disappear so quickly, and even important work can slip your mind months or years later when you want to recall it. If it’s in one, definitive place, you’ll be glad for it.

15 Lessons from 15 Years of Blogging

J’y pense depuis un moment et il était temps d’être en accord avec les principes énoncés par ailleurs. Je commence à récupérer les articles que j’ai semé un peu partout ces dernières années. Ce n’est pas de la duplication mais de la sauvegarde distribuée ;-).

J’ai procédé au rapatriement des 3 articles/tribunes de FaitMain : semences et données, écologie et données, éduquer et militer. Ainsi que l’initiative scopyleft écrit pour l’ANAS et un Web orienté composants pour le train de 13h37. Bonne lecture !

Note pour plus tard : ne publier que des articles sous une licence permettant la conservation à long terme sur ce site.

[logilab] Petit compte rendu du meetup postgresql d'octobre 2014

Publié le 2014-10-09 17:10:00

Hier soir, je suis allé au Meetup PostgreSQL intitulé "DBA et Développeurs enfin réunis". Après quelques bières et pizza (c'est la tradition de le faire dans ce sens), nous avons écouté 4 présentations autour de PostgreSQL après une courte introduction de Dimitri Fontaine et des sponsors (Mozilla et Novapost).

http://www.logilab.org/file/266939/raw/BzcR8UOIQAAdFMh.jpg

Jean-Gérard Pailloncy nous a parlé d'aggrégation temporelle sous contrainte d'IOPS (page wikipedia pour IOPS, au cas où). Malgré le temps court de présentation, c'était une synthèse très bien déroulée d'un projet avec des flux de données ambitieux pour des plateformes "entrée de gamme". Quelques "petites" astuces que chacun pourrait appliquer à ses projets.

Flavio Henrique Araque Gurgel nous a parlé du partitionnement de tables et des mythes qui entourent ce sujet. Dans quels cas dois-je partionner ? Beaucoup de cas de figure sont possibles, les métriques qui permettent de prendre ce genre de décisions sont nombreuses et nécessitent une bonne compréhension du fonctionnement interne des bases de données Postgresql. Il s'agissait principalement d'amener les praticiens de postgresql à se poser les bonnes questions lors de la conception de leur base de données.

Thomas Reiss et Julien Rouhaud nous ont présenté POWA (PostgreSQL Workload Analyzer). Il s'agit d'une extension C pour postgresql (à partir de 9.3) et une interface en Perl and Mojolicious. Un projet prometteur (bien que l'on puisse être supris qu'il soit écrit en Perl) pour maîtriser les performances de sa base de données postgresql.

http://www.logilab.org/file/266940/raw/safe.png

Enfin, Dimitri Fontaine a prêché la bonne parole pour rapprocher les développeurs des administrateurs de bases de données. L'idée était de faire penser aux développeurs que le SQL dans leur code est du code, pas juste des chaînes de caractères. Quelques exemples autour des "window functions" et de "common table expressions" plus tard, on espère que les développeurs feront une partie de leurs calculs directement dans PostgreSQL plutôt que dans leur application (en évitant de balader des tonnes de données entre les deux). Petit conseil : il est recommandé de rajouter des commentaires dans les requêtes SQL. "SQL c'est un language de programmation en vrai."

Les slides devraient être publiés sous peu sur le groupe meetup, que vous pouvez rejoindre pour être informés du prochain meetup.

À Logilab nous utilisons beaucoup Postgresql que ce soit sur des projets clients (données métier, GIS, etc.) mais aussi extensivement dans CubicWeb, framework web en python orienté web sémantique.

Le format de 20 minutes par présentation est pas mal pour toucher rapidement à un grand nombre de sujets, du coup souvent il s'agit de pistes que chacun doit ensuite explorer. Les meetups sont toujours aussi sympathiques et accueillants.

[tarek] New Blog: Foule.es

Publié le 2014-10-08 21:09:00

Dear French reader. I have just launched a new blog in French about running.

=> http://foule.es <=

It'll probably talk about writing software from time to time, but it's basically about running.

[Biologeek] Triathlon

Publié le 2014-10-05 11:00:00

Ils y sont donc surmontés par le Triathlon, synthèse idéale, trinité dont la perfection tend vers le divin, et dont les trois disciplines consubstantielles épousent parfaitement les trois cotés du triangle sacré formant le sommet de la Grande Pyramide. Car si à l’image des Vrais Sports, le Triathlon forge de par son exigence un mental d’acier pour ses pratiquants les plus aguerris, il est également le seul sport qui réussit à réconcilier et synthétiser les exigences et idiosyncrasies antagonistes des trois Vrais Sports majeurs, nous faisant tendre vers le modèle de l’Athlète Idéal, celui de l’Honnête homme, idéal de modération et d’équilibre dans l’usage de toutes ses facultés, aux proportions harmonieuses et exemptes d’excès. Ultime satisfaction, l’exigence extrême de ce sport garantit sa relative confidentialité, ce qui le sauve, en éloignant irrémédiablement le spectre de l’argent facile, et en garantissant une pratique noble et désintéressée, pour le pur goût de l’effort, et dans le mépris des valeurs matérielles inhérentes à ce siècle.

La pyramide des sports

Les copines de boulot vont faire un triathlon, t’es motivé ? Mmh, pourquoi pas. A priori rien ne m’attire dans cet univers : esprit de compétition, culte de soi et atteinte de ses limites. Mais il y a tout de même des côtés à creuser : expérimentations au niveau matériel, sports complémentaires et gestion de l’effort. Challenge accepté. Me voilà embarqué dans la préparation d’un triathlon en 2 mois sans savoir nager le crawl… mais avec une petite base en trail et quelques tours occasionnels en vélo.

Après tout le mal que j’avais lu des triathlètes, il fallait que je me fasse mon propre avis :-)

Tatoué, pucé, étiquetté, on se retrouve dans un parc à vélos tous plus affûtés les uns que les autres (je parle des vélos bien entendu). L’ambiance est plutôt tendue mais la sono à fond permet de faire le vide en enfilant la combinaison qui doit m’aider à ne pas me noyer. Je laisse partir les hors-bords et je me jette doucement à l’eau avec une brasse sacrément lente, conséquence des 6 petites séances en piscine (finalement cette combi me freine plus qu’autre chose !). Je n’ai pas fait 100m que je sens déjà la puce accrochée à ma cheville qui se fait la malle — oups — demi-tour pour finalement l’accrocher au poignet et me rendre compte qu’il n’y a plus grand monde derrière moi :-D

Arrivé enfin sur la plage, je m’extirpe tant bien que mal de la combinaison avant de me rendre compte que je ne suis pas devant mon vélo — re-oups — changement de rangée et je perds 30 sec à enfiler des chaussettes avec les pieds mouillés. J’enfourche mon vélo pour 10 kilomètres de montée qui n’en finissent pas. Toute la difficulté est de ne pas rester dans le rythme imposé pour remonter les nombreuses places perdues lors de la natation. J’y arrive tant bien que mal mais je suis surpris par la longueur, j’aurais mieux fait de repérer un brin le parcours avant… ou d’emporter un compteur mais calculer c’est tricher™. C’est parti pour la descente où je force autant que faire se peut en oubliant de m’hydrater. Je prends pas mal de plaisir à enchaîner les virages avec vue sur le lac lorsque je ne baisse pas la tête dans le guidon pour ressembler à un coureur. J’essaye de rester dans ma course malgré les motos, les voitures, les drones, les accidents, les fausses indications des spectateurs, etc. J’ai les épaules qui tétanisent un peu à force d’être crispé sur la guidoline mais je sais que je n’en aurais pas besoin pour la suite.

La transition vers la course est celle que j’appréhendais le plus mais elle se passe finalement mieux que prévu et je continue à jouer à pacman avec les coureurs me précédant. Je me rends compte que j’arrive au niveau d’une des amies faisant le triathlon avec moi, génial on va pouvoir finir ensemble ! J’essaye d’être moteur le kilomètre suivant et c’est là où ça se gâte, je sens le muscle de ma cuisse droite qui se contracte un peu trop dans les montée et il reste un escalier… [J’apprendrais un peu trop tard que les guidons de triathlètes qui permettent de poser les coudes servent justement à éviter ce genre de crampes.] Je monte avec peine mais j’arrive quand même à reprendre la course et à finir à bonne allure en duo \o/\o/ 1h45 d’effort pour un objectif à moins de 2h, plutôt content.

Au final, c’est une expérience bien différente des challenges que j’ai pu m’imposer par le passé. L’univers de la compétition n’est définitivement pas fait pour moi mais ça reste intéressant en termes de logistique. À refaire. Peut-être. Ou pas. Je préfère quand même de loin me retrouver seul ou en petit comité pour me faire plaisir. Et les triathlètes ? Ils ont l’air de trouver ça marrant sans faire trop de dégâts. À part peut-être dans leur livret A. Pourquoi pas après tout.

Il va vraiment falloir que j’écrive ce billet sur les pyramides.

[hautefeuille] Yify-pop dans un conteneur Docker

Publié le 2014-10-03 16:32:00

L’objectif de ce billet est de constituer un fichier Docker qui va construire un conteneur basé sur une Ubuntu 14.04, installer le logiciel Yify-pop et démarrer le serveur Nodejs. Il est nécessaire d’être déjà aguerri avec les commandes Docker.

Création du fichier Docker

On indique dans ce fichier Docker les actions suivantes :

  • On se base sur une image Ubuntu 14.04,
  • On met à jour la liste des paquets,
  • On met à jour le système,
  • On installe les paquets Nodejs,
  • On télécharge le logiciel Yify-pop,
  • On compile le logiciel,
  • On démarre le démon,
  • On expose les ports 4000 et 8889 de l’application.

Contenu du fichier yifydock :

FROM ubuntu:14.04
MAINTAINER Julien Hautefeuille <julien@hautefeuille.eu>
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get -y install npm
RUN apt-get -y install git
RUN cd /opt && git clone https://github.com/yify-pop/yify-pop.git
RUN npm -g install geddy
RUN npm -g install peerflix
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN cd /opt/yify-pop && npm install && geddy
EXPOSE 4000 8889

Construction de l’image

Lancer la commande de build :

docker build -t jhautefeuille/yify-pop:v1 https://raw.githubusercontent.com/jhautefeuille/dockerfiles/master/yify-pop/yifydock

Cette commande va construire le conteneur et le lancer.

Lancement du conteneur Yify-pop

Pour lancer l’application Yify-pop :

docker run -d --publish 4000:4000 --publish 8889:8889 jhautefeuille/yify-pop:v1

[afpyro] AFPyro à Mons (BE) - le 2 Octobre

Publié le 2014-10-02 00:00:00

English version at the end of this page.

Amis Pythonistes, notez la date du prochain AFPyro (et venez-y) !

Le prochain Apero Python Belgium se tiendra le jeudi 2 Octobre à Mons, lors de la Quizaine Numérique de Mons, du 27 septembre au 19 octobre.

En plus des habitués de l’AFPyro, nous accueillerons des débutants en Python afin de leur présenter la puissance du langage.

Vous pourrez ainsi participer à un des deux workshops proposés en parallèle :

  1. Pour les Pythonistes débutants, un workshop pour apprendre les bases de Python, puis pour construire une application Web avec Flask.

2. Pour les développeurs avancés, une initiation à AsyncIO, suivie d’un exemple concret d’une API REST/JSON asynchrone avec AsyncIO, aiohttp, aiorest et aiopg. Enfin, un benchmark sera réalisé afin de comparer les performances avec une API REST/JSON synchrone en Flask.

N’oubliez pas de prendre votre ordinateur portable si vous voulez participer au workshop.

Bien entendu (car c’est dans le nom), un apéro sera également organisé pendant l’événement.

Rendez-vous à partir de 18h30, à Co-nnexion, Espace de Coworking, 2b Rue des Archers, 7000 Mons.

Toutes les infos des prochains AFPyros en Belgique : Aperos Python Belgium


Dear Pythonista friends, write down in your agenda the date of the next AFPyro (and come to it) !

The next Aperos Python Belgium will take place on Thursday, October 2nd in Mons, during the Quizaine Numérique de Mons.

Not only the regulars of AFPyro are welcome. We are also pleased to meet the beginners who want learn Python.

Two workshops will be available:

  1. For the Python beginners, a workshop to learn Python basic, then to build a Web application with Flask.

2. For the advanced developers, a workshop around AsyncIO with a REST/JSON API example with AsyncIO, aiohttp, aiorest et aiopg. Finally, a benchmark will be made to compare performances with a synchronous REST/JSON API with Flask.

Don’t forget your laptop if you want to take part of a workshop.

Of course (it’s in the name), an “apéro” will be also organized throughout the event.

Meeting as from 18:30, at Co-nnexion, Espace de Coworking, 2b Rue des Archers, 7000 Mons.

Further informations about the next AFPyros in Belgium: Aperos Python Belgium

[hautefeuille] RaspberryPI, NAS Synology et NFS

Publié le 2014-10-01 15:13:00

Introduction

L’objectif de ce billet est d’installer le système de fichiers Raspbian sur un répertoire partagé d’un NAS Synology par l’intermédiaire du protocole NFS.

Cette installation permet de soulager la carte mémoire. Celle-ci n’est en fait nécessaire que pour le démarrage de la carte RaspberryPI.

Prérequis

Il faut disposer d’une carte mémoire avec le système Raspbian déjà installé et configuré. Internet regorge de tutoriels sur l’installation de Raspbian.

L’adresse ip du serveur NAS est 192.168.0.3, l’adresse ip de la carte RaspberryPI est 192.168.0.199.

Il faut disposer d’un réseau local rapide car les fichiers du sytème de la RaspberryPI transiteront par le réseau.

J’ai également pu remarquer des problèmes de connection NFS lorsqu’une MTU trop élevée était utilisée.

Je n’utilise donc pas les “Jumbo frame” dans la configuration réseau du NAS Synology.

MTU

Préparation du NAS Synology

On crée tout d’abord un répertoire partagé.

share

On autorise ensuite le partage par NFS, sans mapping, en lecture / écriture. Le dossier exporté par NFS est donc le suivant : /volume1/rasp0.

share

192.168.0.199 correspond à l’adresse ip de la carte RaspberryPI.

Préparation de la carte mémoire

Dans un premier temps, nous allons monter le partage réseau NFS sur la carte RaspberryPI puis nous allons copier le système de fichiers sur cet emplacement réseau.

sudo mount -t nfs -o rw 192.168.0.3:/volume1/rasp0 /mnt
cp -axv /. /mnt/.
cp -axv /dev/. /mnt/dev/.

Préparation des fichiers du partage réseau

On édite ensuite le fstab du partage réseau auquel on ôte le point de montage de la carte mémoire, ici il s’agit de /dev/mmcblk0p2.

proc            /proc           proc    defaults 0 0
/dev/mmcblk0p1  /boot           vfat    defaults 0 0
none            /tmp            tmpfs   defaults 0 0
none            /var/run        tmpfs   defaults 0 0
none            /var/lock       tmpfs   defaults 0 0
none            /var/tmp        tmpfs   defaults 0 0
192.168.0.3:/volume1/rasp0  /   nfs     rw       0 0

La dernière ligne de la configuration est facultative puisqu’on va renseigner également cette information dans le fichier de boot dans la suite de ce billet.

On édite le fichier /etc/network/interfaces du partage réseau pour y désactiver toute référence à du DHCP.

#iface eth0 inet dhcp

Préparation de la séquence de boot (fichier sur la carte mémoire)

On édite le fichier de la carte mémoire /boot/cmdline.txt.

On y ajoute des informations complémentaires sur la même ligne que la ligne d’origine. Si vous êtes en DHCP, mettez ip=dhcp.

root=/dev/nfs rootfstype=nfs nfsroot=192.168.0.3:/volume1/rasp0,udp,vers=3 smsc95xx.turbo_mode=N ip=192.168.0.199:192.168.0.3:192.168.0.1:255.255.255.0
  • 192.168.0.199 est l’adresse de la carte RaspberryPI,
  • 192.168.0.3 est l’adresse du NAS Synology avec le partage NFS,
  • 192.168.0.1 est l’adresse de la passerelle,
  • 255.255.255.0 est le masque réseau.

Vous pouvez enfin rebooter la carte RaspberryPI.

Optimisations

Enfin pour soulager la carte mémoire, nous allons bouger la swap de la carte mémoire vers un loop device à travers le réseau.

sudo apt-get remove --purge dphys-swapfile
sudo rm /var/swap
sudo rm /etc/init.d/dphys-swapfile
sudo update-rc.d dphys-swapfile remove

sudo dd if=/dev/zero of=/var/swap bs=1M count=1024
sudo losetup /dev/loop0 /var/swap
sudo mkswap /dev/loop0
sudo swapon /dev/loop0

On édite ensuite /etc/rc.local du partage réseau pour y rendre les changements permanents.

echo "swap settings"
sleep 2
losetup /dev/loop0 /var/swap
mkswap /dev/loop0
swapon /dev/loop0

Liens

[anybox] Python comme langage d'intégration universel

Publié le 2014-10-01 01:00:00

[anybox] Sphinx autodoc et modules OpenERP

Publié le 2014-10-01 01:00:00
Guide d'intégration complète d'OpenERP et Sphinx, pour les utilisateurs de buildout.

[Biologeek] 10 ans

Publié le 2014-09-30 11:00:00

C’est difficile à décrire la naissance d’un site, ce qu’on voulait faire, ce que l’on a finalement fait, les doutes, les satisfactions, l’incompréhension de certains, les encouragement d’autres, parfois les mêmes d’ailleurs (normal c’était une surprise). Et le résultat est là, sous vos yeux ébahis : merci à vous, visiteur !

Ouverture de rideau, 30 septembre 2004

Dix années de présence, plus ou moins régulière, plus ou moins pérenne. C’est passé par de la bio-informatique, la création d’ubuntu-fr, la découverte de Python, des réflexions sur la liberté, des essais en CSS, des billets personnels, de l’énergie avec django-fr, des coups de gueule, le grand saut en freelance, quelques photos, un peu de sport, du web sémantique, le montage d’événements, une année au Japon, la co-création de scopyleft, de la philo de comptoir et enfin la paternité. Plein de projets avortés, pas mal de discussions stériles, des rencontres toujours un peu spéciales, des rides numériques partagées. Dix années à tisser ma propre toile. Des liens sans intentions, par affinités au hasard des rencontres. Une audience suffisamment limitée pour ne pas prendre la grosse tête ou être dérangé dans mon intimité.

Cet espace de publication m’aura tout appris de mon métier : l’importance des données et de leurs liens. Je l’ai appris dans la douleur : le design a changé 6 fois, les URLs 5 fois, les données 4 fois, le nom de domaine 1 fois. Ce lieu m’a permis d’expérimenter et de prendre du plaisir à ça, d’être corrigé et de capitaliser itérativement. J’ai offert un cadeau à mes écrits dernièrement en utilisant les polices Fira Sans et Equity afin de vous préserver des mouchards d’Adobe/Typekit (et le gain niveau performances est impressionnant). J’ai d’ailleurs rafraichit un peu tout ça, en utilisant TinyTypo et LESS. Je voulais notamment mettre en avant les citations qui débutent les billets, ça reste très minimaliste pour l’instant et il reste les finitions.

Et pour ces 10 prochaines années ? Peut-être du son, peut-être de la vidéo, peut-être du papier, peut-être la page blanche. J’espère avoir toujours de l’énergie pour explorer et partager de nouveaux centres d’intérêts. Avec vous ?

[logilab] Lancement du blog de la communauté salt francaise

Publié le 2014-09-25 16:14:00

La communauté salt est bien vivante. Suite au meetup de septembre, elle s'est doté d'un petit site web :

http://salt-fr.afpy.org
http://www.logilab.org/file/266455/raw/Screenshot%20from%202014-09-25%2014%3A32%3A27.png

Nous éspérons pouvoir continuer à rassembler les enthousiasmes autour de salt lors de ces rendez-vous tous les 2 mois. J'ai donc publié le compte rendu du meetup sur ce site.

[afpyro] AFPyro à Lyon - mercredi 24 septembre

Publié le 2014-09-24 00:00:00

Un Afpyro aura lieu le mercredi 24 septembre à partir de 19h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Une présentation sur les docstrings sera donnée au cours de cette soirée.

L’Antre Autre est un lieu où nous pouvons discuter autour d’un verre, et, pour ceux qui le souhaitent, prendre un repas.

Pour se rendre à l’Antre Autre :

  • en métro : arrêt Hôtel de Ville
  • en bus : lignes C13 et C18 arrêt Mairie du 1er ou lignes 19, C14 et C3 à l’arrêt Terreaux
  • en vélo’v : stations Place Sathonay, Carmélites Burdeau, Place de la paix

[AFPy Salt-fr] Rencontres Salt à Mozilla Paris

Publié le 2014-09-22 22:00:00

Pour ce 4ème meetup parisien des utilisateurs de Salt, nous étions acceuilli dans le luxe des locaux de Mozilla Paris, merci à eux!

Pour la partie du public qui découvrait salt, Arthur Lutz de Logilab a fait une introduction à Salt.

Arthur Lutz

Cyril Lavier nous à présenté l'utilisation de Salt chez Webedia. Voici les slides : /presentations/webedia-salt.pdf.

Cyril Lavier

Paul Tonelli nous a présenté une utilisation de la mine salt pour gérer des fichier de zone automatiquement avec salt. Voici les slides: http://docs.logilab.org/salt_dns/

Feth Arezki de Majerti a présenté samba_report_module qui produit du json utilisé par le projet samba_report_html.

Feth Arezki

Nicolas Pierron nous a montré une autre facon de penser la gestion de configuration en nous présentant la distribution linux NixOS.

Nicolas Pierron

Forcément, nous avons fini la soirée autour d'une pizza payée par Logilab et quelques boissons fournies par Mozilla. Merci à eux !

Pizza!

Pour les prochains meetups n'oubliez pas le document collaboratif d'organisation sur lequel vous pouvez faire des propositions de présentations. Vous pouvez aussi voter pour la date du meetup de novembre 2014.

[AFPy Salt-fr] Annonce : Meetup Salt Paris - Septembre 2014

Publié le 2014-09-18 22:00:00

Voici notre petit sélection pour démarrer notre meetup de la semaine prochaine (mardi 23 septembre 2014 à 19h dans les locaux de de Mozilla Paris) :

  • Retour d’expérience déploiement Salt chez Webedia (Cyril Lavier - Webedia)
  • Génération de fichiers de zone internes par salt (Paul Tonelli - Logilab)
  • Construire du monitoring de serveurs avec Salt et du HTML/javascript (Feth Arezki - Majerti)

Si un certain nombre de personnes de l'assistance ne connaissent pas Salt, on pourra se charger d'une petite introduction (avec des vieux slides).

N'oubliez pas de vous inscrire sur http://framadate.org/u85rt2y3iz1krhys c'est important car Mozilla a besoin d'un nombre d'inscrits pour des questions de sécurité (et pour offrir à boire).

Pour rappel les locaux de Mozilla Paris c'est au :

16 Bis Blvd. Montmartre Paris 75009 France

[cubicweb] Handling dependencies between form fields in CubicWeb

Publié le 2014-09-17 15:50:00

This post considers the issue of building an edition form of a CubicWeb entity with dependencies on its fields. It's a quite common issue that needs to be handled client-side, based on user interaction.

Consider the following example schema:

from yams.buildobjs import EntityType, RelationDefinition, String, SubjectRelation
from cubicweb.schema import RQLConstraint

_ = unicode

class Country(EntityType):
    name = String(required=True)

class City(EntityType):
    name = String(required=True)

class in_country(RelationDefinition):
    subject = 'City'
    object = 'Country'
    cardinality = '1*'

class Citizen(EntityType):
    name = String(required=True)
    country = SubjectRelation('Country', cardinality='1*',
                              description=_('country the citizen lives in'))
    city = SubjectRelation('City', cardinality='1*',
                           constraints=[
                               RQLConstraint('S country C, O in_country C')],
                           description=_('city the citizen lives in'))

The main entity of interest is Citizen which has two relation definitions towards Country and City. Then, a City is bound to a Country through the in_country relation definition.

In the automatic edition form of Citizen entities, we would like to restrict the choices of cities depending on the selected Country, to be determined from the value of the country field. (In other words, we'd like the constraint on city relation defined above to be fulfilled during form rendering, not just validation.) Typically, in the image below, cities not in Italy should be available in the city select widget:

Example of Citizen entity edition form.

The issue will be solved by little customization of the automatic entity form, some uicfg rules and a bit of Javascript. In the following, the country field will be referred to as the master field whereas the city field as the dependent field.

So here the code of the views.py module:

from cubicweb.predicates import is_instance
from cubicweb.web.views import autoform, uicfg
from cubicweb.uilib import js

_ = unicode


class CitizenAutoForm(autoform.AutomaticEntityForm):
    """Citizen autoform handling dependencies between Country/City form fields
    """
    __select__ = is_instance('Citizen')

    needs_js = autoform.AutomaticEntityForm.needs_js + ('cubes.demo.js', )

    def render(self, *args, **kwargs):
        master_domid = self.field_by_name('country', 'subject').dom_id(self)
        dependent_domid = self.field_by_name('city', 'subject').dom_id(self)
        self._cw.add_onload(js.cw.cubes.demo.initDependentFormField(
            master_domid, dependent_domid))
        super(CitizenAutoForm, self).render(*args, **kwargs)


def city_choice(form, field):
    """Vocabulary function grouping city choices by country."""
    req = form._cw
    vocab = [(req._('<unspecified>'), '')]
    for eid, name in req.execute('Any X,N WHERE X is Country, X name N'):
        rset = req.execute('Any N,E ORDERBY N WHERE'
                           ' X name N, X eid E, X in_country C, C eid %(c)s',
                           {'c': eid})
        if rset:
            # 'optgroup' tag.
            oattrs = {'id': 'country_%s' % eid}
            vocab.append((name, None, oattrs))
            for label, value in rset.rows:
                # 'option' tag.
                vocab.append((label, str(value)))
    return vocab


uicfg.autoform_field_kwargs.tag_subject_of(('Citizen', 'city', '*'),
                                           {'choices': city_choice, 'sort': False})

The first thing (reading from the bottom of the file) is that we've added a choices function on city relation of the Citizen automatic entity form via uicfg. This function city_choice essentially generates the HTML content of the field value by grouping available cities by respective country through the addition of some optgroup tags.

Then, we've overridden the automatic entity form for Citizen entity type by essentially calling a piece of Javascript code fed with the DOM ids of the master and dependent fields. Fields are retrieved by their name (field_by_name method) and respective id using the dom_id method.

Now the Javascript part of the picture:

cw.cubes.demo = {
    // Initialize the dependent form field select and bind update event on
    // change on the master select.
    initDependentFormField: function(masterSelectId,
                                     dependentSelectId) {
        var masterSelect = cw.jqNode(masterSelectId);
        cw.cubes.demo.updateDependentFormField(masterSelect, dependentSelectId);
        masterSelect.change(function(){
            cw.cubes.demo.updateDependentFormField(this, dependentSelectId);
        });
    },

    // Update the dependent form field select.
    updateDependentFormField: function(masterSelect,
                                       dependentSelectId) {
        // Clear previously selected value.
        var dependentSelect = cw.jqNode(dependentSelectId);
        $(dependentSelect).val('');
        // Hide all optgroups.
        $(dependentSelect).find('optgroup').hide();
        // But the one corresponding to the master select.
        $('#country_' + $(masterSelect).val()).show();
    }
}

It consists of two functions. The initDependentFormField is called during form rendering and it essentially bind the second function updateDependentFormField to the change event of the master select field. The latter "update" function retrieves the dependent select field, hides all optgroup nodes (i.e. the whole content of the select widget) and then only shows dependent options that match with selected master option, identified by a custom country_<eid> set by the vocabulary function above.

[AFPy-Nantes] Un barcamp pour bien terminer l'été indien

Publié le 2014-09-14 22:00:00

Suite au succès du dernier meetup, et pour bien finir ce mois de septembre ensoleillé, nous sommes heureux de vous proposer un nouveau BarCamp, le mardi 30 septembre, 19 heure, à la Cantine numérique Nantaise.

Le concept sera de se retrouver autour de plusieurs ateliers, et de participer collectivement, chacun étant invité à présenter ses trouvailles, à poser ses questions, etc.

Que vous soyez pythoniste confirmé, ou simple curieux, le format du barcamp devrait donc répondre à vos attentes : la découverte, l'échange, le collaboratif.

Comme d'habitude, ceux qui le souhaitent pourront prolonger l'évènement autour d'un verre.

Pour vous inscrire à l'évènement, cliquez ici.

Pour vous tenir informé du contenu exact de l'évènement, ou pour faire part de vos suggestions, n'hésitez pas à vous inscrire à la liste de diffusion des pythonistes nantais.

Vous pouvez aussi nous rejoindre sur le chan IRC de l'AFPy Nantes. :)

[tarek] The Perfect Running App

Publié le 2014-09-14 17:05:00

Note

Most running applications out there are good enough for casual runners. This blog post is my tentative to describe what I would like to see in a running app for more serious practice.

I used a few running applications to track all my runs. Mostly the Nike+ app since this what naturally came with my Nike+ watch before I switched to a Garmin Forerunner 310XT.

Changing watch

From Nike+ to Garmin...

The app was a bit frustrating for many reasons and I thought that was because it's made for beginners, and that I was not the typical user anymore. I was not really interested in the provided metrics and was looking for better things.

When I switched to my new watch I though the app would be as good as the hardware. But no. What came as a surprise is that all the applications I have tried or looked at are not really better than Nike+. It looks like they are all aiming at casual runners.

But when you buy a expensive watch and do 5 trainings per week, you have some expectations.

I still wonder how come we don't have something better in a domain where anyone can understand the basics of what a good training session should be, by reading 2 or 3 running magazines. Unless you are doing crazy elite training with a whole staff, it's not rocket science.

And in my running club, even the very experienced runners use one of these apps and get frustrated. But it seems that no one expects these apps to be better than they are right now. The general consensus around me is: you can analyze your runs manually, the watch and its software will just help you get the raw data.

This is not good enough for me. I am very frustrated. I want to see if I am making any progress by using months of data - and this is not easy to do by hand.

SmashRun looks like a promising app but still misses a lot of what I am looking for. Since it's built by runners who seem passionate about building the right stuff, I got a pro account to encourage them. They have a voting system for new features, people that have a pro account can use.

However, I would like to write down in this blog post what I am exactly looking for and what I despise in a running app.

Of course this is what I want - but I am pretty sure that most seasoned runners would want something similar. Maybe it exists ? You should let me know.

Stop comparing Apples and Oranges

I think this is the worst feature all running apps have: they will tell you your average pace and your "progression". Some of them try to take a coach-like tone and tell you stuff like:

You're getting slow!

Jeez. Of course I am getting slow. I ran an interval run yesterday with a specific pace of 3'40/km and today I am doing a long run at a very slow pace because this is how you train !

pace over the week

Yeah the pace varies during the week. Nothing I can do with this chart here.

Global metrics that use all your recorded runs have no sense

You can't do this. That does not mean anything. Knowing that my yearly average pace is 4'45 does not mean anything.

You can't either really know what will be my estimate finish on a 5k using one of my long runs.

Performance Index

My estimated 5k finish time based on one long run. Of course it's completely wrong.

Also, the volume of trainings and kilometers you do really depends on what you're aiming at. Someone that is getting ready for a marathon will do at least 60km/week, and will take it easy the last week.

That would be a non-sense if you are getting ready for a 5k - But in most apps, the runner that prepares for the marathon will appear like a killer compared to the 5k runner. Tell this to the runners that are doing 16' on a 5k...

Gold Medal

I will soon lose my Gold medal since my 5 weeks training plan is over.

Anyways. My point is that the software should be smarter there. Every run needs to be classified in very specific groups to have any useful metrics on it. The most important ones are:

  • long runs
  • short interval runs
  • long interval runs
  • races

Long Runs

A long run is basically running at a lower pace for a longer time than usual. If you are getting ready for a 10k, you usually have one or two long runs per week, that will last for 1h to 1h30 tops.

The goal of those runs is to try to keep the same steady heart rate, and usually if the place where you are running is flat enough, the same pace.

A long run look like this:

Long run

The red zone is the HR drift.

There are several interesting things in this chart: you don't usually warmup when you do long runs. So the first portion of the run is a slow raise of your pace and heart rate until you've reached the targeted zone.

The quality of a long run is your ability to stick with the same heart rate for the whole session. Unless you are very careful and slow down a bit over time, there will be a slow, natural increase of your heart reate over time.

The most interesting metric in the case of a long run is to determine how flat your HR is, excluding the warmup section at the beginning.

A possible variation is to add a few strikes in the middle of your long runs. It makes it less boring. For example 2x2mn at 10k speed. It's important that these two strikes don't confuse the software that measures how flat your HR is.

Comparing long runs can be done by looking at;

  • how good you are at keeping the desired HR over time
  • how fast your heart is beating for a given pace as long as the circuit is flat enough and how this evolves over time.

Short Interval Run

If I do a short interval run, this is how things will go:

  • 30' warmup
  • 12x (45" at max speed, 30" slow)
  • 10' to cool down
Long run

The red line is the linear regression of the fast strikes.

We can ditch the warmup. It does not bring any interesting data besides the volume of training. The only interesting thing to do there is to make sure it was long enough. That varies between runners, but for short intervals, it's usually roughly as long as the intervals themselves.

Now for the intervals, a quality metrics is to check if they are all done at the same speed. It's quite common to start the series very fast and to finish slowly, completely burnt by the first strikes. This is not good! A good interval run is done at the same speed for all strikes (both fast and slow segments). A great interval run is done with a slightly faster speed for the last intervals.

A good metrics in this case is the linear regression of the pace for the fast segments then the slow segments. It should be flat or slightly increasing.

The ten last minutes are also very intesting: how fast your heart rate decreases over the ten minutes ? The faster the better.

Comparing interval runs between them can be done by checking how these metrics progress over time.

Long Interval Runs

Long interval runs are like the short ones. The only difference is that you can take into account your HR variation between strikes to see how good you are at decreasing your HR between each strike. A linear regression can be added there.

Race

A Race is a very specific run, and has its specific metrics. Usually, we tend to start too fast with the danger of getting in the red zone in the first kilometers.

This is the perfect 10k run:

Long run

A 10K run with a perfect negative split.

The first 5-6k are down 3-5 seconds slower than your target pace, and the end of the run 3-5 seconds faster. This is called a negative split. The last 500m should be as fast as you can.

So for races, what I want to find out is if I was able to do a negative split, if I did not start too fast and if I was able to sprint to the finish line.

This is also a set of metrics that can be compared from race to race over time.

The Impact of Temperature

I have a friend at the racing club that trained hard for 8 weeks for a marathon. He was aiming at 3h15mn and practiced accordingly. The day the race was there, we had a very unusual heat wave in France - 37ºC which is a lot for my area. He finished the marathon in 3h40 and was happy about his performance!

The bottom line is that the heat or the cold directly impact how we perform - and this varies a lot between individuals. In my dream running app, I want to correlate my results with the temperature.

I want all my predictions to have a ponderation (not sure that's how you say it in english ;)) with the temperature.

The Impact of Rest

How long did you rest since the last run ? How did it impact your performances ?

With this information and how fast your heart slows down after your training, we can detect overtraining and undertraining.

I know Polar has a bit of this in its latest software. It tells you how long you should rest before your next run. I wonder how they calculate this.

The Social Part

Last year I ran in San Franscisco near the bay bridge with my Nike+ watch and when I uploaded my run I was delighted to see that I did a 1 mile segment many people did.

Unfortunately, the only thing the app was able to tell me is that I was 365th in terms of pace and another ridiculous rank in terms of how many runs I did there.

This is so stupid. Where am I getting with this ? Becoming the Running Mayor of the Pier? :)

There's one thing that could be interesting in running apps when comparing your data with other people: group users by ages and by records.

I am 37 and my 10k record is around 38' - I don't really care to know how I perform on a weekly basis compared to an elite runner who does 31', or a more casual runner who does 50'.

What could be interesting though is to compare with people that are at my level or age and that are getting ready for the same race maybe ? or a race that's similar enough and close enough.

Conclusion

This blog post is just a brain dump - some ideas are pretty vague and I have not really talked about the UX of the Running Software.

But the bottom line is that if you don't just jog, and want to use a running application for serious training, what I have described is what I think is needed.

I hope Smashrun will go into that direction!

[cubicweb] CubicWeb roadmap meeting on September 4th, 2014

Publié le 2014-09-08 23:52:00

The Logilab team holds a roadmap meeting every two months to plan its CubicWeb development effort. The previous roadmap meeting was in July 2014.

Here is the report about the September 4th, 2014 meeting. Christophe de Vienne (Unlish) and Dimitri Papadopoulos (CEA) joined us to express their concerns and discuss the future of CubicWeb.

Versions

Version 3.17

This version is stable but old and maintainance will continue only as long as some customers will be willing to pay for it (current is 3.17.16 with 3.17.17 in development).

Version 3.18

This version is stable and maintained (current is 3.18.5 with 3.18.6 in development).

Version 3.19

This version is stable and maintained (current is 3.19.3 with 3.19.4 in development).

Version 3.20

This version is under development. It will try to reduce as much as possible the stock of patches in the state "reviewed", "awaiting review" and "in progress". If you have had something in the works that has not been accepted yet, please ready it for 3.20 and get it merged.

It should still include the work done for CWEP-002 (computed attributes and relations).

For details read list of tickets for CubicWeb 3.20.0.

Version 3.21

Removal of the dbapi, merging of Connection and ClientConnection, CWEP-003 (adding a FROM clause to RQL).

Version 4.0

When the work done for Pyramid will have been tested, it will become the default runner and a lot of things will be dropped: twisted, dead code, ui and core code that would be better cast into cubes, etc.

This version could happen early in 2015.

Cubes

New cubes and libraries

CWEPs

Here is the status of open CubicWeb Evolution Proposals:

CWEP-0002 full-featured implementation, to be merged in 3.20

CWEP-0003 patches sent to the review. . Champion will be adim.

Work in progress

PyConFR

Christophe will try to present at PyConFR the work he did on getting CubicWeb to work with Pyramid.

Pip-friendly source layout

Logilab and Christophe will try to make CubicWeb more pip/virtualenv-friendly. This may involve changing the source layout to include a sub-directory, but the impact on existing devs is expected to be too much and could be delayed to CubicWeb 4.0.

Pyramid

Christophe has made good progress on getting CubicWeb to work with Pyramid and he intends to put it into production real soon now. There is a Pyramid extension named pyramid_cubicweb and a CubicWeb cube named cubicweb-pyramid. Both work with CubicWeb 3.19. Christophe demonstrated using the debug toolbar, authenticating users with Authomatic and starting multiple workers with uWSGI.

Early adopters are now invited to jump in and help harden the code!

Agenda

Logilab's next roadmap meeting will be held at the beginning of november 2014 and Christophe and Dimitri were invited.

[AFPy Salt-fr] Hello World

Publié le 2014-09-08 22:00:00

Hello World.

Les meetups existent depuis XX.

Quelques comptes rendus des éditions précédentes.

[logilab] Report from DebConf14

Publié le 2014-09-05 16:21:00

Last week I attended DebConf14 in Portland, Oregon. As usual the conference was a blur, with lots of talks, lots of new people, and lots of old friends. The organizers tried to do something different this year, with a longer conference (9 days instead of a week) and some dedicated hack time, instead of a pre-DebConf "DebCamp" week. That worked quite well for me, as it meant the schedule was not quite so full with talks, and even though I didn't really get any hacking done, it felt a bit more relaxed and allowed some more hallway track discussions.

http://www.logilab.org/file/264666/raw/Screenshot%20from%202014-09-05%2015%3A09%3A38.png

On the talks side, the keynotes from Zack and Biella provided some interesting thoughts. Some nice progress was made on making package builds reproducible.

I gave two talks: an introduction to salt (odp),

http://www.logilab.org/file/264663/raw/slide2.jpg

and a report on the Debian jessie release progress (pdf).

http://www.logilab.org/file/264665/raw/slide3.jpg

And as usual all talks were streamed live and recorded, and many are already available thanks to the awesome DebConf video team. Also for a change, and because I'm a sucker for punishment, I came back with more stuff to do.

[logilab] Logilab à EuroSciPy 2014

Publié le 2014-09-03 13:02:00
http://www.euroscipy.org/2014/site_media/static/symposion/img/logo.png

Logilab était présent à EuroSciPy2014 à Cambridge la semaine dernière, à la fois pour suivre les travaux de la communauté scientifique, et pour y présenter deux posters.

Performances

Il y a encore beaucoup été question de performances, au travers de tutoriels et de conférences de grande qualité :

  • une Keynote de Steven G. Johnson expliquant comment le langage Julia, de haut niveau et à typage dynamique parvient à atteindre des performances dignes du C et du Fortran dans le domaine numérique : le langage a été conçu pour être compilé efficacement avec un jit (just-in-time compiler) basé sur LLVM , en veillant à rendre possible l'inférence des types du maximum de variables intermédiaires et des retours des fonctions à partir des types d'entrée, connus au moment de leur exécution. L'interfaçage bidirectionnel avec le Python semble très simple et efficace à mettre en place.
  • un tutoriel de Ian Ozswald très bien construit, mettant bien en avant la démarche d'optimisation d'un code en démarrant par le profiling (cf. aussi notre article précédent sur le sujet). Les différentes solutions disponibles sont ensuite analysées, en montrant les avantages et inconvénients de chacune (Cython, Numba, Pythran, Pypy).
  • l'histoire du travail d'optimisation des forêts d'arbres décisionnels (random forests) dans scikit-learn, qui montre à quel point il est important de partir d'une base de code saine et aussi simple que possible avant de chercher à optimiser. Cet algorithme a été entièrement ré-écrit de façon itérative, conduisant au final à l'une des implémentations les plus rapides (sinon la plus rapide), tous langages confondus. Pour parvenir à ce résultat des formulations adroites de différentes parties de l'algorithme ont été utilisées puis optimisées (via Cython, une ré-organisation des données pour améliorer la contiguïté en mémoire et du multi-threading avec libération du GIL notamment).
  • la présentation de Firedrake, un framework de résolution d'équations différentielles par la méthode des éléments finis, qui utilise une partie de FEniCS (son API de description des équations et des éléments finis à utiliser) et la librairie PyOP2 pour assembler en parallèle les matrices et résoudre les systèmes d'équations sur GPU comme sur CPU.
  • la présentation par Jérôme Kieffer et Giannis Ashiotis de l'ESRF de l'optimisation de traitements d'images issues de caméras à rayons X haute résolution débitant 800Mo/s de données en utilisant Cython et du calcul sur GPU.

Autres sujets remarqués

D'autres sujets que je vous laisse découvrir plus en détails sur le site d'EuroSciPy2014 prouvent que la communauté européenne du Python scientifique est dynamique. Parmi eux :

  • un tutoriel très bien fait d'Olivier Grisel et Gaël Varoquaux sur l'analyse prédictive avec scikit-learn et Pandas.
  • une belle présentation de Gijs Molenaar qui a créé une belle application web pour présenter les données d'imagerie radioastronomiques issues du LOFAR.
  • enfin, Thomas Kluyver et Matthias Bussonnier nous ont notamment parlé du projet Jupyter qui permet d'utiliser le notebook IPython avec des noyaux non Python, dont Julia, R et Haskell.

Posters

Logilab a eu l'opportunité de prendre part au projet de recherche PAFI (Plateforme d'Aide à la Facture Instrumentale), en développant une application WEB innovante, basée sur CubicWeb, visant à la fois à faciliter le prototypage virtuel d'instruments (à vent pour le moment) et à permettre des échanges de données entre les acteurs de la recherche et les facteurs d'instrument, voire les musées qui possèdent des instruments anciens ou exceptionnels. La plateforme met ainsi en œuvre la Web Audio API et un modèle de collaboration élaboré.

L'autre poster présenté par Logilab concerne Simulagora, un service en ligne de simulation numérique collaborative, qui permet de lancer des calculs dans les nuages (donc sans investissement dans du matériel ou d'administration système), qui met l'accent sur la traçabilité et la reproductibilité des calculs, ainsi que sur le travail collaboratif (partage de logiciel, de données et d'études numériques complètes).

Un grand merci à l'équipe d'organisation de l'événement, qui a encore remporté un joli succès cette année.

[afpyro] AFPyro à Lyon - le 27 août 2014

Publié le 2014-08-27 00:00:00

Un Afpyro aura lieu le mercredi 27 août à partir de 19h au Tooley’s - 7 quai Fulchiron - Lyon 5éme (probablement sur la terrasse côté rue Monseigneur Lavarenne, si le temps le permet).

Aucune présentation n’est prévue, mais nous pourrons discuter autour des dernières actualités sur Python, et ceux qui sont allés à Europython pourrons en parler autour d’un verre.

Pour se rendre au Tooley’s :
  • en métro : arrêt Vieux Lyon
  • en vélo’v : stations Place Crépu, Saint Jean, Place Gourjus
  • en bus : bus 31 ou C20, arrêt Saint Georges

[Biologeek] Un web omni-présent

Publié le 2014-08-26 11:00:00

Intervention donnée lors des Rencontres de Lure, avec pour thème CHEMINS DE FAIRE, ACTIVER LA PAGE BLANCHE // Traverse. 1h et un public inconnu, bien éloigné de ma zone de confort…

J’ai emprunté plusieurs chemins de traverse au cours de ma vie. Le premier a été de passer de la biologie à l’informatique et plus particulièrement au web. Puis j’ai assez rapidement décidé de travailler à mon compte pour avoir plus de liberté. Je suis ensuite allé au Japon pendant un an pour explorer une nouvelle culture, d’autres modes de vie et de pensée. Et enfin j’ai co-créé une SCOP de retour en France il y a 2 ans. Chacune de ces expériences a été l’occasion de repartir d’une page blanche. Ou presque. De faire en sorte que mon passé et ma culture soient des acteurs de nouvelles interactions dans de nouveaux domaines.

En découvrant le web, j’ai exploré un monde de relations qui n’était finalement pas si éloigné de la biologie. En découvrant la vie de freelance, j’ai pris conscience des enjeux et des responsabilités qui incombent à un chef d’entreprise, chaque client devenant un petit patron. En découvrant le Japon, j’ai appris à apprécier les singularités de la culture française. En découvrant la collaboration, j’ai été confronté aux difficultés d’une approche démocratique.

Aujourd’hui, on expérimente avec scopyleft l’activation de la page blanche des autres pour arriver ensemble à produire le plus de valeur. On a essayé l’agilité avant de se rendre compte qu’il fallait travailler en amont même des projets en s’inspirant des méthodes du Lean Startup (et notamment du Lean Canvas). La vérification de la pertinence d’une idée peut être obtenue avant même de plonger dans la technique à travers des interviews ou des « produits embryons ».

Je me représente le web comme cet univers en expansion. On en définit mal les contours — on sait qu’il s’agit d’amas d’amas de galaxies — que l’on se représente plus ou moins sphérique. Parmi cette multitude d’étoiles, des planètes se sont formées et certaines se trouvent être à des conditions de pression et de température favorables à l’apparition de rencontres. J’ai l’impression d’être un astéroïde qui a atterri par hasard sur la planète des Rencontres de Lure. Afin que l’on partage un vocabulaire commun, j’ai posé 3 questions pour que l’on puisse échanger durant l’heure qui a suivi :

  • Quels sont ceux d’entre vous qui travaillent dans le web ?
  • Quels sont ceux parmi vous qui codent pour le web (html, css, js) ?
  • Quels sont ceux qui ont un compte Facebook ? Twitter ? Gmail ?

Un web

The problem with a centralized web is that the few points of control attract some unsavory characters. […] It’s not just possible, but fairly common for someone to visit a Google website from a Google device, using Google DNS servers and a Google browser on the way.

The Internet With A Human Face

On appelle souvent le web « la toile » ce qui lui donne une représentation concentrique avec l’araignée généralement au centre. C’est une assez mauvaise image du web originel, malheureusement cette métaphore tend à se rapprocher du web actuel. Nous sommes partis d’un web plus ou moins acentré pour arriver à un web qui ressemble à une télévision sur lequel on zappe entre 6 onglets (Google, Facebook, Twitter, Instagram, Wikipedia, Amazon). Cette position donne à ces monopoles une situation préoccupante à triple titre :

  • Ils peuvent fragmenter le web. Certains contenus, certaines données, ne deviennent accessibles qu’en faisant partie de la plateforme. En publiant sur ces sites, vous êtes acteurs de cette fragmentation sous couvert d’élitisme/snobisme.
  • Ils peuvent filtrer le web. Les algorithmes mis en place pour vous afficher les contenus de manière pertinente sont des œillères dangereuses. En ne consultant que ces sources d’information vous devenez prisonniers de bulles de complaisance bien lisses.
  • Ils peuvent monétiser le web. À partir de vos données, de vos relations, de vos interactions, de vos simples explorations. Votre profil prend de la valeur si vous êtes malade, si vous êtes dépensier, si vous tombez enceinte !

Les amas de galaxies dont je parlais en introduction s’agrègent et perdent de leur hétérogénéité. Comment évoluera un réseau en pair à pair avec de telles inégalités entre les pairs ?

On assiste également à une app-ification du web qui sous couvert de simplicité transforme vos interactions à travers le réseau en passant par des boîtes noires qui n’ont plus ni la simplicité des technologies web, ni la lisibilité de leur code.

La diversité sur le web se réduit à tel point qu’une page personnelle vous fait aujourd’hui passer pour un marginal. Voire un suspect ?

Omni

Le coût de la surveillance est beaucoup trop bas.

Lettre aux barbus, Laurent Chemla

On parle beaucoup d’Internet of Things, de Quantified Self ou d’OpenData avec l’idée derrière tout cela que beaucoup de données (Big Data — BINGO!) vont transiter entre nous, nos objets et notre environnement au sens large pour enrichir des hipsters de la silicon valley nous simplifier la vie.

Malheureusement ce dont on s’est aperçu avec Snowden et depuis, c’est que ces données servent surtout à nous tracer à grande échelle. Cette surveillance généralisée est préoccupante pour 3 raisons :

  • Perte de confiance dans le politique. C’était déjà pas la joie mais alors là c’est à vous faire douter de votre intérêt pour la citoyenneté. Les acteurs en puissance ont tout à gagner à ce qu’on les laisse s’amuser entre eux. Mais ce n’est plus de la démocratie…
  • Sentiment d’insécurité et lissage de l’opinion. Si chaque citoyen devient suspect, il faut se fondre dans la masse. Pour tromper les algorithmes, pour tromper les (futurs) drones, pour finir par se tromper soi-même. Et lorsqu’on s’est suffisamment conformé au moule on tape sur la minorité voisine pour évacuer son stress et se sentir vivant. Ou on retweete une cause vraiment juste… mais passagère aussi.
  • Renoncement à une vie privée numérique. Puisque plus rien ne marche, autant vivre avec et arrêter d’essayer de se battre contre des moulins. De toute façon ceux qui ont peur doivent bien avoir quelque chose à cacher ? Ou peut-être que l’on a envie d’un web intime, d’un web qui autorise les erreurs, d’un web qui dénonce les injustices ?

Devant cette surveillance généralisée, pour vivre heureux vivons submergés ?

Présent

Seven generation sustainability is an ecological concept that urges the current generation of humans to live sustainably and work for the benefit of the seventh generation into the future.

Great Law of the Iroquois

Internet n’oublie jamais. On a tous entendu cet adage qui est pourtant relativement faux. Des pages, des photos, des données disparaissent tous les jours. Lorsqu’un service ferme ce sont des milliers, voire des millions de comptes qui sont perdus. J’ai d’ailleurs appelé cela un datacide lorsque l’on assiste à un génocide de données. Cela peut avoir des effets bénéfiques et l’on pense bien évidemment au droit à l’oubli mais le problème est qu’Internet n’agit pas comme une souvenance — la façon dont on se souvient de ce que l’on a vécu — mais comme un journal de bord à moitié effacé. On ne choisit pas ce qui est conservé, on le subit.

Face à cette culpabilité numérique on en vient à une sorte d’exhibitionnisme numérique : plus je publie et moins les choses que je souhaite cacher seront visibles. On obtient des flux sans réflexion, sans espoir d’archivage, sans aucun contrôle. Le lâcher-prise sur ses interactions en ligne est symptomatique d’une inconscience généralisée de l’usage qui peut en être fait.

Ouf ! On a survécu à l’introduction un peu déprimante (j’ai réussi à plomber l’ambiance de typographes — huhu). Si l’on analyse chacun des points de ce web omni-présent, on constate qu’il y a principalement un problème de confort. Le web se fragmente car on ne prend pas la peine d’avoir son propre serveur, se surveille massivement car on est paresseux sur le chiffrement et disparait car l’on n’a pas envie de se soucier de ses traces numériques. Quelles pistes non techniques pour un web plus sain ?

Pistes

Militer

Le militantisme peut avoir un impact s’il est pratiqué à large échelle. La force du web est de pouvoir transmettre et propager des informations très rapidement. Il faut se servir de cet outil à bon escient !

Déconnecter

Je vais prendre mon exemple : je n’ai pas de compte Facebook, j’ai fait plusieurs diètes de tweets, je n’ai plus de smartphone. C’est certainement extrême mais je n’en suis pas mort numériquement pour autant. Je me porte même plutôt mieux depuis. S’interroger sur ses usages permet de prendre conscience de ce qui a vraiment de la valeur.

Innover localement

Je fonde beaucoup d’espoirs dans les initiatives locales. De nombreux projets sont en gestation et se développent autour de petites communautés de façon décentralisée. Une façon de s’adapter à la culture locale, de recréer une sorte d’intimité numérique.

Éduquer

Cette dynamique d’ouverture ne se fera pas sans éducation. Pas seulement auprès des enfants, on n’a malheureusement pas le luxe d’attendre que les nouvelles générations représentent la majorité. Il faudrait une éducation citoyenne de masse, 100 personnes aujourd’hui qui transmettront demain à 1000 autres ? ;-)

Se réapproprier

En utilisant des outils conviviaux tels que les défini Ivan Illich :

  • ne doit pas dégrader l’autonomie personnelle en se rendant indispensable
  • ne suscite ni esclave, ni maître
  • élargit le rayon d’action personnel

Il est temps de se réapproprier ses savoirs pour être à même de réacquérir son autonomie et en offrir à d’autres.

La concentration de galaxies est à l’origine d’une augmentation de la température qui se termine généralement en trous noirs. Quels autres leviers avons-nous pour éviter que le web ne soit aspiré par ces trous noirs ? J’ai démarré le discussion avec cette citation :

Il faut choisir, se reposer ou être libre.

Thucydide, ~2400 av. Facebook

Discussion

Questions techniques

Beaucoup de discussions sur la faisabilité technique d’une telle surveillance. Si l’on fait un premier point sur l’affaire Snowden, le constat est on ne peut plus limpide. C’est même pire après tout ce qui a été découvert depuis…

Questions sur la peur

On m’a demandé de quoi est-ce que j’avais peur, ressortant le fameux Nothing to hide, nothing to fear. Je n’ai pas peur, je m’interroge sur un constat et sur ma participation indirecte à la situation actuelle en étant acteur de ce système. J’explore des solutions et je vais en chercher dans des lieux comme les rencontres de Lure pour y retrouver une certaine naïveté technique et une expérience vieille de quelques millénaires.

Solutions techniques

Il m’a quand même été demandé de donner quelques solutions techniques. Voici des propositions :

Ces 4 points sont très basiques, vous pouvez ensuite vous pencher sur des solutions comme les réseaux privés virtuels (VPN) ou Tor pour aller plus loin.

Le web est une invention précieuse, préservons son graphe : ses liens et ses données.

[AFPy-Nantes] 40 pythons, 1 conférence et des trolls

Publié le 2014-08-25 22:00:00

Nous étions nombreux mardi dernier aux conférences. À la louche, une quarantaine. Un groupe assez hétérogène composé de curieux comme d'experts.

Deux sujets ont donc été abordés, merci à Florent et Alex pour leur préparation :).

Ci-dessous, le compte-rendu de près de 2h de conférence :).

Django, framework web

Intervenant : Florent

Les slides de la présentation sont disponibles ici : Introduction à Django

chapter Part I: Django Django

Présentation

Django est donc un framework pour le web développé dans l'optique d'être rapide à configurer et déployer. Ainsi, il présente un haut niveau d'abstraction. Étant un projet open-source, il est assez facile de l'étendre.

La dernière release est 1.6 et celle à venir, 1.7, devrait présenter des mises à jour de fond, tel un système de migration intégré : django-migrations.

Le projet est développé selon les philosophies KISS (Keep It Shot & Simple) et DRY (Don't Repeat Yourself). Si le premier objectif est bien rempli, il semble que le second soit sujet à débat. On notera différents avantages à django, notamment son installation très facile ainsi que son excellente documentation. Il dispose également d'une communauté très active.

Sous le capot ?

Concernant les aspects techniques, l'environnement classique est une version 1.6 du framework sous python 2.7. Django est compatible python 3 mais ce n'est pas le cas de tous les modules qui peuvent s'y ajouter. Pour la partie serveur, il semble qu'il s'intègre correctement derrière tout et n'importe quoi (apache, nginx,...). Du côté base de données (BDD), django fonctionne essentiellement avec SQL (MySQL, PostgreSQL, SQLite). Il est possible de l'interfacer avec des bases NoSQL, mais il faut garder en tête que tout le framework est pensé pour intéragir avec des bases de données relationnelles.

Pour ce qui est de la création de site, Django repose sur un modèle type MVC (modèle-vue-contrôleur) qui sera appelé MTV (modèle-template-vue). Les modèles, qui décrivent les objets stockés en base, sont écrits en Python. Cela rend la configuration intuitive. Il est à noter que le moteur de template, semblable à Jinja en terme de syntaxe, est réputé comme étant lourd et lent.

En pratique...

Après toute cette théorie, démonstration rapide avec la mise en place d'un site pour recenser les coins à champignons. C'est l'occasion d'observer la rapidité avec laquelle il est possible de déployer un nouveau site (environ 4 commandes ^^). Cerise sur le gâteau, Django génère automatiquement une interface d'administration contenant formulaire et tout ce qu'il faut pour gérer le contenu de la BDD (opérations CRUD). L'administration d'un projet se fait essentiellement via le script manage.py.

Django sépare les modules métiers sous forme d'applications. Chacune contenant un fichier models.py, views.py, admin.py et tests.py (pour vous encourager à créer des tests unitaires). Les modèles se déclarent sous forme de classes Python dont les champs sont des colonnes en base. Il est possible d'étendre facilement les types de champs pour créer des types spécifiques, autre que ceux de SQL.

Concernant la définition des routes, comme souvent, elle se fait via l'utilisation de schémas et d'expressions régulières. Ici, on découvre avec plaisir que Django repère automatiquement lorsqu'un fichier est modifié et redéploie.

Aller plus loin

Les bases de Django en poche, on évoque rapidement les fonctionnalités avancées. Notamment de l'héritage sur les modèles, à la fois puissant mais rapidement complexe. Des mécanismes similaires existent sur les vues et les templates.

Django présente aussi des fonctionnalités d'internationnalisation, tant pour les URL que pour le contenu.

Pour la gestion des login, la notion de groupes, d'utilisateur et de droits est pré-intégrée et est aisément personnalisable.

Il est ressorti des questions que Django possède un système de rétro-spécification, capable de définir les fichiers modèles nécessaires décrivant une BDD pré-existante, très utile quand combiné avec des modules de migration, type south (c.f. ci-après).

Les modules

Que serait un framework (open-source) sans ses plugins & modules ? La communauté étant active, il existe de nombreux modules très utiles, il ressort de la conférence :

  1. South. Un outil pour effectuer des migrations de base de données. Un exemple de cas d'utilisation : l'intervenant devait migrer une vieille application vers Django. Parmi les problèmes, il faisait face à la structure SQL de très mauvaise qualité (du genre clé étrangère non unique...). A l'aide de l'outils de rétro-spécification de Django, il a été capable de récupérer les définitions des modèles et de corriger la BDD grâce à South. Hallelujah ! Comme mentionné plus haut, la version 1.7 de Django intègre un tel module (essentiellement basé sur South). Cela peut également être très utile pour manipuler différentes bases sur différents serveurs (dev, prod, pre-prod,...).
  2. django-extensions: utilitaire pour manage.py ajoutant des commandes pour faciliter l'administration.
  3. django-debug-toolbar: outil pour faire du profiling dans le navigateur.
  4. factory-boy: création de grappes de données pour le test (Déclaration de factory). Par rapport à l'utilisation de fixtures, il permet un maintien plus facile des données de test. De plus, la gestion des clés étrangères est très pratique.
  5. Un module shop très différent de prestashop. Beaucoup plus modulaire que ce dernier (donc pas solution out of the box).

Conclusion & commentaires

Ce petit tour d'horizon nous aura permis de constater l'extrême rapidité de développement qu'offre Django. Énorme avantage également, sa large bibliothèque de modules.

Concernant la question du choix du framework web, il existe des alternatives à Django. Pour choisir ce dernier, c'est l'usage final qui est déterminant. Bien que Django soit rapide et efficace, il est en revanche très monolythique. Si vous comptez utiliser un autre ORM par exemple, un framework plus modulaire serait Pyramid. Enfin, il existe des framework très léger comme Flask.

L'inévitable comparaison avec d'autres langages tels que PHP était plutôt sans appel (l'occasion pour certains templiers/trolls de partir en croisade contre Symfony :)). PHP est jugé (très) lourd et peu efficace. Il y avait d'ailleurs parmi nous 3 personnes qui souhaitaient quitter l'univers PHP au profit de Python.

Finalement, Django présente quelques points noirs, tels que la personnalisation de l'interface d'administration ou bien la gestion de pages multi-formulaires. Si ces dernières se complexifient, leur maintien devient vite très difficile.

Quelques liens pour se documenter :

Questions

Les questions ont fait ressortir les points suivant.

Il est aisé de définir plusieurs environnements (prod, pre-prod, dev) via les fichiers de configuration. Le script settings.py (configuration générale) se charge ensuite de sélectionner la configuration appropriée en fonction de l'environnement.

Pour les tests unitaires, les capacités de test de Python sont très utiles. Ainsi que le module LiveServerTestCase pour tester les requêtes réellement à travers de réelles requêtes HTTP.

Il est possible d'utiliser Django sans installer un SGBD relationnel sur son poste, grâce à SQLite. L'utilisation du framework sans base de donnée du tout se limitera à l'utilisation du routage d'URL, des vues et des templates. Dans un tel cas d'utilisation, un coup d'oeil à un framework plus léger comme Flask (c.f. plus haut) est conseillé.

Python, les bonnes pratiques.

Intervenant : Alex

Les slides de la présentation sont disponibles ici : Écrire du code vraiment pythonique

Vous voulez coder en Python ? D'accord, mais pas n'importe comment ! Les bonnes pratiques facilitent la relecture du code et le maintien que cela soit par un tier ou par son auteur lui-même. Il ne faut pas oublier qu'on laisse parfois nos projets personnels un peu en suspend, et lorsqu'on les reprend, on est alors un étranger dans sa propre maison. Au cas où, mieux vaut baliser le terrain ;).

Notre intervenant commence par quelques généralités sur Python, sa syntaxe et sa philosophie. "Python essaie d'être élégant", voilà une des premières choses qu'on entend. Par rapport à d'autres langages (e.g. Ruby) qui recherchent en plus la pureté. Pour le développeur Python, la pureté n'est pas une fin en soi. c.f. The Zen of Python que je cite " Special cases aren't special enough to break the rules. Although practicality beats purity". En bref, un mot très important : pragramatisme (practicality).

Coder proprement, ça ne s'invente pas, encore moins quand on débute et les gens qui travaillent avec Python y réfléchissent. Du coup il existe un guide de références définissant les bonnes pratiques, on l'appelle le PEP8. Derrière ce terme à l'apparence obscure de PEP (Python Enhancement Proposals) se cache tout simplement des propositions d'amélioration du langage, qu'elles soient techniques ou formelles.

Pour ce qui est de la mise en pratique du PEP8, je me permets de vous renvoyer aux slides de la présentation qui seront plus clairs et exhaustifs. Cependant, durant la présentation, quelques points sont ressortis plus que d'autres. Je continue donc avec une liste non exhaustive...

D'abord, il existe des outils pour suivre les lignes directrices (guide lines) comme flake8 qui vérifie le respect du PEP8 (il en existe d'autres !). Mais plus simple encore, l'easter egg (introduit par le PEP20) du import this qui affiche le Zen of Python.

Concernant les entrées d'un programme, une bonne habitude est de traiter les données en deux fois :
  1. Normaliser l'entrée
  2. Traiter la donnée normalisée

Cela permet de simplifier le code, notamment celui du traitement qui est du coup toujours le même. Donc, évitez d'avoir à gérer trop de cas d'erreurs (excpetions) dans le code de traitement. On notera ici la phrase célèbre de Jon Postel : "Be liberal in what you accept, and conservative in what you send". Qu'on pourrait traduire par : soyer souple pour vos entrées, intransigent pour vos sorties.

On a aussi parlé des tuples, structure de données constantes (immutable) très pratique pour passer de la donnée à une fonction. Attention cependant à ne pas en abuser. Si de nombreux traitements sont inhérents à vos tuples, vous avez peut-être besoin d'un objet (classe) pour mieux gérer tout ça (e.g. points en mathématique...). Pour un type point en Mathématiques, peut-être qu'une classe est plus adaptée. VOus pourrez alors profiter de la surcharge d'opérateur pour implémenter les opérations spécifiques.

A plusieurs reprises nous avons mentionné les dictionnaires, c'est un synonyme de tableau associatif, i.e. un ensemble clé-valeur.

Autre point fort, les ContextManager, ces objets qu'on utilise grâce au mots clés with-as. Ils sont une fonctionnalité très importante du langage qui permet de bien maîtriser la portée des variables. Par exemple pour l'ouverture et la fermeture d'un fichier, ou encore pour la création et l'excécution d'une requête dans Django :).

A propos des lambda functions, ces petits bouts de code très courts qui n'acceptent qu'une expression pour seule opération, rappel qui a son importance : pas de unpacking de tuple dans les paramètres (c.f. slydes et tuples pour la notion de unpacking).

Le mot de la fin

Les slides des deux présentations sont disponibles ici:

On a vu et appris plein de choses, c'était super ! A la prochaine fois, et d'ici là, codez bien !

[logilab] Logilab at Debconf 2014 - Debian annual conference

Publié le 2014-08-21 19:07:00

Logilab is proud to contribute to the annual debian conference which will take place in Portland (USA) from the 23rd to the 31st of august.

Julien Cristau (debian page) will be giving two talks at the conference :

http://www.logilab.org/file/263602/raw/debconf2014.png

Logilab is also contributing to the conference as a sponsor for the event.

Here is what we previously blogged about salt and the previous debconf . Stay tuned for a blog post about what we saw and heard at the conference.

https://www.debian.org/logos/openlogo-100.png

[tarek] ToxMail Experiment Cont'd

Publié le 2014-08-03 19:33:00

I started the other day experimenting with Tox to build a secure e-mailing system. You can read my last post here.

To summarize what Toxmail does:

  • connects to the Tox network
  • runs a local SMTP and a local POP3 servers
  • converts any e-mail sent to the local SMTP into a Tox message

The prototype is looking pretty good now with a web dashboard that lists all your contacts, uses DNS lookups to find users Tox Ids, and has a experimental relay feature I am making progress on.

See https://github.com/tarekziade/toxmail

DNS Lookups

As described here, Tox proposes a protocol where you can query a DNS server to find out the Tox ID of a user as long they have registered themselves to that server.

There are two Tox DNS servers I know about: http://toxme.se and http://utox.org

If you register a nickname on one of those servers, they will add a TXT record in their DNS database. For example, I have registered tarek at toxme.se and people can get my Tox Id querying this DNS:

$ nslookup -q=txt tarek._tox.toxme.se.
Server:     212.27.40.241
Address:    212.27.40.241#53

Non-authoritative answer:
tarek._tox.toxme.se text = "v=tox1\;id=545325E0B0B85B29C26BF0B6448CE12DFE0CD8D432D48D20362878C63BA4A734018C37107090\;sign=u+u+sQ516e9VKJRMiubQiRrWiVN0Nt98dSbUtsHBEwYiaQHk2T8zAq4hGprMl9lc89VXRnI+AukoqpC7vJoHDXRhcmVrVFMl4LC4WynCa/C2RIzhLf4M2NQy1I0gNih4xjukpzRwkA=="

Like other Tox clients, the Toxmail server uses this feature to convert on the fly a recipient e-mail into a corresponding Tox ID. So if I write an e-mail to tarek@toxme.se, Toxmail knows where to send the message.

That breaks anonymity of course, if the Tox Ids are published on a public server, but that's another issue.

Offline mode

The biggest issue of the Toxmail project is the requirement of having both ends connected to the network when a mail is sent.

I have added a retry loop when the recipient is offline, but the mail will eventually make it only when the two sides are connected at the same time.

This is a bit of a problem when you are building an asynchronous messaging system. We started to discuss some possible solutions on the tracker and the idea came up to have a Supernode that would relay e-mails to a recipient when its back online.

In order to do it securely, the mail is encrypted using the Tox public/private keys so the supernode don't get the message in clear text. It uses the same crypto_box APIs than Tox itself, and that was really easy to add thanks to the nice PyNaCL binding, see https://github.com/tarekziade/toxmail/blob/master/toxmail/crypto.py

However, using supernodes is adding centralization to the whole system, and that's less appealing than a full decentralized system.

Another option is to use all your contacts as relays. A e-mail propagated to all your contacts has probably good chances to eventually make it to its destination.

Based on this, I have added a relay feature in Toxmail that will send around the mail and ask people to relay it.

This adds another issue though: for two nodes to exchange data, they have to be friends on Tox. So if you ask Bob to relay a message to Sarah, Bob needs to be friend with Sarah. And maybe Bob does not want you to know that he's friend with Sarah.

Ideally everyone should be able to relay e-mails anonymously - like other existing systems where data is just stored around for the recipient to come pick it.

I am not sure yet how to solve this issue, and maybe Tox is not suited to my e-mail use case.

Maybe I am just trying to reinvent BitMessage. Still digging :)

[Biologeek] Héritage et immobilier

Publié le 2014-08-01 11:00:00

— Tu n’en as pas marre de payer un loyer ?
— Non, tirade sur la propriété, fléau de cette société.
— Mais pour ton fils ?!!!

La discussion revient souvent donc pour clarifier :

  • Faire un achat immobilier consiste à s’endetter et donc à se condamner à assurer un revenu sur x années. Cela réduit considérablement les options possibles pour passer plus de temps avec mon fils. Le loyer est le prix de cette flexibilité.
  • Acquérir une maison c’est s’immobiliser et donc renoncer à une vie nomade permettant de rencontrer d’autres cultures. Je ne souhaite pas que du matériel vienne entraver une soif de découverte et d’expériences. Le loyer est le prix de cette liberté.
  • Léguer c’est déchirer une famille, je n’ai pas vu un seul héritage dans mon entourage qui se soit déroulé sans accrocs. Je ne pense pas que le gain soit à la hauteur de l’enjeu. Vraiment. Le loyer est le prix de cette intégrité.

J’espère que mon fils aura hérité de bien d’autres choses pour être autonome, bienveillant et heureux dans la vie. La richesse que je lui propose d’accumuler n’est pas matérielle, elle ne se mesure pas en m², elle n’est pas spéculative non plus. La chose la plus importante dont il a besoin c’est de l’attention et du temps de tendresse disponible.

Pas un tas de cailloux.

[AFPy-Nantes] Fin des vacances, Nantes se replonge dans Python :)

Publié le 2014-07-31 22:00:00

Tout le monde est bien reposé, il est de temps de se replonger dans le bain. Rien de tel qu'un meetup de rentrée !

Deux sujets de présentations vous seront proposés:

  • « Introduction à Django, le framework de développement web pour les perfectionnistes sous pression. »
  • « Écrire du code python selon les règles de l’art. »

La suite du meetup et de la soirée nous laissera le temps de discuter librement et d'aller boire un verre pour profiter de cette fin de période estivale.

Que vous soyez experts Python, débutants ou simplement curieux de découvrir ce langage, nous serons heureux de vous compter parmis nous !

L'évènement est publié sur le site de la Cantine: Meetup Python #4.

À bientôt, et en attendant ... respectez la PEP8 :)

[Biologeek] Jeune photographe

Publié le 2014-07-31 11:00:00

Accepter les photographies que nous avons faites comme elles sont devient alors un acte d’accompagnement du mouvement permanent du monde. On ne fait pas toujours des photographies comme on embaume des cadavres. On en fait aussi parfois comme on cueille des fleurs, en sachant nos sensations périssables, pour le plaisir d’accompagner leur évanouissement fugitif ou de rendre hommage à la beauté du monde. Et on en fait parfois comme on planterait des graines, en attente de la floraison à venir.

En attente d’une floraison à venir, Serge Tisseron

Jeune photographe, tu vas te réfugier dans la technique. Les focales et les boîtiers n’auront plus de secret pour toi. Tu manieras l’exposition, la composition, le bokeh et le flou cinétique comme un pro. Tu feras de belles photos. La technique est rassurante et rationnelle, elle fait partie du domaine du connu en se rapprochant de ce qui est enseigné à l’école. Malheureusement, la technique est aux antipodes des émotions. La maîtrise d’un outil peut réduire son expression artistique et sa créativité.

Jeune photographe, tu vas chercher des mentors. Les écouter, les aduler, les copier, parfois même les rencontrer. Examiner leur travail, méticuleusement, tirage après tirage pour comprendre la chaîne photographique. Leur expérience va te permettre de progresser rapidement, de connaître des astuces stylistiques et d’identifier les scènes qui ont du potentiel. Tu feras des photos artistiques. Malheureusement, ces sources d’inspiration étoufferont ton propre style. La photographie est avant tout l’expression de son soi profond et personnel.

Jeune photographe, tu vas être attiré par l’exotisme. Nu, N&B, contrées lointaines, macro, animalier, les catégories ne manquent pas pour se distinguer et sortir de la monotonie. Qu’il est reposant d’explorer en continu sans prendre le temps de s’ennuyer sur un domaine. Tu vas faire des photos attrayantes. Malheureusement, c’est dans cet ordinaire que résident les pépites artistiques. L’intimité photographique comme un partage de ces instants de vie.

Jeune photographe, surprends-toi !

Billet auto-critique suite à une twiscussion avec Éric, Karl et Emmanuel.

[AFPy-Nantes] Barcamp estival du 29 juillet 2014

Publié le 2014-07-30 22:00:00

Notre premier barcamp, animé par Georges nous a permis d'aborder différents sujets en groupes de 3 à 5 personnes pendant 45 minutes environ.

Les comptes-rendus sont ci-dessous, rendez-vous à la prochaine rencontre !

barcamp estival du 29 juillet 2014

Outils Python pour les adminsys/devops

Participants : Florent, Antoine et Pablo

Rapporteur : Pablo

L'idée était de discuter des outils Python disponibles pour les adminsys.

Les point abordés étaient :

  • Les outils pour disponibles pour le déploiement/provisioning, comme Fabric http://www.fabfile.org/, Ansible http://www.ansible.com/home ou Saltstack http://www.saltstack.com/
  • Les nouvelles façons de travailler entre développeurs et administrateurs systèmes, Antoine nous a raconté son expérience avec Fabric et Puppet (Ruby) chez Wikipedia, nous avons évoqué la problématique du stockage/versioning de donnés sensibles et partagées dans une même équipe
  • Les outils de monitoring comme Graphite http://graphite.wikidot.com/ et ElasticSearch/Logstash/Kibana (Java) pour les métriques des apps/activités
  • L'utilisation de Sentry https://getsentry.com/ pour le tracking des erreurs/exception dans une application Python

Pour résumer, la discussion a été ouverte et variée. De plus, c'était la première fois que nous nous rencontrions et les échanges ont permis de mieux connaître l'intérêt et l'expérience de chacun sur le sujet, le tout dans une très bonne ambiance.

Django

Participants : Mathieu F., ?, ?, ?

Rapporteur : Mathieu F.

Nous avons évoqué les serveurs web et leurs modes "FastCGI" et WSGI".

FastCGI :

WSGI :

Nous avons ensuite rapidement parlé de Gunicorn (http://gunicorn.org/), un serveur web conçu pour Python et WSGI.

Puis Django :

  • framework de développement web
  • permet d'architecturer le code selon le modèle MVC
  • permet de définir une liste d'URL (exemple pour "www.monsite.fr" : /login, /blog, /admin, /voirArticle et d'associer une action / un script à chacune (ce que Symfony appelle des routes, dans le monde PHP ;-)
  • fournit une commande shell "manage.py" permet des actions de debug, initialisation, lancement du serveur web en local, etc
  • Django permet de créer un back office très light (CRUD) de manière presque automatique

Les "virtualenv" :

  • permettent de faire cohabiter des logiciels écrits en Python ayant des prérequis différents. Par exemple : le logiciel "Toto" requiert la lib "libA" en version 12, alors que le logiciel "Truc" requiert la lib "libA" en version 10
  • sont utiles (indispensables !) à la fois en environnement de dév et en prod
  • voir commandes "virtualenv", "virtualenvwrapper" et "venv"

Déploiement d'applis Django :

Hébergement :

Python 2.7 ou Python 3.x ? (troll inside ;-)
==> A ce jour, la seule raison de commencer un développement en 2.7 plutôt qu'en 3.x serait d'avoir un besoin impératif d'une lib non dispo en Python 3 (et dont le portage n'est pas envisagé). De très nombreuses libs ont été mises à jour, donc ce cas de figure devrait se raréfier.

Depuis la version 1.6, Django (https://www.djangoproject.com/) supporte Python 3.

Pour terminer, un petit lien vers un blog TRES intéressant sur Python (mais pas que ;-) :

Bonnes pratiques et outils python

Participants : Reine, Nicolas, Yoann

Rapporteur : Yoann

Tout d'abord, nous avons discuté de maisons d'édition chez qui paraissent des livres intéressants pour de la doc ou de l'outillage (Python/Linux mais pas que) : Packt, O'Reilly, Apress, No starch press. Nous avons aussi parlé de sites plus orientés Linux : TLLTS (The Linux Link Tech Show:podcasts sur youtube), Linux Luddites, distrowatch.

Ensuite, nous avons abordé la démarche générale à suivre dans les projets pour en venir plus particulièrement à l'outillage : en fonction des besoins du projet on choisit les technologies, puis vient le choix des outils. Avec Python, la référence permet généralement comprendre rapidement comment utiliser les librairies.

Enfin, nous avons parlé des virtualenv qui permettent d'avoir plusieurs environnements bien séparés sur une machine physique (et donc de disposer de différentes versions des librairies, voire de Python) ainsi que les importer/exporter grâce à pip, par l'intermédiaire d'un fichier listant les dépendances du projet.

Regards croisés sur des projets python

Participants : Jean D., Georges G., Jean-Baptiste, ?

Rapporteur : Jean D.

Python est recherché pour simplifier et debugger des développements existants. D'un accès facile sur le Web, il est également rapide d'apprentissage. Il permet de réduire la taille d'un développement classique. L'ordre de grandeur de cette réduction peut-être de 75 % du temps. Ceci grâce à 2 atouts principaux : son "moteur" performant ses nombreuses fonctionnalités.

[AFPy-Nantes] Rencontre et key signing party 24 mai 2014

Publié le 2014-07-30 22:00:00

Après le meetup-pilote qui nous a permis de découvrir GrapheekDB, cette rencontre avait pour principal objectif de faire connaissance et préparer les prochains évènements.

Il en est sortie l'idée d'organiser un meetup par mois en alternant conférences et barcamps.

Quelques sujets potentiels de présentations ont déjà émergés :

  • Initiation à Python ou comment écrire du code pythonesque pour ceux qui viennent d'autres langages
  • Retour d'expérience sur migration vers Python3
  • Python legacy avec Zope, Grok, etc.
  • Demo d'IPython Notebook avec un peu de dataviz
  • Programmation un Raspberry PI avec Python
  • Présentation/Introduction à Django
  • Retour d'expérience sur apps Django et bibliothèques sympas
  • Sites et blogs statiques avec Pelican
  • Générateurs et co-routines

La key signing party organisée par Pablo a permis d'animer la suite du meetup, en attendant la bière !

rencontre et key signing party

À bientôt, et en attendant ... respectez la PEP8 :)

[AFPy-Nantes] Retour sur le meetup du 09 avril 2014

Publié le 2014-07-29 22:00:00

Lors de ce premier meetup Python, où plus d'une vingtaine de personnes étaient présentes, Raphaël Braud nous a présenté GrapheekDB, une base de données de graphe libre !

Ce premier rendez-vous était surtout l'occasion de nous rencontrer et de discuter de l'organisation de nos prochaines rassemblements.

À bientôt, et en attendant ... respectez la PEP8 :)

[logilab] Pylint 1.3 / Astroid 1.2 released

Publié le 2014-07-28 15:21:00

The EP14 Pylint sprint team (more on this here and there) is proud to announce they just released Pylint 1.3 together with its companion Astroid 1.2. As usual, this includes several new features as well and bug fixes. You'll find below some structured list of the changes.

Packages are uploaded to pypi, debian/ubuntu packages should be soon provided by Logilab, until they get into the standard packaging system of your favorite distribution.

Please notice Pylint 1.3 will be the last release branch support python 2.5 and 2.6. Starting from 1.4, we will only support python greater or equal to 2.7. This will be the occasion to do some great cleanup in the code base. Notice this is only about the Pylint's runtime, you should still be able to run Pylint on your Python 2.5 code, through using Python 2.7 at least.

New checks

  • Add multiple checks for PEP 3101 advanced string formatting: 'bad-format-string', 'missing-format-argument-key', 'unused-format-string-argument', 'format-combined-specification', 'missing-format-attribute' and 'invalid-format-index'
  • New 'invalid-slice-index' and 'invalid-sequence-index' for invalid sequence and slice indices
  • New 'assigning-non-slot' warning, which detects assignments to attributes not defined in slots

Improved checkers

  • Fixed 'fixme' false positive (#149)
  • Fixed 'unbalanced-iterable-unpacking' false positive when encountering starred nodes (#273)
  • Fixed 'bad-format-character' false positive when encountering the 'a' format on Python 3
  • Fixed 'unused-variable' false positive when the variable is assigned through an import (#196)
  • Fixed 'unused-variable' false positive when assigning to a nonlocal (#275)
  • Fixed 'pointless-string-statement' false positive for attribute docstrings (#193)
  • Emit 'undefined-variable' when using the Python 3 metaclass= argument. Also fix 'unused-import' false for that construction (#143)
  • Emit 'broad-except' and 'bare-except' even if the number of except handlers is different than 1. Fixes issue (#113)
  • Emit 'attribute-defined-outside-init' for all statements in the same module as the offended class, not just for the last assignment (#262, as well as a long standing output mangling problem in some edge cases)
  • Emit 'not-callable' when calling properties (#268)
  • Don't let ImportError propagate from the imports checker, leading to crash in some namespace package related cases (#203)
  • Don't emit 'no-name-in-module' for ignored modules (#223)
  • Don't emit 'unnecessary-lambda' if the body of the lambda call contains call chaining (#243)
  • Definition order is considered for classes, function arguments and annotations (#257)
  • Only emit 'attribute-defined-outside-init' for definition within the same module as the offended class, avoiding to mangle the output in some cases
  • Don't emit 'hidden-method' message when the attribute has been monkey-patched, you're on your own when you do that.

Others changes

  • Checkers are now properly ordered to respect priority(#229)
  • Use the proper mode for pickle when opening and writing the stats file (#148)

Astroid changes

  • Function nodes can detect decorator call chain and see if they are decorated with builtin descriptors (classmethod and staticmethod).
  • infer_call_result called on a subtype of the builtin type will now return a new Class rather than an Instance.
  • Class.metaclass() now handles module-level __metaclass__ declaration on python 2, and no longer looks at the __metaclass__ class attribute on python 3.
  • Add slots method to Class nodes, for retrieving the list of valid slots it defines.
  • Expose function annotation to astroid: Arguments node exposes 'varargannotation', 'kwargannotation' and 'annotations' attributes, while Function node has the 'returns' attribute.
  • Backported most of the logilab.common.modutils module there, as most things there are for pylint/astroid only and we want to be able to fix them without requiring a new logilab.common release
  • Fix names grabed using wildcard import in "absolute import mode" (i.e. with absolute_import activated from the __future__ or with python 3) (pylint issue #58)
  • Add support in brain for understanding enum classes.

[logilab] EP14 Pylint sprint Day 2 and 3 reports

Publié le 2014-07-28 15:21:00
https://ep2014.europython.eu/static_media/assets/images/logo.png

Here are the list of things we managed to achieve during those last two days at EuroPython.

After several attempts, Michal managed to have pylint running analysis on several files in parallel. This is still in a pull request (https://bitbucket.org/logilab/pylint/pull-request/82/added-support-for-checking-files-in) because of some limitations, so we decided it won't be part of the 1.3 release.

Claudiu killed maybe 10 bugs or so and did some heavy issues cleanup in the trackers. He also demonstrated some experimental support of python 3 style annotation to drive a better inference. Pretty exciting! Torsten also killed several bugs, restored python 2.5 compat (though that will need a logilab-common release as well), introduced a new functional test framework that will replace the old one once all the existing tests will be backported. On wednesday, he did show us a near future feature they already have at Google: some kind of confidence level associated to messages so that you can filter out based on that. Sylvain fixed a couple of bugs (including https://bitbucket.org/logilab/pylint/issue/58/ which was annoying all the numpy community), started some refactoring of the PyLinter class so it does a little bit fewer things (still way too many though) and attempted to improve the pylint note on both pylint and astroid, which went down recently "thanks" to the new checks like 'bad-continuation'.

Also, we merged the pylint-brain project into astroid to simplify things, so you should now submit your brain plugins directly to the astroid project. Hopefuly you'll be redirected there on attempt to use the old (removed) pylint-brain project on bitbucket.

And, the good news is that now both Torsten and Claudiu have new powers: they should be able to do some releases of pylint and astroid. To celebrate that and the end of the sprint, we published Pylint 1.3 together with Astroid 1.2. More on this here.

[tarek] ToxMail experiment

Publié le 2014-07-26 11:22:00

I am still looking for a good e-mail replacement that is more respectful of my privacy.

This will never happen with the existing e-mail system due to the way it works: when you send an e-mail to someone, even if you encrypt the body of your e-mail, the metadata will transit from server to server in clear, and the final destination will store it.

Every PGP UX I have tried is terrible anyways. It's just too painful to get things right for someone that has no knowledge (and no desire to have some) of how things work.

What I aiming for now is a separate system to send and receive mails with my close friends and my family. Something that my mother can use like regular e-mails, without any extra work.

I guess some kind of "Darknet for E-mails" where they are no intermediate servers between my mailbox and my mom's mailbox, and no way for a eavesdropper to get the content.

Ideally:

  • end-to-end encryption
  • direct network link between my mom's mail server and me
  • based on existing protocols (SMTP/IMAP/POP3) so my mom can use Thunderbird or I can set her up a Zimbra server.

Project Tox

The Tox Project is a project that aims to replace Skype with a more secured instant messaging system. You can send text, voice and even video messages to your friends.

It's based on NaCL for the crypto bits and in particular the crypto_box API which provides high-level functions to generate public/private key pairs and encrypt/decrypt messages with it.

The other main feature of Tox is its Distributed Hash Table that contains the list of nodes that are connected to the network with their Tox Id.

When you run a Tox-based application, you become part of the Tox network by registering to a few known public nodes.

To send a message to someone, you have to know their Tox Id and send a crypted message using the crypto_box api and the keypair magic.

Tox was created as an instant messaging system, so it has features to add/remove/invite friends, create groups etc. but its core capability is to let you reach out another node given its id, and communicate with it. And that can be any kind of communication.

So e-mails could transit through Tox nodes.

Toxmail experiment

Toxmail is my little experiment to build a secure e-mail system on the top of Tox.

It's a daemon that registers to the Tox network and runs an SMTP service that converts outgoing e-mails to text messages that are sent through Tox. It also converts incoming text messages back into e-mails and stores them in a local Maildir.

Toxmail also runs a simple POP3 server, so it's actually a full stack that can be used through an e-mail client like Thunderbird.

You can just create a new account in Thunderbird, point it to the Toxmail SMPT and POP3 local services, and use it like another e-mail account.

When you want to send someone an e-mail, you have to know their Tox Id, and use TOXID@tox as the recipient.

For example:

7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029@tox

When the SMTP daemon sees this, it tries to send the e-mail to that Tox-ID. What I am planning to do is to have an automatic conversion of regular e-mails using a lookup table the user can maintain. A list of contacts where you provide for each entry an e-mail and a tox id.

End-to-end encryption, no intermediates between the user and the recipient. Ya!

Caveats & Limitations

For ToxMail to work, it needs to be registered to the Tox network all the time.

This limitation can be partially solved by adding in the SMTP daemon a retry feature: if the recipient's node is offline, the mail is stored and it tries to send it later.

But for the e-mail to go through, the two nodes have to be online at the same time at some point.

Maybe a good way to solve this would be to have Toxmail run into a Raspberry-PI plugged into the home internet box. That'd make sense actually: run your own little mail server for all your family/friends conversations.

One major problem though is what to do with e-mails that are to be sent to recipients that are part of your toxmail contact list, but also to recipients that are not using Toxmail. I guess the best thing to do is to fallback to the regular routing in that case, and let the user know.

Anyways, lots of fun playing with this on my spare time.

The prototype is being built here, using Python and the PyTox binding:

https://github.com/tarekziade/toxmail

It has reached a state where you can actually send and receive e-mails :)

I'd love to have feedback on this little project.

[afpyro] AFPyro à Berlin - Vendredi 25 Juillet

Publié le 2014-07-25 00:00:00

Fr

A l’occasion d’EuroPython, venez transpirer au Sanatorium23 [et non Yaam] en dégustant une bonne bière fraiche

Départ groupé à 19h devant le BCC

En

The french python community is organising a non official meetup at Sanatorium23 [not Yaam] on friday. Come an meet us while tasting a fresh beer and dancing

A group will start at 7pm from the BCC

[gvaroquaux] The 2014 international scikit-learn sprint

Publié le 2014-07-24 22:59:58
A week ago, the 2014 edition of the scikit-learn sprint was held in Paris. This was the third time that we held an internation sprint and it was hugely productive, and great fun, as always. Great people and great venues We had a mix of core contributors and newcomers, which is a great combination, as it enables [...]

[rcommande] Papaye: le clone de PyPi

Publié le 2014-07-24 22:00:00
Papaya de ramyo, sur Flickr

Aujourd'hui, je vais vous parler d'un petit projet que je viens de mettre sur les rails. Je l'ai nommé Papaye, comme l'illustration ci-dessus, mais je ne suis pas certain que cela vous aide vraiment à savoir de quoi il s'agit.

C'est tout simplement d'une ré-implémentation du dépôt officiel de modules Python (PyPI pour "Python Packages Index"). Le but étant d'avoir son propre dépôt (sur sa machine ou sur son réseau) et d'y stocker des modules qui n'ont rien à faire sur le dépôt officiel, comme des modules construits par l'intégration continue, pas encore prêt à être diffusés ou tout simplement privés (souvent le cas en entreprise). L'avantage, c'est que l'on conservera toute la puissance de "PIP" pour l'installation !

Autre avantage de l'outil c'est de pouvoir travailler en local et installer des modules sans dépendre du réseau. Et oui, Papaye fait également office de proxy et de cache pour PyPI !

Implémenter ce genre de dépôt n'a vraiment rien de très complexe, d'autant que la majorité de l'intelligence ce situe côté client (via la commande "pip"). De plus, il existe tout un tas de projets similaires (localshop, pypiserver, pyshop, etc...) mais aucun ne correspondait vraiment à ce que je cherchai. J'ai dans un premier temps pensé à contribuer ou "forker" les projets existants, mais j'avais finalement une vision un peu différente des projets que j'avais sous les yeux (l'impression que je pourrai répondre à mon besoin de façon plus simple) et j'avais envie d'un peu ... d'expérimentations! J'ai finalement décidé de commencer le mien "from scratch".

Pourquoi "Papaye" ?

Comme d'habitude, une jeux de mot "tout pourri". Le dépôt officiel s'appelant "PyPI" et étant assez mauvais en anglais et ne n'ai absolument aucune idée de comment cela ce prononce. J'ai remarqué que beaucoup de francophone ont tendance à dire "PaïPaï", certainement parce que "pipi", ce n'est pas génial. Alors, finalement, "Papaye", ça y ressemble beaucoup et il y a une vraie signification en français. J'aime bien l'idée de dire que c'est pareil que le dépôt officiel, mais finalement, un peu différent.

Et puis "Papaye" c'est parfait. Un point c'est tout !

Objectifs

Avant de réaliser ce petit bricolage, voici les objectifs que je me suis fixés :

  • être le plus simple possible à mettre en place. Si possible, que du Python et tout installable via la commande "PIP". Je ne voulais vraiment pas qu'un utilisateur se tape un manuel d'installation de 45 pages pour installer l'outil sachant que je voulais qu'on puisse utiliser l'application aussi bien depuis un serveur qu'en local sur son poste. Je n'aurais pas supporté de perdre patience lors de la mise en place de ma propre application !
  • ne dépendre d'aucun service externe. Donc toute sorte de bases de données sous forme de service à démarrer et à configurer avant d'installer l'application n'est pas envisageable. Tous le monde ne sait pas comment cela fonctionne.
  • tout doit se lancer en une seule ligne de commande. Je passe mon temps à taper plein de commandes en tout genre tout au long de la journée, une seule pour lancer l'application ça suffit largement !
  • faire office de proxy vers le dépôt officiel. Comme ça je fais toujours pointer les fichiers de configuration de "PIP" vers mon instance Papaye qui, elle, redispatchera au bon endroit, c'est beaucoup moins prise de tête à gérer.
  • faire office de cache local pour le dépôt officiel. Une panne réseau ? PyPI non disponible ? On continue de bosser !
  • tailler pour des dépôt de petite et moyenne taille. Pour le moment, ne soyons pas trop ambicieux .

Présentation technique

Là encore, rien de bien compliqué :

  • Python. À bon ? Cela vous surprend toujours ?
  • Pyramid. Mon framework web favoris. J'aime vraiment beaucoup ce framework, mais je n'avais jamais eu l'occasion de mener un projet de bout en bout avec (le syndrome du "projet perso", le projet qu'on commence, qui révolutionnera le monde mais, qui ne sortira jamais par manque de temps :-p). Au boulot, c'est plutôt Django.
  • ZODB. La base de données NOSQL assez surprenante qui permet de stocker des objets Python directement. C'est ce que j'ai trouvé de plus simple et de plus pythonique pour faire du traversal avec Pyramid. Si le mode traversal ne vous dit rien, je vous invite à lire la documentation de Pyramid à ce sujet. C'est vraiment une façon intéressante de concevoir une application web qui tranche radicalement avec l'url dispatch. Les deux méthodes sont combinées dans Papaye.
  • Beaker. Pour mettre en cache les réponses venant du dépôt officiel.

Installation

Comment installer et faire tourner Papaye en quelques commandes :

pip install papaye
wget https://raw.githubusercontent.com/rcommande/papaye/master/production.ini
papaye_init production.ini
pserve production.ini

il ne reste plus qu'à vérifier que le serveur nous réponde (par défaut, à l'adresse http://localhost:6543/simple)

On peut maintenant l'utiliser avec PIP :

pip install -i http://localhost:6543/simple numpy

C'est tout de même plus pratique de configurer le dépôt de façon définitive plutôt que de devoir le préciser à chaque fois. Ça se passe dans le fichier ~/pip.conf. Il suffit d'ajouter la ligne suivante :

[install]
index-url = http://localhost:6543/simple

Ensuite, pour pouvoir envoyer vos modules dans votre instance Papaye, il faut éditer le fichier ~/.pypirc :

[distutils]
index-servers =
    papaye

[papaye]
username: <admin>
password: <password>
repository: http://localhost:6543/simple

Et pour finir, pour envoyer notre module sur le dépôt :

cd /chemin/vers/votre/module
python setup.py sdist upload -v -r papaye

Conclusion

Pour le moment seul l'interface "simple" a été implémenté. Ce n'est pas super sexy mais c'est le minimum pour pouvoir fonctionner avec PIP et Setuptools. En revanche, les fonctions de recherche (commande "pip search <pattern>) ne fonctionneront pas (j'ai manqué d'avoir une crise cardiaque quand j'ai vu que "PIP" communiquait avec le dépôt officiel en XML-RPC ...).

La prochaine étape, c'est une interface pour pouvoir naviguer dans les modules, car, pour le moment, c'est un peu une boite noire et ça ne vend pas du rêve.

Voilà pour mon petit projet du moment. Surtout n'hésitez pas à me faire parvenir vos retours / critiques / contributions / idées / cadeaux / bisous (rayer les mentions inutiles).

Plus d'infos ? C'est par ici

[logilab] EP14 Pylint sprint Day 1 report

Publié le 2014-07-24 14:51:00
https://ep2014.europython.eu/static_media/assets/images/logo.png

We've had a fairly enjoyable and productive first day in our little hidden room at EuroPython in Berlin ! Below are some noticeable things we've worked on and discussed about.

First, we discussed and agreed that while we should at some point cut the cord to the logilab.common package, it will take some time notably because of the usage logilab.common.configuration which would be somewhat costly to replace (and is working pretty well). There are some small steps we should do but basically we should mostly get back some pylint/astroid specific things from logilab.common to astroid or pylint. This should be partly done during the sprint, and remaining work will go to tickets in the tracker.

We also discussed about release management. The point is that we should release more often, so every pylint maintainers should be able to do that easily. Sylvain will write some document about the release procedure and ensure access are granted to the pylint and astroid projects on pypi. We shall release pylint 1.3 / astroid 1.2 soon, and those releases branches will be the last one supporting python < 2.7.

During this first day, we also had the opportunity to meet Carl Crowder, the guy behind http://landscape.io, as well as David Halter which is building the Jedi completion library (https://github.com/davidhalter/jedi). Landscape.io runs pylint on thousands of projects, and it would be nice if we could test beta release on some part of this panel. On the other hand, there are probably many code to share with the Jedi library like the parser and ast generation, as well as a static inference engine. That deserves a sprint on his own though, so we agreed that a nice first step would be to build a common library for import resolution without relying on the python interpreter for that, while handling most of the python dark import features like zip/egg import, .pth files and so one. Indeed that may be two nice future collaborations!

Last but not least, we got some actual work done:

  • Michal Nowikowski from Intel in Poland joined us to work on the ability to run pylint in different processes so it may drastically improve performance on multiple cores box.
  • Torsten did continue some work on various improvements of the functionnal test framework.
  • Sylvain did merge logilab.common.modutils module into astroid as it's mostly driven by astroid and pylint needs. Also fixed the annoying namespace package crash.
  • Claudiu keep up the good work he does daily at improving and fixing pylint :)

[gvaroquaux] Scikit-learn 0.15 release: lots of speedups!

Publié le 2014-07-15 13:25:57
We have just released the 0.15 version of scikit-learn. Hurray!! Thanks to all involved. A long development stretch It’s been a while since the last release of scikit-learn. So a lot has happened. Exactly 2611 commits according my count. Quite clearly, we have more and more existing code, more and more features to support. This means that when [...]

[logilab] PyLint sprint during EuroPython in Berlin

Publié le 2014-07-11 12:51:00

The three main maintainers/developpers of Pylint/astroid (Claudiu, Torsten and I) will meet together in Berlin during EuroPython 2014. While this is not an "official" EuroPython sprint but it's still worth announcing it since it's a good opportunity to meet and enhance Pylint. We should find place and time to work on Pylint between wednesday 23 and friday 25.

If you're interested, don't hesitate to contact me (sylvain.thenault@logilab.fr / @sythenault).