Planète AFPy RSS

[afpyro] AFPyro à Lyon - mercredi 26 novembre

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

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

Cet apéro python sera l’occassion de rencontrer à nouveau les gens de l’AFUP/apéro PHP, autour d’une présentation sur Ruby. Ruby est un langage open source qui met l’accent sur la simplicité et la productivité.

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 : Responsive et Documentation

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

Un exemple de manque de pragmatisme : j’ai déjà vu sur un projet, les intégrateurs faire toute l’intégration d’un site avec flexbox, puis passer des jours à tout refaire dans une autre feuille de style pour IE, alors qu’il était établi dès le départ que IE8 était dans la cible. Ils avaient envie d’utiliser flexbox, ce qui est compréhensible, mais dans ce contexte c’était une perte de temps pour tout le monde. La bonne technique aurait du être de faire une version correcte sur IE8, avec les techniques utilisables (ça ne manque pas), et d’ajouter ensuite les beaux dégradés, ombres, etc… que permet CSS3.

Attitude et éthique du développeur.

La dernière session des cours que je donne à l’IUT a permis d’attaquer un projet qui servira de fil rouge. La plupart se sont mis en groupe de 2 ou 3 et j’ai 2 personnes qui ont préférées faire cavalier seul, l’une pour tout comprendre et l’autre pour garder son indépendance. La rétrospective nous a permis de discuter des améliorations possibles :

  • aborder tout ce qui est relatif à l’approche mobile et responsive ;
  • avoir la possibilité d’afficher des choses sur le vidéoprojecteur (2 fails consécutifs là-dessus avec un adaptateur oublié la première fois et un vidéoprojecteur incompatible la seconde…) ;
  • faire un goûter.

Le prochain cours va donc mettre l’accent sur l’adaptation aux différentes résolutions à l’aide des media-queries en présentant les différents outils comme responsive.is ou des approches comme la responsive typography. Il existe même des moyens de visualiser les principes de base ou de réfléchir en terme de responsive philosophy. Une première étape sera de pouvoir modifier leur menu géré avec Flexbox en changeant la flex-direction de row à column par exemple. Je ne compte pas aller jusqu’à la gestion des différentes résolutions d’images, il y a déjà bien assez à faire en parlant de contenu.

J’ai préparé des cookies pour la pause du goûter, l’occasion de parler de préservation de la vie privée ? :-)

La seconde partie va encore une fois être l’occasion de les mettre en situation en faisant tourner les sources des différents projets entre les groupes et en leur demandant une amélioration mineure. L’occasion de voir à quel point il est difficile de reprendre un projet et l’intérêt d’une documentation haut niveau en plus du styleguide qu’ils ont commencé à faire lors du dernier cours.

Si j’ai un peu de temps on abordera aussi les notions de performances web car j’ai pu remarquer à quel point les élèves sont enclins à rajouter des polices ou des images assez lourdes. C’est l’intérêt d’avoir demandé à récupérer tous les projets par email en imposant d’avoir moins d’1Mo par site. J’ai ainsi pu leur faire un retour personnalisé sur les choses à améliorer, on verra ce qu’ils en ont fait.

[Biologeek] Cours IUT : Flexbox et Styleguide

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

Afin de faire émerger les pratiques personnelles des élèves, renforcer leurs connaissances, il me semble important d’instaurer l’horizontalité dans les rapports humains, au sein de la classe. J’espère pouvoir devenir alors un accompagnateur, un facilitateur, encadrant le processus de maîtrise des concepts de littérature et de grammaire. Le but est de fluidifier la communication, d’augmenter les feedbacks, de rendre les réussites plus accessibles.

D’une sélection artificielle à une sélection naturelle dans un écosystème complexe

Suite de mes aventures dans l’enseignement, après les bases, on passe à du plus consistant. On commence par repartir de zéro sur un sujet qui leur tient à cœur et en plus petit groupes comme proposé en rétro. La première contrainte et d’établir un styleguide en parallèle du développement du site, c’est quelque chose que j’utilise depuis 7 ans et qui dispose maintenant de nombreuses ressources. J’aime cette approche pour plusieurs raisons :

  • réflexion sur la sémantique lorsqu’on se rend compte du nombre d’id/class à ajouter au styleguide pour avoir quelque chose de potable ;
  • documentation dynamique pour les divers contributeurs et pour soi-même, on a vite fait de dupliquer un style par méconnaissance du projet ;
  • facilité d’expérimentation lors de refontes en applicant directement la nouvelle feuille de style au styleguide.

Il s’avère que c’est aussi extrêmement utile en terme de retour pour corriger un bug récalcitrant de façon visuelle.

Le second concept que je souhaite aborder est Flexbox, c’est encore relativement récent mais Vincent me rappelait à juste titre que l’« on enseigne pour aujourd’hui et pour demain » (pour hier, il reste les polyfills) et Flexbox est aussi un moyen de ne pas les dégoûter tout de suite des CSS :-). C’était bien sûr une occasion pour moi de me mettre à niveau dans ce domaine et d’expérimenter, participer à une formation reste la meilleure façon d’apprendre.

Quelques ressources sur le sujet :

Si j’ai le temps, je terminerai sur l’approche mobile et les media-queries pour tirer pleinement partie de Flexbox. Je me rends compte à quel point les minutes sont comptées lorsqu’on est limité à 24 heures de cours sur un sujet aussi vaste…

[cubicweb] CubicWeb roadmap meeting on November 6th, 2014

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

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

Here is the report about the November 6th, 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.17).

If you're still using 3.17, you should go directly to 3.19.

Version 3.18

This version is stable but old and maintained (current is 3.18.6).

Version 3.19

This version is stable and maintained (current is 3.19.5).

Version 3.20

This version is still under development but should be released very soon now (expected next week). Its main feature being the inclusion of CWEP-002 (computed attributes and relations), along with many small improvement patches.

For details read list of tickets for CubicWeb 3.20.0.

We would have loved to integrate the pyramid cube in this release, but the debian packaging effort needed by the pyramid stack is quite big on is only reasonable if we target jessie only (at decent price).

Version 3.21

For now, the roadmap for 3.21 is still the complete removal of the dbapi, the merging of Connection and ClientConnection, and possibly including CWEP-003 (adding a FROM clause to RQL).

Integrate the pyramid cube.

CWEP-004 is being under heavy discussions.

Version 4.0

We expect to accelerate development of CubicWeb 4, which exact roadmap is still to be discussed, but we may already want:

  • be pyramid-based (remove twisted, auth management, etc.),
  • do not have anything left of old dbapi and ClientConnection,
  • integrate squareui as main (and only) web-ui "template" or remove web generation (almost) completely from cubicweb-core and provide it only through the cube system.

CWEPs

Here is the status of open CubicWeb Evolution Proposals:

to be written

Work in progress

Some work is in progress around CKAN, DCAT and othr Open Data and Semantic Web related technologies.

Agenda

Next roadmap meeting will be held at the beginning of january 2015 at Logilab, and Christophe and Dimitri or Yann are invited.

Open Discussions

Migration:

  • AppObjects should be not loaded by default
  • Have a look at Alembic and take inspiration from there

[logilab] PyconFR 2014 : jour 1, bus de communication, packaging et fin

Publié le 2014-11-04 19:26:00

Suite à :

XBUS

Florent Aide nous a présenté son projet XBUS, un bus de communication pour les applications. L'idée est de gérer l'historique : pour faire parler des applications métier entre elles, on les connecte toutes au même bus. Dans certains cas, notamment quand la sécurité des données est en jeux, l'application qui traite le message renvoie un accusé de réception et de traitement (ACK).

Côté technique, il s'agit de :

  • un cœur écrit en Go
  • zmq pour la communication
  • Python pour la logique

Lors des questions un projet similaire a été mentionné : autobahn. Le projet XBUS est libre et publié sur bitbucket.

Comment le packaging m'a simplifié la vie

Étant donné qu'à Logilab, nous avons des avis assez arrêté sur les questions de packaging, je suis allé voir cette conférence.

Xavier Ordoquy nous a présenté en détail virtualenv (pyvenv directement dans python à partir de 3.4) ainsi que l'outil pip.

Historiquement pypi a été instable, mais la situation s'est améliorée depuis qu'il est sur un CDN. Il y a un travail en cours sur la sécurité (vérification d'intégrité, ssl obligatoire etc). devpi permet d'avoir un pypi en interne comme cache, mais aussi comme système de "staging" avant de publier sur le pypi "officiel".

Selon Xavier, la guerre des distutils, python.packaging, distutils2, distribute, etc est finie. Il faut à présent utiliser setuptools et le connaître sur le bouts des doigts. Xavier nous recommande de copier un setup.py pour démarrer nos projets, par exemple celui de sentry.

Côté numéro de version, il faut aller lire la PEP440 Version Identification and Dependency Specification.

extra_requires permet de faire : pip install sentry[postgres] qui installe sentry mais aussi les dépendances pour le faire marcher avec PostgreSQL.

Côté packaging, il va falloir selon Christophe apprendre à utiliser wheel et stevedore (code).

Lors des questions, un membre du public mentionne le projet diecutter (docs, pypi).

Support de présentation : https://speakerdeck.com/xordoquy/packaging-pratique-fr

Autres liens collectés

  • Pour travailler sur les docstrings d'un projet python, pyment peut être utile.
  • fedmsg est un bus de communication utilisé chez fedora/redhat pour un grand nombre d'applications, il y a probablement de bonnes choses dedans. Il y a un début de travail sur un bus similaire chez debian

Prochain épisode

Prochain épisode: jour 2

[logilab] PyconFR 2014 : jour 1, frameworks web et gestion de source

Publié le 2014-11-04 11:28:00

Suite de pyconfr 2014 jour 1 épisode 1.

Performance des frameworks web : Python vs the world

Ronan Amicel nous a présenté le travail de benchmark publié par TechEmpower. Ces tests et résultats sont forcement faux et biaisés, mais le code source des tests est publié en libre et il est donc possible d'apporter des corrections via le projet sur github

Pour l'instant, Python3 serait plus lent que Python2, mais on peut espérer que Python3 rattrape son retard, puisqu'il est toujours développé. La comparaison avec pypy est surprenante, celui-ci est bien plus lent, l'hypothèse étant qu'il est ralenti lorsqu'il parle au driver mysql. En revanche, pour le test pypy + tornado, les performances peuvent être meilleures que nodejs car tornado est écrit en pur python il peut être optimisé par pypy.

Dans le comparatif entre python et php, un acteur surprenant est phalcon qui a pris le parti de tout coder en C (plutôt qu'une partie seulement comme on peut le trouver dans nombre de projets python).

Support de présentation : https://speakerdeck.com/ronnix/performance-des-frameworks-web-python-vs-the-world-v1-dot-1

CubicWeb - Vos données ont du sens

Nous attendions avec impatience cette présentation, et Christophe de Vienne a très bien présenté CubicWeb, le framework web dont Logilab est à l'origine.

https://www.logilab.org/file/269991/raw/logo-cubicweb.png

Après une courte introduction aux concepts du web sémantique (les URIS, les relations, le Linked Data), il a appuyé sur la nécéssité de donner du sens aux données que l'on stoque dans nos applications. Il a expliqué la finesse des réglages dans le moteur de permissions de CubicWeb.

Il a expliqué certaines fonctionnalités intéressantes selon lui dans Cubicweb :

  • les hooks: équivalent des procédures stockées déclenchées par des triggers, ils sont écrits en Python et permettent de modifier des données en cascades, implémenter des règle de gestion ou générer des notifications.
  • les adaptateurs : permettent de maximiser la réutilisation de code en adaptant une entité à une nouvelle interface

Selon Christophe, CubicWeb permet de développer une "base de donnée métier" strictement structurée, mais restant souple. Il a expliqué que l'interface par défaut n'est pas très sexy, mais qu'elle est néanmoins fonctionnelle comme backend d'édition.

Une petite introduction aux cubes qui sont les "plugins" ou les "extensions" dans le monde CubicWeb, ils contiennent :

  • un schéma
  • du code métier
  • des vues
  • des contrôleurs

Pour manipuler les données, CubicWeb utilise RQL, qui a été inventé avant SPARQL (langage de requête du web sémantique) et est plus pragmatique et lisible. Une fonctionnalité notable de RQL : plus besoin d'écrire des jointures SQL !

Finalement Christophe a conclu en présentant le mariage de Pyramid et Cubicweb. Selon lui, en regardant dedans, ils ont des philosophies communes. Le code permettant de développer une application Pyramid sur une base CubicWeb est publié sur la forge de CubicWeb. Christophe a aussi expliqué qu'il pousse des modifications pour que CubicWeb soit plus accessible aux développeurs habitués aux modes de développement "à la python".

Support de présentation : https://dl.dropboxusercontent.com/u/36590471/pyconfr-2014-pres-cubicweb/index.html

La gestion de version, ce problème tellement simple…

Pierre-Yves David (marmoute) nous a concocté un petit panorama des problèmes traités par les gestionnaires de source, avec des anecdotes de problèmes non-triviaux et quelques rappels historiques sur notre "science" informatique (merci les encodages!) Pierre-Yves s'est concentré sur les systèmes de gestion de version de "nouvelle génération", les outils décentralisés (hg, git, bzr). Forcément, étant donné qu'il travaille sur mercurial (et oui, celui écrit en python) il s'est concentré sur celui-là.

http://mercurial.selenic.com/images/mercurial-logo.png

Quand il travaillait chez Logilab, Pierre-Yves a notamment rajouté à Mercurial la notion de changeset obsolete et de phase pour faciliter la revue de code et le travail en équipe.

Manipuler son code python avec RedBaron

baron et RedBaron sont des projets assez prometteurs (et assez dingues) de manipulation de code en utilisant du code (plutôt que des éditeurs).

Laurent Peuch est revenu sur les outils historiques du domaine : rope qui a pris la suite de bicycle repair man. Il y a aussi pyfmt par le même auteur, et autopep8 écrit par d'autres.

Un exemple qui m'a parlé : ajouter @profile sur toutes les fonctions d'un script devient faisable en 3 lignes de python, et inversement pour les enlever. À suivre...

Support de présentation : https://psycojoker.github.io/pyconfr-redbaron/presentation.html

Prochain épisode

Prochain épisode: jour 1, bus de communication, packaging et fin

[Biologeek] Flux et données

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

Probablement une des choses qui change le plus quand on passe d’une architecture dite d’ « entreprise » à l’architecture d’un pure player du web, c’est l’orientation nette vers une logique de flux.

Un architecte d’entreprise vous présentera son architecture en commençant par les grands blocs applicatifs puis continuera par le système d’échange et d’intégration des données entre les différents systèmes applicatifs.

A l’inverse, l’architecte d’un pure player présentera son architecture dans la perspective d’un flux : de la collecte des données à leur mode de persistance en passant par les divers traitements. On a tout de suite le sentiment d’avoir l’orchestration temporelle d’une suite d’événements.

Dans un cas on met l’accès sur les données comme ressources applicatives, dans l’autre on met l’accent sur le flux des données. Là où la première conception est plutôt spatiale et statique, la deuxième est plutôt temporelle et dynamique.

De l’intégration des données

Je vous invite à aller lire le billet complet de Christian et le premier commentaire de Gautier. Il y est question de dualité entre des données stockées dans des bases distribuées et un système de log globalisé. Là où ça devient intéressant, c’est lorsque l’on rapproche ces réflexions de ce qu’a fait Facebook avec Flux :

Flux is the application architecture that Facebook uses for building client-side web applications. It complements React’s composable view components by utilizing a unidirectional data flow. It’s more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code.

Il n’y a plus d’opposition entre statique et dynamique mais une unidirectionnalité du flux de dynamisation du statique. (Ça c’est pour Damien :p.) La problématique ne se pose plus en termes de stockage et de transfert mais en terme d’évolutivité des données. Ainsi on s’abstrait de la nécessité d’un log global en ayant des flux indépendants et isolés, le stockage peut être distribué c’est le dispatcher qui va s’assurer de la cohérence de la modification des données. On se retrouve avec une approche hybride qui est à la fois spatiale et temporelle. L’intégration et le croisement des données est — si l’on fait abstraction des problèmes de performances — plus politique que technique (cf. OpenData et citoyenneté ou OpenData et évaluation), il ne faut pas concentrer les données dans un même log mais réunir les acteurs dans une même pièce ;-).

Je suis extrêmement surpris que les vieux concepts réutilisés dans Flux n’aient pas donné lieux à une prolifération de nouveaux frameworks web. Je suis presque sûr que l’on peut combiner cette approche à asyncio

[logilab] PyconFR 2014 : jour 1, BDD, postgresql et asyncio

Publié le 2014-11-03 19:19:00

J'ai eu le plaisir de participer à la conférence PyconFR 2014, voici quelques notes sur les présentations auxquelles j'ai pu assister. Étant donné la longueur, je vais publier sous forme de plusieurs billets de blog.

http://www.pycon.fr/2014_static/pyconfr/images/banner.png

BDD avec Behave

Le Behaviour Driven Develpment en Python peut se faire avec behave. Dans un premier temps on décrit en language "naturel" le test. Dans un deuxième temps on implémente les tests unitaires pour faire le lien avec la description behave, et on met les chaines de caractères dans un decorateur @given, puis @when puis @then.

Les scenarios behave sont utiles pour le dévelopement, pour la documentation, pour la formation des nouveaux arrivants et même pour faciliter la supervision des applications en production.

Les diapos de la présentation sont disponible sur slideshare.

Python + PostgreSQL

Stéphane Wirtle nous a présenté comment les relations étroites entre le monde de Python et celui de PostgreSQL.

https://avatars1.githubusercontent.com/u/2947270?v=2&s=400

Points à noter :

  • FDW : Foreign Data Wrapper, dont voici une liste sur le wiki de PostgreSQL
  • PL (Procedure Language) : PL/C, PL/Python, PL/v8, etc. pour étendre sa base de donnée. Les procedure language SQL sont par défault "trusted", les autres ne sont pas trusted par défaut. Dans CubicWeb, nous utilisons PL/Python pour la recherche plein texte et la lemmatisation du texte.

Pour ceux qui souhaiteraient essayer un ORM, Stéphane Wirtle conseille Peewee ORM.

Pour les migrations de schema SQLalchemy, Stéphane Wirtle nous conseille Alembic.

Parfois un ORM peut générer beaucoup de requêtes SQL et il y a de la place pour une optimisation en tapant directement du SQL. Pour évaluer la surcharge dûe à l'ORM, on peut utiliser pgBadger.

Support de présentation : https://speakerdeck.com/matrixise/python-and-postgresql-a-wonderful-wedding/

Un serveur fiable avec python 3.4

Après une petite introduction aux principes de concurrence, Martin Richard nous a présenté un retour d'expérience sur l'utilisation du module asyncio introduit dans python 3.4. Il permet de ne plus avoir à utiliser twisted ou gevent.

Les ressources et bibliothèques qui utilisent asyncio sont recensées sur http://asyncio.org/

objgraph permet de d'analyser des structures de données Python pour identifier des fuites memoire.

memoryview introduit dans python3.4 permet de faire "référence" à une structure de données sans la copier, ce qui peut être très pratique mais rend complexe la gestion de code.

Martin a utilisé @lru_cache pour mettre en cache les resultats d'un calcul en utilisant la politique de cache "Least Recently Used (LRU)".

Support de présentation : http://marti.us/t/pyconfr-2014/

Prochain épisode

Prochain épisode : 1ère journée pyconfr, frameworks web et gestion de source.

[j-mad] Django 1.7 et écriture de tests, petites explorations

Publié le 2014-11-02 16:41:50
Je me suis enfin lancé dans l’écriture d’une app django gérant les badges (ou les succès si vous préférez). L’objectif étant de pouvoir réécrire de zéro histoires de rôlistes. L’idée était de tenter de faire une vraie app django, en mode réutilisable, histoire que peut-être des gens puissent trouver intéressant de l’utiliser. Je me suis [...]

[Biologeek] Moments sportifs

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

Ce moment où le cœur ralentit et où chaque cellule réclame sa ration de sucre, de magnésium, de calcium et d’acides aminés. L’organisme se rappelle qu’il lui faut vivre et non plus survivre.

Ce moment où le corps refroidit et où chaque douleur refait surface. La douche brûlante pour essayer de retarder ce nouvel état. Les étirements et les massages pour soulager les muscles, les exercices posturaux pour supporter le reste.

Ce moment où le cerveau s’engourdit et où les images défilent. Passées et à venir, fantasmées et avec désir. Avant de se laisser choir dans les bras de Morphée.

Le temps de la récupération.

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

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

[anybox] Sphinx autodoc et modules OpenERP

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

[Biologeek] Données et secret

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

Je fais le serment de remplir mes fonctions avec conscience, indépendance, et humanité.
Je m’engage à suivre les standards du web, de la qualité et de l’accessibilité pour que le web reste universel, neutre, libre et ouvert.
Je m’engage à respecter et protéger le secret dû aux données personnelles et à la vie privée dont j’aurai connaissance dans l’exécution de mon travail.
Je suis un travailleur du web, j’en suis fier, et j’assumerai mon rôle avec dignité.

Le serment du Beffroi de Montrouge

Cela fait quelques jours que ce serment tourne sur Twitter et j’ai du mal. J’ai donc fini par regarder la vidéo et derrière l’enrobage un peu pompeux et les assertions à faire sourire Miss France, il est surtout question de données personnelles (des autres). J’ai pas mal réfléchi à la question et j’en suis malheureusement arrivé à la conclusion qu’il était illusoire de prétendre avoir le moindre contrôle là-dessus. Les données stockées sur mon ordinateur sont incontrôlables. Je ne sais pas qui y a accès et où elles sont envoyées. Et vous ne savez pas non plus. À moins que :

  • votre ordinateur soit déconnecté ET protégé de tout réseau ET inaccessible physiquement ;
  • vous ayez construit votre ordinateur ainsi que le firmware de chaque puce ;
  • vous ayez pu passer en revue chaque logiciel installé ET chaque mise à jour ET chaque moyen pour mettre à jour ce logiciel.

La liste est bien plus longue mais ces 3 items montrent déjà l’ampleur de la tâche. Aussi « Je m’engage à respecter et protéger le secret dû aux données personnelles et à la vie privée dont j’aurai connaissance dans l’exécution de mon travail. » est un vœux pieux qui ne pourra être respecté. Ou alors il faut être explicite sur les mesures prises pour essayer d’honorer cette déclaration. Par exemple :

  • je m’engage à ne pas effectuer de sauvegardes distantes de ces données en vous éduquant sur ce que cela implique en cas de crash ;
  • je m’engage à chiffrer ces données lorsqu’elles ne sont pas utilisées quotidiennement ET à les supprimer après 30 jours sans utilisation ;
  • je m’engage à ne pas transmettre intentionnellement ces données à un tiers ET à restreindre l’accès physique à ma machine ;
  • je m’engage à vous avertir immédiatement en cas d’accès non autorisé à vos données OU de leur transmission (indépendante de ma volonté) sur un quelconque réseau.

Ce sont les engagements que je m’efforce de tenir au niveau pro avec plus ou moins de succès. C’est faible mais c’est bien au-delà de ce qui est pratiqué habituellement.

Si le problème est un problème d’image et de confiance, je ne vois pas trop ce qu’un serment pourrais nous apporter en matière de crédibilité. Et ce même s’il était signé par — soyons fous — 80% de la profession. La confiance se construit avec de la communication et de l’éducation. Si notre image est actuellement mise à mal à cause des données personnelles qui nous sont confiées : communiquons mieux, éduquons plus.

[AFPy-Nantes] Meetup / Conférences Python le 18 novembre

Publié le 2014-10-27 23:00:00

Pour éviter de faire de l'ombre à la PyConFr (</joke>), nous avons décalé la prochaine rencontre des pythonistes nantais au mois de novembre.

Le meetup est donc prévu le 18 novembre, toujours à La Cantine de Nantes, à partir de 19h.

Au programme cette fois-ci, deux conférences:

  • IPython & dataviz : Quand on pense cartographie, certains pensent logiciels bureautiques, d'autres en ligne, ici nous montrerons qu'il existe d'autres voies en particulier pour l'analyse de données. Ainsi, nous vous proposons de voir l'utilisation de IPython pour découvrir des données et les cartographier. Nous pourrons ainsi introduire quelques bibliothèques pour l'analyse statistique, la manipulation de données et les représentations cartographiques.
  • Pelican : À contre-courant des frameworks web « full-stack », complexes et lourds, se trouve Pelican, et les générateurs de sites statiques. Pourquoi opter pour une approche si minimaliste ? Que peut-on en tirer ? Découvrez l’utilisation de Pelican, ses forces, ses limites, et comment les contourner.

Comme d'habitude, nous espérons vous compter parmi nous pour ces conférences, ainsi pour le verre qui s'en suivra probablement :).

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. :)

[afpyro] AFPyro à Lyon - samedi 25 octobre

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

Un Afpyro aura lieu le 25 octobre à partir de 18h30 au 1929 Label Époque, situé `10 rue de la république, Lyon <http://www.openstreetmap.org/node/1865407690#map=18/45.76571/4.83582`_.

Cet apéro Python accueillera les participants à PyConFr.

Toutes les infos sur la soirée sur le site de PyConFr.

[tarek] Web Application Firewall

Publié le 2014-10-24 14:41:00

Web Application Firewall (WAF) applied to HTTP web services is an interesting concept.

It basically consists of extracting from a web app a set of rules that describes how the endpoints should be used. Then a Firewall proxy can enforce those rules on incoming requests.

Le't say you have a search api where you want to validate that:

  • there's a optional before field that has to be a datetime
  • you want to limit the number of calls per user per minute to 10
  • you want to reject with a 405 any call that uses another HTTP method than GET

Such a rule could look like this:

"/search": {
    "GET": {
        "parameters": {
            "before": {
                "validation":"datetime",
                "required": false
            }
        },
        "limits": {
            "rates": [
                {
                    "seconds": 60,
                    "hits": 10,
                    "match": "header:Authorization AND header:User-Agent or remote_addr"
                }
            ]
        }
    }
}

Where the rate limiter will use the Authorization and the User-Agent header to uniquely identify a user, or the remote IP address if those fields are not present.

Note

We've played a little bit around request validation with Cornice, where you can programmatically describe schemas to validate incoming requests, and the ultimate goal is to make Cornice generate those rules in a spec file independantly from the code.

I've started a new project around this with two colleagues at Mozilla (Julien & Benson), called Videur. We're defining a very basic JSON spec to describe rules on incoming requests:

https://github.com/mozilla/videur/blob/master/spec/VAS.rst

What makes it a very exciting project is that our reference implementation for the proxy is based on NGinx and Lua.

I've written a couple of Lua scripts that get loaded in Nginx, and our Nginx configuration roughly looks like this for any project that has this API spec file:

http {
    server {
        listen 80;
        set $spec_url "http://127.0.0.1:8282/api-specs";
        access_by_lua_file "videur.lua";
    }
}

Instead of manually defining all the proxy rules to point to our app, we're simply pointing the spec file that contains the description of the endpoints and use the lua script to dynamically build all the proxying.

Videur will then make sure incoming requests comply with the rules before passing them to the backend server.

One extra benefit is that Videur will reject any request that's not described in the spec file. This implicit white listing is in itself a good way to avoid improper calls on our stacks.

Last but not least, Lua in Nginx is freaking robust and fast. I am still amazed by the power of this combo. Kudos to Yichun Zhang for the amazing work he's done there.

Videur is being deployed on one project at Mozilla to see how it goes, and if that works well, we'll move forward to more projects and add more features.

And thanks to NginxTest our Lua script are fully tested.

[logilab] PyconFR 2014 - on y va !

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

Pycon.fr est l’événement annuel qui rassemble les utilisateurs et développeurs Python en France, c'est une conférence organisée par l'AFPY (L'Association Francophone Python). Elle se déroulera cette année sur 4 jours à Lyon : 2 jours de conférences, 2 jours de sprints.

http://www.pycon.fr/2014_static/pyconfr/images/banner.png

Nous serons présents à PyconFR les samedi et dimanche pour y voir les présentation nombreuses et prometteuses. Nous assisterons en particulier à deux présentations qui sont liés à l'activité de Logilab :

On espère vous y croiser. Si tout va bien, nous prendrons le temps de faire un compte rendu de ce qui a retenu notre attention lors de la conférence.

[afpyro] AFPyro à Lyon - vendredi 24 octobre

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

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

Si jamais vous venez à PyConFr 2014, et que vous arrivez le vendredi soir, venez retrouver d’autres participants à l’endroits qui accueille la plupart des afpyros lyonnais !

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] Annonce : Logilab présente Saltstack le 3 novembre à la cantine Toulouse

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

Logilab vous invite le lundi 3 novembre à une présentation de Salt à la cantine de Toulouse. Cela se passera de 18 à 20h, avec une présentation suivie d'un moment convivial autour d'un apéritif afin de continuer la discussion.

Plus d'information et inscription sur la page de l'événement à la cantine.

[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

[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 :

[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).

[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. Update : slides publiés sur : https://wiki.postgresql.org/wiki/PostgreSQL_Meetup_Paris_2014_Sept

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

[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

[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

[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 :)

[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 :)

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