Planète AFPy RSS

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

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

Un Afpyro aura lieu le jeudi 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

[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 givin two talks at the conference :

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

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

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

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

[tarek] ToxMail Experiment Cont'd

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

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

To summarize what Toxmail does:

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

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

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

DNS Lookups

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

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

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

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

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

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

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

Offline mode

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

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

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

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

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

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

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

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

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

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

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

[Biologeek] Héritage et immobilier

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

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

La discussion revient souvent donc pour clarifier :

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

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

Pas un tas de cailloux.

[anybox] Sphinx autodoc et modules OpenERP

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

[Biologeek] Jeune photographe

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

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

En attente d’une floraison à venir, Serge Tisseron

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

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

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

Jeune photographe, surprends-toi !

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

[logilab] Pylint 1.3 / Astroid 1.2 released

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

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

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

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

New checks

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

Improved checkers

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

Others changes

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

Astroid changes

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

[logilab] EP14 Pylint sprint Day 2 and 3 reports

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

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

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

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

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

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

[tarek] ToxMail experiment

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

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

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

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

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

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

Ideally:

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

Project Tox

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

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

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

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

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

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

So e-mails could transit through Tox nodes.

Toxmail experiment

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

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

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

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

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

For example:

7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029@tox

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

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

Caveats & Limitations

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

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

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

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

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

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

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

https://github.com/tarekziade/toxmail

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

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

[afpyro] AFPyro à Berlin - Vendredi 25 Juillet

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

Fr

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

Départ groupé à 19h devant le BCC

En

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

A group will start at 7pm from the BCC

[gvaroquaux] The 2014 international scikit-learn sprint

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

[rcommande] Papaye: le clone de PyPi

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

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

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

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

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

Pourquoi "Papaye" ?

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

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

Objectifs

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

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

Présentation technique

Là encore, rien de bien compliqué :

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

Installation

Comment installer et faire tourner Papaye en quelques commandes :

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

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

On peut maintenant l'utiliser avec PIP :

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

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

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

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

[distutils]
index-servers =
    papaye

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

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

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

Conclusion

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

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

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

Plus d'infos ? C'est par ici

[logilab] EP14 Pylint sprint Day 1 report

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

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

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

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

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

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

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

[Biologeek] Lecture et joie

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

Je ne milite en aucun cas pour l’abolition de l’école. Je crois, effectivement, qu’il serait catastrophique, en l’état actuel des choses, de la supprimer. Je pense, effectivement, qu’il y a de nombreux parents qui ne pourraient, ne voudraient ou ne sauraient en aucun cas assumer cette nouvelle condition ; je pense, effectivement, que la situation actuelle de nombreuses personnes rendrait irréaliste, voire périlleuse, la non-scolarisation de leurs enfants.

Mais quid de tous ceux qui en ont la possibilité et, peut-être, le désir, mais qui l’ignorent ? C’est à eux que mon témoignage offre, je l’espère, l’inspiration pour une pensée nouvelle. Respecter ses convictions, faire, en toute conscience, des choix personnels, honorer son originalité, être l’artisan de son propre devenir : tout cela, bien davantage que l’endoctrinement des masses, contribue à la progression du monde et à l’apparition de nouveaux paradigmes.

… et je ne suis jamais allé à l’école, André Stern

J’ai terminé de lire … et je ne suis jamais allé à l’école à mon fils. Quelques pages quasiment chaque jour depuis 3 mois. La joie qu’il a manifesté lorsque j’ai sorti le livre les dernières fois m’a vraiment ému. Identifier le livre comme un moment de bonheur. Comme une vaine tentative de le dévorer littéralement aussi :-).

Au fil des pages, je me suis rendu compte à quel point ma lecture à voix haute a changée, une meilleure continuité, une meilleure gestion des liaisons, des différentes voix des personnages. Essayer de rendre la forme aussi intéressante que le fond a été un exercice quotidien, pour une lecture plus lente, plus détaillée, plus profonde. La prose d’André Stern se prête bien à une telle lecture et le propos est lucide et sensé, ça donne des idées…

Prochaine lecture : Libres enfants de Summerhill.

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

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

[logilab] PyLint sprint during EuroPython in Berlin

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

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

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

[cubicweb] CubicWeb roadmap meeting on July 3rd, 2014

Publié le 2014-07-07 14:18:00

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

Here is the report about the July 3rd, 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.15 with 3.17.16 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 was published at the end of April and has now been tested on our internal servers. It includes support for Cross Origin Resource Sharing (CORS) and a heavy refactoring that modifies sessions and sources to lay the path for CubicWeb 4.

For details read the release notes or the list of tickets for CubicWeb 3.19.0. Current is 3.19.2

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 (or maybe 4.0?)

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

Cubes

Cubes published over the past two months

New cubes

  • cubicweb-frbr: Cube providing a schema based on FRBR entities
  • cubicweb-clinipath
  • cubicweb-fastimport

CWEPs

Here is the status of open CubicWeb Evolution Proposals:

CWEP-0002 only missing a bit of migration support, to be finished soon for inclusion in 3.20.

CWEP-0003 has been reviewed and is waiting for a bit of reshaping that should occurs soon. It's targeted for 3.21.

New CWEPs are expected to be written for clarifying the API of the _cw object, supporting persistent sessions and improving the performance of massive imports.

Work in progress

Design

The new logo is now published in the 3.19 line. David showed us his experimentation that modernize a forge's ui with a bit of CSS. There is still a bit of pressure on the bootstrap side though, as it still rely on heavy monkey-patching in the cubicweb-bootstrap cube.

Data import

Also, Dimitry expressed is concerns with the lack of proper data import API. We should soon have some feedback from Aurelien's cubicweb-fastimport experimentation, which may be an answer to Dimitry's need. In the end, we somewhat agreed that there were different needs (eg massive-no-consistency import vs not-so-big-but-still-safe), that cubicweb.dataimport was an attempt to answer them all and then cubicweb-dataio and cubicweb-fastimport were more specific responses. In the end we may reasonably hope that an API will emerge.

Removals

On his way to persistent sessions, Aurélien made a huge progress toward silence of warnings in the 3.19 tests. dbapi has been removed, ClientConnection / Connection merged. We decided to take some time to think about the recurring task management as it is related to other tricky topics (application / instance configuration) and it's not directly related to persistent session.

Rebasing on Pyramid

Last but not least, Christophe demonstrated that CubicWeb could basically live with Pyramid. This experimentation will be pursued as it sounds very promising to get the good parts from the two framework.

Agenda

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

[logilab] Nazca notebooks

Publié le 2014-07-07 12:44:00

We have just published the following ipython notebooks explaining how to perform record linkage and entities matching with Nazca:

[tarek] NGinxTest

Publié le 2014-06-29 09:40:00

I've been playing with Lua and Nginx lately, using the OpenResty bundle.

This bundle is an Nginx distribution on steroids, that includes some extensions and in particular the HTTPLuaModule which let you script Nginx using the Lua programming language.

Coming from a Python background, I was quite pleased with the Lua syntax, which feels like a cleaner Javascript inspired from Pascal and Python - if that even makes any sense :)

Here's how a Lua function look like:

-- rate limiting
function rate_limit(remote_ip, stats)
    local hits = stats:get(remote_ip)
    if hits == nil then
        stats:set(remote_ip, 1, throttle_time)
        return false
    end

    hits = hits + 1
    stats:set(remote_ip, hits, throttle_time)
    return hits >= max_hits
end

Peformance-wise, interacting with incoming web requests in Lua co-routines in Nginx is blazing fast. And there are a lot of work that can be done there to spare your proxied Python/Node.js/Go/Whatever application some cycles and complexity.

It can also help you standardize and reuse good practices across all your web apps no matter what language/framework they use.

Some things that can be done there:

  • web application firewalling
  • caching
  • dynamic routing
  • logging, load balancing
  • a ton of other pre-work...

To put it simply:

Nginx become very easy to extend with Lua scripting without having to re-compile it all the time, and Lua lowers the barrier for ops and developers to implement new server behaviors.

Testing with Test::Nginx

When you start to add some Lua scripting in your Nginx environment, testing soon become mandatory. Pure unit testing Lua scripts in that context is quite hard because you are interacting with Nginx variables and functions.

The other approach is doing only pure functional tests by launching Nginx with the Lua script loaded, and interacting with the server using an HTTP client.

OpenResty offers a Perl tool to do this, called Test::Nginx where you can describe in a light DSL an interaction with the NGinx server.

Example from the documentation:

# foo.t
use Test::Nginx::Socket;
repeat_each(1);
plan tests => 2 * repeat_each() * blocks();
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;  # make this env take a default value
run_tests();

__DATA__

=== TEST 1: sanity
--- config
location /foo {
    set $memc_cmd set;
    set $memc_key foo;
    set $memc_value bar;
    memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
}
--- request
    GET /foo
--- response_body_like: STORED
--- error_code: 201

The data section of the Perl script describes the Nginx configuration, the request made and the expected response body and status code.

For simple tests it's quite handy, but as soon as you want to do more complex tests it becomes hard to use the DSL. In my case I needed to run a series of requests in a precise timing to test my rate limiting script.

I missed my usual tools like WebTest, where you can write plain Python to interact with a web server.

Testing with NginxTest

Starting and stopping an Nginx server with a specific configuration loaded is not hard, so I started a small project in Python in order to be able to write my tests using WebTest.

It's called NGinxTest and has no ambitions to provide all the features the Perl tool provides, but is good enough to write complex scenarios in WebTest or whatever Python HTTP client you want in a Python unit test class.

The project provides a NginxServer class that takes care of driving an Nginx server.

Here's a full example of a test using it:

import os
import unittest
import time

from webtest import TestApp
from nginxtest.server import NginxServer

LIBDIR = os.path.normpath(os.path.join(os.path.dirname(__file__),
                        '..', 'lib'))
LUA_SCRIPT = os.path.join(LIBDIR, 'rate_limit.lua')

_HTTP_OPTIONS = """\
lua_package_path "%s/?.lua;;";
lua_shared_dict stats 100k;
""" % LIBDIR


_SERVER_OPTIONS = """\
set $max_hits 4;
set $throttle_time 0.3;
access_by_lua_file '%s/rate_limit.lua';
""" % LIBDIR


class TestMyNginx(unittest.TestCase):

    def setUp(self):
        hello = {'path': '/hello', 'definition': 'echo "hello";'}
        self.nginx = NginxServer(locations=[hello],
                                http_options=_HTTP_OPTIONS,
                                server_options=_SERVER_OPTIONS)
        self.nginx.start()
        self.app = TestApp(self.nginx.root_url, lint=True)

    def tearDown(self):
        self.nginx.stop()

    def test_rate(self):
        # the 3rd call should be returning a 429
        self.app.get('/hello', status=200)
        self.app.get('/hello', status=200)
        self.app.get('/hello', status=404)

    def test_rate2(self):
        # the 3rd call should be returning a 200
        # because the blacklist is ttled
        self.app.get('/hello', status=200)
        self.app.get('/hello', status=200)
        time.sleep(.4)
        self.app.get('/hello', status=200)

Like the Perl script, you provide bits of configuration for your Nginx server -- in this case pointing the Lua script to test and some general configuration.

Then I test my rate limiting feature using Nose:

$ bin/nosetests -sv tests/test_rate_limit.py
test_rate (test_rate_limit.TestMyNginx) ... ok
test_rate2 (test_rate_limit.TestMyNginx) ... ok

----------------------------------------------------------------------
Ran 2 tests in 1.196s

OK

Out of the 1.2 seconds, the test sleeps half a second, and the class starts and stops a full Nginx server twice. Not too bad!

I have not released that project at PyPI - but if you think it's useful to you and if you want some more features in it, let me know!

[tarek] Decentralization Mailing List

Publié le 2014-06-27 14:20:00

This is long time due !

Following up with my previous blog post I have started a Decentralization Mailing list.

The goal of this mailing list is to discuss technologies related to data decentralization in Mozilla projects - and in particular in the ones we work at in the Cloud Services team (but it can go beyond of course)

A few topic examples that people brought up:

  1. Could remoteStorage be used with Firefox Account to build Firefox OS apps where people can store their own data ?
  2. Can Firefox Sync use a remoteStorage backend ?
  3. Why can't I run a simple "apt-get install firefox-sync" and host my own server ?
  4. What about peer-to-peer ? How does that fit with the services we provide ?

The list is at : https://lists.mozilla.org/listinfo/dev-decentralization

I will wait a week or so to launch topics there, but if you are interested in this topic, if you want to lurk or to launch an idea - please join.

On my side, the first topic I will probably talk about in this ML is #1.

[afpyro] AFPyro à Lyon - mercredi 25 juin

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

Un Afpyro aura lieu le mercredi 25 juin à partir de 20h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Cette soirée aura pour thème Docker avec deux présentations :

  • Docker 101 par Geoffrey Bachelet
  • Docker et Python par Haïkel Guémar

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] Éducation et informatique

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

Moins les enfants regarderont les écrans, plus ils développeront leur imagination et leur créativité. Car les écrans contiennent en eux des histoires visuelles et sonores qui empêcheraient les enfants d’imaginer d’autres images et d’autres mondes possibles.

Écran global, reportage de Anne-Sophie Lévy-Chambon

Protéger son enfant des écrans s’avère être une tâche plus difficile que ce que j’imaginais. Le compteur en cumulé doit être aux alentours des 10-15 minutes après 7 mois, ce qui est plutôt dans la limite haute de ce que je m’étais fixé. Et lorsque je vois l’attrait qu’il a pour un écran dès qu’il en croise un, cela me conforte dans l’idée qu’il va falloir attendre qu’il soit en mesure de comprendre un peu ce qu’il y a derrière : une fenêtre déshumanisée sur l’Humanité.

On parle souvent de la limite des 3 ans pour qu’un enfant puisse regarder/interagir avec un écran sans être perturbé par l’absence de retour de sa part. On verra à ce moment là si mon digital native souhaite faire usage de ses doigts.

L’élève sait que les équipements informatiques utilisent une information codée et il est initié au fonctionnement, au processus et aux règles des langages informatiques ; il est capable de réaliser de petites applications utilisant des algorithmes simples.

Socle commun de connaissances, de compétences et de culture

Damien B et Éric D. discutaient ce soir de l’apprentissage du code en primaire sur Twitter. J’ai beaucoup de mal avec cette question car le code constitue une part non négligeable de mon quotidien et de mon métier. Et si je trouve que la connaissance du Web devrait faire partie de l’éducation citoyenne, je suis plus circonspect sur le développement en lui-même. En fait, il s’agit d’une problématique de cohérence. Soit on considère que le codage (sic) est une activité artisanale et dans ce cas il faudrait également enseigner d’autres activités comme le travail du bois en primaire (ce que certaines écoles alternatives font — voir le reportage sus-cité). Soit on considère que l’industrialisation de l’informatique est inévitable et dans ce cas là toute la question algorithmique simple devient inutile puisqu’il s’agira d’empiler les boîtes noires à un autre niveau. Il faut bien définir les objectifs que l’on se fixe avec cet apprentissage du code dès la primaire. Dans quelle mesure permet-il la poursuite d’études, la construction d’un avenir personnel et professionnel et préparer à l’exercice de la citoyenneté ? Tous bidouilleurs, soit, mais que nous laisse-t-on bidouiller par la suite ?

Ce que je vois en filigrane de cette mutation est plus grave, c’est la mise sur un piédestal de ceux qui savent coder par pure incompréhension du changement de paradigme qui est en train de s’effectuer avec le numérique. Ou serait-ce pour pouvoir à terme alimenter plus facilement les canons publicitaires ? La question reste ouverte… jusqu’à la prochaine réforme.

[logilab] Tester MPI avec CMake et un framework de test comme Boost

Publié le 2014-06-20 12:12:00

Objectif

Compiler et exécuter un fichier de test unitaire avec MPI.

Je suppose que :

  • une implémentation de MPI est installée (nous prendrons OpenMPI)
  • les bibliothèques Boost MPI et Boost Unit Test Framework sont présentes
  • vous connaissez quelques rudiments de CMake

CMake

On utilise le bien connu find_package pour Boost et MPI afin de récupérer tout ce qu'il nous faut pour les headers et les futurs links.

find_package (MPI REQUIRED)
find_package (Boost COMPONENTS mpi REQUIRED)

# Boost dirs for headers and libs.
include_directories (SYSTEM ${Boost_INCLUDE_DIR})
link_directories (${Boost_LIBRARY_DIRS})

Par la suite, on a essentiellement besoin des variables CMake :

  • Boost_MPI_LIBRARY pour le link avec Boost::MPI
  • MPI_CXX_LIBRARIES pour le link avec la bibliothèque OpenMPI
  • MPIEXEC qui nous donne la commande pour lancer un exécutable via MPI

On prend un fichier example_mpi.cpp (des exemples simples sont faciles à trouver sur la Toile). Pour le compiler, on fait :

set(CMAKE_CXX_COMPILER mpicxx)

# MPI example.
add_executable(example_mpi example_mpi.cpp)
target_link_libraries(example_mpi ${MPI_CXX_LIBRARIES})

voire juste

target_link_libraries(example_mpi ${Boost_MPI_LIBRARY})

si on décide d'utiliser la bibliothèque Boost MPI.

Note

mpicxx est une commande qui enrobe le compilateur (g++ par exemple). On dit à CMake d'utiliser mpicxx au lieu du compilo par défaut.

Note

Boost::MPI n'est pas une implémentation de MPI. C'est une bibliothèque plus haut niveau qui s'abstrait de l'implémentation de MPI. Il faut nécessairement en installer une (OpenMPI, LAM/MPI, MPICH2, ...).

L'exemple peut très simplement ressembler à :

#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>

namespace mpi = boost::mpi;

int main()
{
  mpi::environment env;
  mpi::communicator world;
  std::cout << "I am process " << world.rank() << " of " << world.size()
            << "." << std::endl;
  return 0;
}

Exécuter

Une fois la compilation effectuée, faire simplement :

> mpiexec -np 4 ./example_mpi

pour lancer l'exécutable sur 4 cœurs.

Problème : mais pourquoi tu testes ?

On veut pouvoir faire des exécutables qui soient de vrais tests unitaires et non pas un exemple avec juste une fonction main. De plus, comme j'utilise CMake, je veux pouvoir automatiser le lancement de tous mes exécutables via CTest.

Problème : il faut bien initialiser et bien dire à MPI que j'en ai fini avec toutes mes MPI-series.

En "vrai" MPI, on a :

int main(int argc, char* argv[])
{
  MPI_Init(&argc, &argv);

  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  // Code here..
  // ... and here
  MPI_Finalize();

  return 0;
}

Note

C'est ce que fait le constructeur/destructeur de boost::mpi::environment.

En d'autres termes, je veux me faire ma propre fonction main pour l'initialisation de tous mes cas tests Boost (ou avec n'importe quel autre framework de test unitaire C/C++).

La documentation de Boost Unit Test, que je trouve parfois très peu claire avec un manque cruel d'exemple, m'a fait galérer quelques heures avant de trouver quelque chose de simple qui fonctionne.

Conseil : aller regarder les exemples des sources en faisant quelques grep est parfois plus efficace que de trouver la bonne info dans la doc en ligne. On peut aussi en lire sur https://github.com/boostorg/test/tree/master/example

Deux solutions :

  1. la première que j'ai trouvée dans les tests de Boost::MPI lui-même. Ils utilisent le minimal testing facility. Mais seule la macro BOOST_CHECK est utilisable. Et oubliez les BOOST_CHECK_EQUAL ainsi que l'enregistrement automatique de vos tests dans la suite de tests.
  2. la deuxième redéfinit la fonction main et appelle boost::unit_test::unit_test_main sans définir ni la macro BOOST_TEST_MODULE ni BOOST_TEST_MAIN qui impliquent la génération automatique de la fonction main par le framework de test (que l'on compile en statique ou dynamique). Pour plus de détails, lire http://www.boost.org/doc/libs/release/libs/test/doc/html/utf/user-guide/test-runners.html

J'utiliserai la deuxième solution.

Note

Ne pensez même pas faire une fixture Boost pour y mettre votre boost::mpi::environment puisque cette dernière sera construite/détruite pour chaque cas test (équivalent du setUp/tearDown). Et il est fort probable que vous ayez ce genre d'erreur :

*** The MPI_Errhandler_set() function was called after MPI_FINALIZE was invoked.
*** This is disallowed by the MPI standard.
*** Your MPI job will now abort.
[hostname:11843] Abort after MPI_FINALIZE completed successfully; not able to guarantee that all other processes were killed!

Un exemple qui marche

On souhaite ici tester que le nombre de procs passés en argument de mpiexec est au moins 2.

Le BOOST_TEST_DYN_LINK dit juste que je vais me lier dynamiquement à Boost::Test.

#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>

namespace mpi = boost::mpi;

BOOST_AUTO_TEST_CASE(test_check_world_size)
{
    mpi::communicator world;
    BOOST_CHECK(world.size() > 1);
}


// (empty) Initialization function. Can't use testing tools here.
bool init_function()
{
    return true;
}

int main(int argc, char* argv[])
{
    mpi::environment env(argc, argv);
    return ::boost::unit_test::unit_test_main( &init_function, argc, argv );
}

On lance tout ça avec un joli mpiexec -np 2 ./test_mpi et on est (presque) content.

Et un peu de CTest pour finir

Une dernière chose : on aimerait dire à CMake via CTest de lancer cet exécutable, mais avec mpiexec et les arguments qui vont bien.

Un cmake --help-command add_test nous indique qu'il est possible de lancer n'importe quel exécutable avec un nombre variable d'arguments. On va donc lui passer : /usr/bin/mpiexec -np NB_PROC ./test_mpi.

Un œil au module FindMPI.cmake nous dit aussi qu'on peut utiliser d'autres variables CMake MPI pour ce genre de chose.

Reprenons donc notre fichier CMake et ajoutons :

add_executable(test_mpi test_mpi.cpp)
target_link_libraries(test_mpi ${Boost_MPI_LIBRARY})
# Number of procs for MPI.
set (PROCS 2)
# Command to launch by CTest. Need the MPI executable and the number of procs.
add_test (test_mpi ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${PROCS}
   ${MPIEXEC_PREFLAGS}
   test_mpi
   ${MPIEXEC_POSTFLAGS})

où mon exécutable et mon test porte le même nom : test_mpi. On lance le tout avec la commande ctest dans notre dossier de build et hop, le tour est joué !

[Biologeek] Écriture et bonheur

Publié le 2014-06-20 11:00:00

Difficile d’écrire sur le bonheur. Sans faire dans le mièvre. Sans tomber dans les clichés. Sans craindre d’attiser les convoitises et jalousies. Sans avoir peur surtout de briser cet instant en tentant de le décrire. Sans mentir.

6 mois de vie. De survie. De co-vie. Je ne sais pas trop comment appeler cela, ni de quel point de vue. Toujours est-il que ça semble fonctionner. Des doutes, des essais, des désespoirs, des soulagements. Des moments spéciaux. Inattendus. Intimes.

Apprendre à flâner avec une poussette. Se défendre des fumées et des bruits de la ville. Réduire son exposition aux écrans. Se nourrir plus sainement. Sourire très souvent. Apprécier ce rythme plus lent qui contribue au bien-être. Et au bonheur.

Songer à cette question de l’héritage. Vouloir léguer des valeurs et une culture plus que des biens. Amasser du temps de vivre ensemble. Donner son attention avant tout. Et sentir qu’il s’agit d’un échange. Réciproque et gratuit.

Rire et s’émerveiller des nouveautés. Se demander qui éduque qui. S’endormir épuisé mais heureux. Se réveiller sur un simple sourire. Apprendre à se connaître, à apprécier des rituels. À cohabiter.

Et au milieu de tout cela des questionnements. Pourquoi est-ce que j’ai choisi de passer autant de temps avec mon fils ? Comment lui transmettre des valeurs sans ressentir la pression de l’exemplarité ? Quel enseignement lui proposer avant qu’il ne puisse choisir par lui-même ? Quels « effets papillons » lui permettront à terme de battre de ses propres ailes ? Quelle image va-t-il me renvoyer de moi-même ? Que ressent-il vraiment ? Et tant d’autres.

Fermer les yeux. Respirer. Faire le vide. Sourire. Se sentir bien.

[afpyro] AFPyro à Pau - Jeudi 19 Juin

Publié le 2014-06-19 00:00:00

Un Afpyro aura lieu le Jeudi 19 Juin à partir de 20h au Fablab de Pau

Venez rencontrer et échanger avec la comunauté pythoniste paloise en vous délectant de succulant breuvages!

Fablab

4 rue despourrins

64000 PAU

Voir la map

[sciunto] Utiliser pyserial pour dialoguer avec une balance et un port série

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

Dans mon billet précédent, je présentais une méthode permettant d'obtenir la valeur d'un afficheur à partir d'une prise de photos et d'un traitement d'images suivis d'un machine-learning.

Je passe maintenant au cas où l'appareil est doté d'un port série et de la documentation qui va avec. Je connecte donc ma machine à un adapatateur usb/série et le device apparait dans /dev/ttyUSB0.

On sort python et sa bibliothèque pyserial. Je souhaite ici récupérer la masse en fonction du temps d'une balance Mettler Toledo XS105. Dans la doc, je sais que je dois envoyer la commande 'SI' et que la balance me répondra (même si elle n'est pas stable, cf doc).

Je commence par écrire une petite fonction qui va me récupérer tout ça.

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# License: GPLv3

# Parameters for the Mettler Toledo XS105 scale:
# 9600
# 8/No
# 1 stopbit
# Xon/Xoff
# <CR><LF>
# Ansi/win
# Off

import serial
import time
import re


def read_weight(socket, timelapse=1):
    """
    Returns the weight in gram and the stability.

    :param socket: serial socket
    :param timelapse: timelapse between each measurement
    :returns: tuple (weight, stability)
    """
    ser.write('\nSI\n')
    time.sleep(1)
    value = ser.read(ser.inWaiting())
    value = value.split('\n')[1][:-1]
    if value[3] == 'S':
        stability = True
    else:
        stability = False
    weight = value[4:-1].strip(' ')
    return (weight, stability)

Ensuite, je procède à l'ouverture d'une socket avec les options que j'ai configuré dans la balance, puis je boucle sur ma fonction pour récupérer régulièrement la masse. Le programme se termine avec un Ctrl-C.

if __name__ == '__main__':

    ser = serial.Serial(port='/dev/ttyUSB0',
                        baudrate=9600,
                        parity=serial.PARITY_NONE,
                        stopbits=serial.STOPBITS_ONE,
                        bytesize=serial.EIGHTBITS
    )

    if not ser.isOpen():
        ser.open()
    with open('data.dat', 'w') as fh:
        fh.write('# Time (s) | Weight (g) | Stability')
        zerotimer = time.time()  # perf_counter might be better py3
        try:
            while True:
                weight, stability = read_weight(ser)
                timer = time.time() - zerotimer
                print('t = ' + str(timer) + 's | M = ' + str(weight) + ' g')
                fh.write(str(timer) + ' ' + weight + ' ' + str(stability) +'\n')
        except KeyboardInterrupt:
            fh.close()

Et voilà !

[logilab] Open Legislative Data Conference 2014

Publié le 2014-06-10 15:57:00

I was at the Open Legislative Data Conference on may 28 2014 in Paris, to present a simple demo I worked on since the same event that happened two years ago.

The demo was called "Law is Code Rebooted with CubicWeb". It featured the use of the cubicweb-vcreview component to display the amendments of the hospital law ("loi hospitalière") gathered into a version control system (namely Mercurial).

The basic idea is to compare writing code and writing law, for both are collaborative and distributed writing processes. Could we reuse for the second one the tools developed for the first?

Here are the slides and a few screenshots.

http://www.logilab.org/file/253394/raw/lawiscode1.png

Statistics with queries embedded in report page.

http://www.logilab.org/file/253400/raw/lawiscode2.png

List of amendments.

http://www.logilab.org/file/253396/raw/lawiscode3.png

User comment on an amendment.

While attending the conference, I enjoyed several interesting talks and chats with other participants, including:

  1. the study of co-sponsorship of proposals in the french parliament
  2. data.senat.fr announcing their use of PostgreSQL and JSON.
  3. and last but not least, the great work done by RegardsCitoyens and SciencesPo MediaLab on visualizing the law making process.

Thanks to the organisation team and the other speakers. Hope to see you again!

[sciunto] Détection de nombres d'un afficheur avec scikit-image et scikit-learn

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

Dans ce billet, je propose de traiter le problème suivant. Prenons le cas d'un appareil possédant un afficheur digital tel qu'une balance, un voltmètre, un réveil, un hygromètre... mais ne possédant pas de moyen simple de récupérer les données (absence de port série etc). Si on souhaite collecter les données, deux méthodes s'offrent à nous. La première est celle de l'électronicien qui consiste à mettre un moyen de communication là où il n'y en a pas. L'inconvénient est qu'il faut avoir une compétence (que je n'ai pas) et qu'il faut faire du cas par cas. La seconde technique est de prendre en photo l'afficheur et d'analyser les images. C'est ce qu'on va faire ici.

Pour la démonstration, je vais utiliser python, une balance dont la masse affichée fluctue au cours du temps et les photos de l'afficheur.

Une fois le lot de photos sur le disque (ex: Img0001.png), on va chercher à détecter les chiffres (ou digits). Scikit-image va nous être précieux. Il nous faut :

  • appliquer un seuil à l'image pour enlever les parasites et passer en binaire. Otsu est intéressant car local, ce qui permet de se prémunir de variation de contraste à grande échelle.
  • connecter les morceaux dans le cas d'un afficheur 7 segments ou d'un seuillage trop agressif.
  • remplir les trous pour qu'il ne soit pas détecté comme objet
  • étiqueter les régions et ne considérer que celles supérieures à une taille critique
  • les extraire

Ceci est fait par ce code (qui manque encore de soin)

import os.path
import glob

import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

import skimage.io
from skimage.filter import threshold_otsu
from skimage.segmentation import clear_border
from skimage.morphology import closing, square
from skimage.measure import regionprops, label
from skimage.color import label2rgb


def segment_digit(image, filename, output_dir, digit_height=100, digit_width=52,
                  border=7, black_on_white=True, closingpx=4):
    """
    Segement each digit of a picture

    :param image: grey scale picture
    :param filename: filename of the picture source
    :param output_dir: path for the output
    :param digit_height: height of a digit
    :param digit_width: width of a digit
    :param border: pixels to shift the border
    :param black_on_white: black digit on clear background
    :param closingpx: number of pixels to close
    """
    # apply threshold
    thresh = threshold_otsu(image)
    if black_on_white:
        bw = closing(image > thresh, square(closingpx))
    else:
        bw = closing(image < thresh, square(closingpx))

    filled = ndimage.binary_fill_holes(bw)
    #plt.imshow(filled)
    #plt.show()

    # remove artifacts connected to image border
    cleared = filled.copy()
    clear_border(cleared)

    # label image regions
    label_image = label(cleared)
    borders = np.logical_xor(filled, cleared)
    label_image[borders] = -1
    image_label_overlay = label2rgb(label_image, image=image)

    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(image_label_overlay)

    regions = regionprops(label_image)

    for item, region in enumerate(regions):
        # skip small elements
        if region['Area'] < 300:
            continue

        # draw rectangle around segmented digits
        minr, minc, maxr, maxc = region['BoundingBox']
        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                                  fill=False, edgecolor='red', linewidth=2)

        # uniq size
        img = np.zeros((100, 75), 'uint8')
        img[bw[minr:maxr, minc:maxc]!=0] = 255
        newname = os.path.splitext(os.path.basename(filename))[0] + '-' + str(item) + '.png'
        skimage.io.imsave(os.path.join(output_dir, newname), img)
        ax.add_patch(rect)

    plt.show()
Segmentation de chaque digit

Segmentation de chaque digit

On s'est donc fabriqué un lot d'images (Img0001-0.png, Img0001-1.png...) correspondant à chaque digit.

Il nous reste maintenant à les identifier. Une première méthode serait de faire du template matching, mais ça peut vite s'avérer peu robuste. On va donc préférer passer par du machine-learning. Scikit-learn est là pour ça.

Le principe :

  • On identifie un sous lot d'images. Dans mon cas, j'ai identifié trois images pour chaque digit (donc 30) et elles sont nommées sous la forme digit-id.png).
  • On entraine l'algorithme sur ces images identifiées.
  • On demande de deviner les images inconnues.

Pour la partie connue :

import glob
import os

import numpy as np
import pylab as pl

from sklearn import svm, metrics
import skimage.io

def load_knowndata(filenames):
    training = {'images': [], 'targets': [], 'data' : [], 'name' : []}

    for index, filename in enumerate(filenames):
        target = os.path.splitext(os.path.basename(filename))[0]
        target = int(target.split('-')[0])
        image = skimage.io.imread(filename)
        training['targets'].append(target)
        training['images'].append(image)
        training['name'].append(filename)
        training['data'].append(image.flatten().tolist())
        pl.subplot(6, 5, index + 1)
        pl.axis('off')
        pl.imshow(image, cmap=pl.cm.gray_r, interpolation='nearest')
        pl.title('Training: %i' % target)

    ## To apply an classifier on this data, we need to flatten the image, to
    ## turn the data in a (samples, feature) matrix:
    n_samples = len(training['images'])
    training['images'] = np.array(training['images'])
    training['targets'] = np.array(training['targets'])
    training['data'] = np.array(training['data'])
    return training

Pour la partie inconnue :

def load_unknowndata(filenames):
    training = {'images': [], 'targets': [], 'data' : [], 'name' : []}

    for index, filename in enumerate(filenames):
        image = skimage.io.imread(filename)
        training['targets'].append(-1) # Target = -1: unkown
        training['images'].append(image)
        training['name'].append(filename)
        training['data'].append(image.flatten().tolist())

    ## To apply an classifier on this data, we need to flatten the image, to
    ## turn the data in a (samples, feature) matrix:
    n_samples = len(training['images'])
    training['images'] = np.array(training['images'])
    training['targets'] = np.array(training['targets'])
    training['data'] = np.array(training['data'])
    return training

et on écrit un main rapidement pour enchainer tout ça


if __name__ == '__main__':
    filenames = sorted(glob.glob('learn/*-*.png'))
    training = load_knowndata(filenames)
    pl.show()
    pl.close()

    # Create a classifier: a support vector classifier
    classifier = svm.SVC(gamma=1e-8)

    # We learn the digits on the first half of the digits
    classifier.fit(training['data'], training['targets'])

    filenames = sorted(glob.glob('data/*.png'))
    unknown = load_unknowndata(filenames)

    filenames = glob.glob('data/*.png')
    filenames = set([os.path.splitext(os.path.basename(fn))[0].split('-')[0] for fn in filenames])

    for filename in filenames:
        print('----')
        print(filename)
        print('----')
        fn = sorted(glob.glob('data/' + filename  + '*.png'))
        unknown = load_unknowndata(fn)
        # Now predict the value of the digit on the second half:
        #expected = digits.target[n_samples / 2:]
        predicted = classifier.predict(unknown['data'])

        result = ''
        for pred, image, name in zip(predicted, unknown['images'], unknown['name']):
            print(pred)
            print(name)
            result += str(pred)

        # Check
        fn = 'pictures/' + filename  + '.png'
        image = skimage.io.imread(fn)
        pl.imshow(image[:150, 56:], cmap=pl.cm.gray_r, interpolation='nearest')
        pl.title('Predicted: %s' % result)
        pl.show()

Le résultat est que sur des images de 150 par 300 pixels, contenant 5 digits chacune, j'ai eu 100% de succès sur un test de 60 images. L'algo est même robuste à un changement de valeur du dernier chiffre significatif de la balance lors de la prise de la photo qui se traduit par une superposition de deux digits sur la photos. L'algo détecte l'une ou l'autre des valeurs qu'un humain verrait.

detection de nombres avec une fluctuation : 24774

detection de nombres avec une fluctuation : 24774

En conclusion, on se retrouve avec un moyen simple de récupérer les valeurs de n'importe quel afficheur et sans effort ni bricolage.

[afpyro] AFPyro à Lyon - mercredi 28 mai

Publié le 2014-05-28 00:00:00

Un Afpyro aura lieu le mercredi 28 mai à partir de 20h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Une présentation sur Celery sera donnée. Celery est un gestionnaire de tâches qui permet de les traiter de manière asynchrone.

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

[cubicweb] Logilab's roadmap for CubicWeb on May 15th, 2014

Publié le 2014-05-22 15:24:00

The Logilab team holds a roadmap meeting every two months to plan its CubicWeb development effort. Here is the report about the May 15th, 2014 meeting. The previous report posted to the blog was the march 2014 roadmap.

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

Version 3.18

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

Version 3.19

This version was published at the end of April. It includes support for Cross Origin Resource Sharing (CORS) and a heavy refactoring that modifies sessions and sources to lay the path for CubicWeb 4.

For details read the release notes or the list of tickets for CubicWeb 3.19.0.

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 also include the work done for CWEP-002 (computed attributes and relations) and the merging of Connection and ClientConnection if it happens to be simple enough to get done quickly (in case the removal of dbapi would really help, this merging will wait for 3.21).

For details read list of tickets for CubicWeb 3.20.0.

Version 3.21 (or maybe 4.0?)

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

Cubes

Here is a list of cubes that had versions published over the past two months: accidents, awstats, book, bootstrap, brainomics, cmt, collaboration, condor, container, dataio, expense, faq, file, forge, forum, genomics, geocoding, inlineedit, inventory, keyword, link, mailinglist, mediaplayer, medicalexp, nazcaui, ner, neuroimaging, newsaggregator, processing, questionnaire, rqlcontroller, semnews, signedrequest, squareui, task, testcard, timesheet, tracker, treeview, vcsfile, workorder.

Here are a the new cubes we are pleased to announce:

rqlcontroller receives via a POST a list of RQL queries and executes them. This is a way to build web services.

wsme is helping build a web service API on top of a CubicWeb database.

signedrequest is a simple token based authentication system. This is a way for scripts or callback urls to access an instance without login/pwd information.

relationwidget is a widget usable in forms to edit relationships between objects. It depends on CubicWeb 3.19.

searchui is an experiment on adding blocks to the list of facets that allow building complex RQL queries step by step by clicking with the mouse instead of directly writing the RQL with the keyboard.

ckan is using the REST API of a CKAN data portal to mirror its content.

CWEPs

Here is the status of open CubicWeb Evolution Proposals:

CWEP-0002 is now in good shape and the goal is to have it merged into 3.20. It lacks some documentation and a migration script.

CWEP-0003 has made good progress during the latest sprint, but will need a thorough review before being merged. It will probably not be ready for 3.20 and have to wait for 3.21.

New CWEPs are expected to be written for clarifying the API of the _cw object, supporting persistent sessions and improving the performance of massive imports.

Visual identity

CubicWeb has a new logo that will appear before the end of may on its revamped homepage at http://www.cubicweb.org

Last but not least

As already said on the mailing list, other developers and contributors are more than welcome to share their own goals in order to define a roadmap that best fits everyone's needs.

Logilab's next roadmap meeting will be held at the beginning of july 2014.

[logilab] SaltStack Meetup with Thomas Hatch in Paris France

Publié le 2014-05-22 11:25:00

This monday (19th of may 2014), Thomas Hatch was in Paris for dotScale 2014. After presenting SaltStack there (videos will be published at some point), he spent the evening with members of the French SaltStack community during a meetup set up by Logilab at IRILL.

http://www.logilab.org/file/248338/raw/thomas-hatch.png

Here is a list of what we talked about :

  • Since Salt seems to have pushed ZMQ to its limits, SaltStack has been working on RAET (Reliable Asynchronous Event Transport Protocol ), a transport layer based on UDP and elliptic curve cryptography (Dan Berstein's CURVE-255-19) that works more like a stack than a socket and has reliability built in. RAET will be released as an optionnal beta feature in the next Salt release.
  • Folks from Dailymotion bumped into a bug that seems related to high latency networks and the auth_timeout. Updating to the very latest release should fix the issue.
  • Thomas told us about how a dedicated team at SaltStack handles pull requests and another team works on triaging github issues to input them into their internal SCRUM process. There are a lot of duplicate issues and old inactive issues that need attention and clutter the issue tracker. Help will be welcome.
http://www.logilab.org/file/248336/raw/Salt-Logo.png
  • Continuous integration is based on Jenkins and spins up VMs to test pull request. There is work in progress to test multiple clouds, various latencies and loads.
  • For the Docker integration, salt now keeps track of forwarded ports and relevant information about the containers.
  • salt-virt bumped into problems with chroots and timeouts due to ZMQ.
  • Multi-master: the problem lies with syncronisation of data which is sent to minions but also the data that is sent to the masters. Possible solutions to be explored are : the use of gitfs, there is no built-in solution for keys (salt-key has to be run on all masters), mine.send should send the data at both masters, for the jobs cache: one could use an external returner.
  • Thomas talked briefly about ioflo which should bring queuing, data hierarchy and data pub-sub to Salt.
http://www.logilab.org/file/248335/raw/ioflo.png
  • About the rolling release question: versions in Salt are definitely not git snapshots, things get backported into previous versions. No clear definition yet of length of LTS versions.
  • salt-cloud and libcloud : in the next release, libcloud will not be a hard dependency. Some clouds didn't work in libcloud (for example AWS), so these providers got implemented directly in salt-cloud or by using third-party libraries (eg. python-boto).
  • Documentation: a sprint is planned next week. Reference documentation will not be completly revamped, but tutorial content will be added.

Boris Feld showed a demo of vagrant images orchestrated by salt and a web UI to monitor a salt install.

http://www.vagrantup.com/images/logo_vagrant-81478652.png

Thanks again to Thomas Hatch for coming and meeting up with (part of) the community here in France.

[tarek] French Services Hackaton #1

Publié le 2014-05-22 08:35:00

The Mozilla Cloud Services team just got a little bit reorganized and I am now managing a new subteam.

I am very happy about the new subteam I am part of: Alexis, Rémy and myself are the French Cloud Services team. We're still working on projects with other teams of course - but being a team in the same timezone and speaking the same native language helps a lot.

One topic that is owned by our team is building and maintaining tools that help build, deploy & run web services.

Currently, the three most active projects are:

  • Loads -- a distributed load testing tool we use to verify that a given service scales.
  • Circus -- an extensible process supervisor we're using in all our deployments
  • Cornice -- a Python framework on the top of Pyramid that helps you write web services - as opposed to "web pages"

Hackaton #1

Rémy & Alexis are in Rennes, and I am located not far from Dijon - so we're very close to each other. Closer than from our colleagues from the US or Canada. When the team was set, we've decided that we would gather for a couple of days once every month at the Mozilla Paris office to work on tools.

That's what we did this week. And that event is open to the community - we had the pleasure to have Boris coming and working with us during those 2 days.

We worked on the following topics:

  • We released the long overdue Circus 0.11
  • We made the Circus web dashboard compatible with several Circus instances. In other words, you can now supervise processes that are running on several servers from the same dashboard
  • We looked at some improvements in how Cornice publishes its APIs specifications.

But the most important task: we socialized, had fun around food/drinks.

The next hackaton will be sometimes in June. I'll try to announce it so more people can join us.

[logilab] Compte rendu présentation Salt à Solution Linux

Publié le 2014-05-21 18:57:00

Logilab était à l'édition 2014 de Solutions Linux qui se déroulait au CNIT à Paris. David Douard participait à la table ronde sur les outils libres pour la supervision lors de la session Administration Système, Devops, au cours de laquelle un certain nombre de projets libres ont été mentionnés : nagios, shinken, graphite, ElasticSearch, logstash, munin, saltstack, kibana, centreon, rsyslog.

http://www.logilab.org/file/248048/raw/solutionlinux.png

Suite à des présentations sur OpenLDAP, LXC, btrfs et ElasticSearch David Douard a présenté notre approche agile de l'administration système articulée autour de Salt et en particulier le principe de l'administration système pilotée par les tests (diapos) (Test-Driven Infrastructure).

https://www.logilab.org/file/248098/raw/Screenshot%20from%202014-05-21%2017%3A55%3A35.png

Merci aux organisateurs de Solutions Linux pour cette édition 2014.

[logilab] Salt April Meetup in Paris (France)

Publié le 2014-05-14 12:28:00

On the 15th of april, in Paris (France), we took part in yet another Salt meetup. The community is now meeting up once every two months.

We had two presentations:

  • Arthur Lutz made an introduction to returners and the scheduler using the SalMon monitoring system as an example. Salt is not only about configuration management Indeed!
  • The folks from Is Cool Entertainment did a presentation about how they are using salt-cloud to deploy and orchestrate clusters of EC2 machines (islands in their jargon) to reproduce parts of their production environment for testing and developement.

More discussions about various salty subjects followed and were pursued in an Italian restaurant (photos here).

In case it is not already in your diary : Thomas Hatch is coming to Paris next week, on Monday the 19th of May, and will be speaking at dotscale during the day and at a Salt meetup in the evening. The Salt Meetup will take place at IRILL (like the previous meetups, thanks again to them) and should start at 19h. The meetup is free and open to the public, but registering on this framadate would be appreciated.

[logilab] Quelques pointeurs présentés lors d'un atelier sur le web sémantique à Nantes

Publié le 2014-05-14 11:36:00

À l'appel du DataLab Pays de la Loire, nous avons co-animé (avec Hala Skaf-Molli) un atelier sur le web sémantique à la Cantine Numérique de Nantes.

Voici quelques diapos avec essentiellement des pointeurs pour donner des exemples de réalisations web sémantique mais aussi pour appuyer les concepts présentés. Vous trouverez les diapos de Hala Skaf sur sa page web (dans les prochains jours).

Si vous avez raté cette session et êtes intéressé par le sujet, n'hésitez pas à le faire savoir au DataLab.

http://www.datalab-paysdelaloire.org/auth/public/images/datalab.png

[hautefeuille] Distribution d’une application Python sous Windows

Publié le 2014-05-13 21:05:00

Introduction

Même si la majorité des développeurs Python travaillent sur des environnements de développement Unix, il est parfois nécessaire de fournir une distribution d’une application Python sous le système d’exploitation Windows. Ce document constitue davantage une prise de notes qu’un tutoriel complet puisque je passe les éventuelles étapes d’installation de Cython, MinGW, Visual Studio ou Nuitka. J’utilise les versions 32 bits pour l’interpréteur Python 2.7, les packages Python et les compilateurs. J’utilise à la place de MinGW, la distribution TDM-GCC.

Ces méthodes ne servent pas à obfusquer votre code mais à distribuer l’interpréteur Python, les bibliothèques associées et votre application sous forme d’un paquet.

Sous Windows, pour développer, j’utilise

Sublime Text 2.

La distribution Python fournie par ActiveState.

Les paquets Python disponibles sur ce site pour Windows.

Microsoft Visual Studio Express 2008.

Microsoft Visual C++ 2008 Redistributable Package (x86).

Admettons que nous ayons une application Python sous cette forme

Un dossier principal nommé “supershape”.

Un fichier principal main.py résidant dans ce dossier et qui constitue l’application principale.

J’utilise ici une application développée avec l’outil Kivy.

Avec Pyinstaller

On initialise d’abord un fichier de spécifications

pyinstaller --name supershape supershape\main.py

On édite le fichier supershape.spec créé.

Pour un dossier regroupant l’exécutable et les dll, on édite le fichier comme suivant

# -*- mode: python -*-
from kivy.tools.packaging.pyinstaller_hooks import install_hooks
install_hooks(globals())

a = Analysis(['SuperShape\\main.py'],
             pathex=['C:\\Users\\ANTEC\\Documents'],
             hiddenimports=[],
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='supershape.exe',
          debug=False,
          strip=None,
          upx=True,
          console=False )
coll = COLLECT(exe, Tree('C:\\Users\\ANTEC\\Documents\\Supershape'),
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name='supershape')

Pour un exécutable standalone qui regroupe l’interpréteur

# -*- mode: python -*-
from kivy.tools.packaging.pyinstaller_hooks import install_hooks
install_hooks(globals())

a = Analysis(['SuperShape\\main.py'],
             pathex=['C:\\Users\\ANTEC\\Documents'],
             hiddenimports=[],
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,  Tree('C:\\Users\\ANTEC\\Documents\\Supershape'),
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='supershape.exe',
          debug=False,
          strip=None,
          upx=True,
          console=False )

Enfin on enveloppe le tout par la commande suivante

pyinstaller supershape.spec

Avec Nuikta

On génère la compilation en C avec la commande suivante

nuikta --recurse-all main.py

Avec Cython

On transforme le fichier Python en C

cython main.py -o supershape.c --embed

On compile le C avec Visual Studio et son compilateur

cl.exe /nologo /Ox /MD /W3 /GS- /DNDEBUG -Ic:\Python27\include -Ic:\Python27\PC /supershape.c /link /OUT:"supershape.exe" /SUBSYSTEM:CONSOLE /MACHINE:X86 /LIBPATH:c:\Python27\libs /LIBPATH:c:\Python27\PCbuild

[tarek] Un an de course

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

For once, I'll blog in French - if you want this post translated in English, mail me. It's about Running.

Je cours sérieusement depuis un an. C'est l'heure du bilan.

Mertics Pr0n

Je collecte des statistiques avec ma montre GPS depuis le 6 Août 2013 - donc presque un an aussi. A la louche, 10% de mon activité seulement n'a pas été trackée (course en tapis, fausse manip' au début d'une course) - donc les données que j'ai récupérées sont assez proches de la réalité.

En dix mois environ - ou 40 semaines, J'ai fait 1477 km en 192 séances avec donc une moyenne de 7.6km par séance. Si l'on retire les quelques données parasites comme les séances de 1mn pour cause de fausse manipulation - ou les séances de chauffe qui précèdent une plus longue séance, on est plus proche de séances de 10km en moyenne.

Mais le kilométrage est plus parlant, ca représente une moyenne de 36km par semaine, ce qui est beaucoup en période de compétition. (j'y reviendrais.)

Le temps total passé à courir est de 118h, à une allure moyenne de 4'48"/KM soit environ 12.5 KM/h. L'énergie dépensé est estimée à 92966 calories. Ce calcul calorique est un peu bidon puisque la montre ne connaît pas mon rythme cardiaque (elle pourrait) et ne prend pas en compte le dénivelé.

Mais je viens de commander une ceinture cardio donc dans un an j'aurais des stats plus précises grâce à la collecte du rythme cardique.

Impact sur la santé et l'alimentation

Je suis passé d'un rythme cardique au repos (au réveil) de 70 pulsations à 46. Les petits mal de dos chroniques après une journée penché sur le clavier ont disparus. Mon état général est passé de moyennement motivé pour me lever le matin, crevé le soir à une bonne pêche toute la journée.

Je ne bois quasiment plus d'alcool car je suis très vite saoul (deux bières peuvent suffire). Avant de me mettre au sport c'était parfois 2/3 (bonnes) bières le même soir. La faible tolérance à l'alcool est probablement lié à la chute de poids: je suis passé de 75kg à 60kg pour 1M68. On me dira que c'est mieux pour ma santé mais c'est frustrant ;)

Mon alimentation a pas mal changée aussi: je suis devenu végétarien et je mange peu mais souvent. En gros des petits repas, et plein d'encas toute la journée, comme des graines bien grasses (noix de cajou, noisettes, amandes). Aussi une quantitée anormale de pommes (3/4 par jour en moyenne - Chirac serait ravi). Je bois aussi 1 litre de thé par jour environ - plutôt du thé vert. Je passe donc plus de temps aux toilettes - mais grâce au wifi j'y travaille très bien.

En terme de bobos, je n'ai pas eu de problèmes majeurs. Juste des ongles noirs liés à l'impact des chaussures qui ont disparus une fois que je me suis décidé à porter des chaussures à ma taille - soit une taille de plus vu que les pieds gonflent un peu en course. Je suis aussi adepte de la course pieds nus de temps en temps, ca réveille les sens et à petite dose ca évite les petites blessures.

Le passage à une nouvelle paire de chaussure m'a aussi fait un peu mal aux genoux pendant quelque temps, mais rien de très grave. Quand je lis les histoires horribles sur les forums de course à pied, je me dis que j'ai de la chance globalement.

Pratique en Club

J'ai été très surpris du nombre de licenciés de course à pied, et du dynamise de ce sport en France. Il y a des évènements partout, tout le temps - avec des gens de tous les ages et couches sociales.

Il y a deux types de clubs:

Les clubs qui se prennent très au sérieux - qui s'entraînent principalement sur piste - le genre de club où le coach va te pousser à te surpasser ou te faire une remarque si tu n'as pas fait un sprint à l'arrivée d'une course (!?). La moyenne d'age semble un peu plus jeune.

Le deuxième type: les clubs à la cool, avec des gens de tous niveau et tout age, où l'on boira du vin chaud après le cross.

Je me suis inscris en novembre/décembre dernier à un petit club local, l'Association des Coureurs de Route (ACR) de Dijon - après avoir regardé un peu les clubs existants.

J'essaye de faire un entraînement par semaine avec le club, et le reste tout seul car je suis trop éloigné de Dijon pour y aller plus souvent.

C'est un club à la cool, mais avec quelques coureurs très fort avec qui je progresse.

Compétition

Je me suis pris au jeu des compétitions - ca brise la monotonie des joggings dans son coin.

Le site de la FFA track les courses que je fais en France pour moi, c'est assez bien fait. Voici ma fiche.

J'ai fait aussi deux courses à l'étranger. Un semi-marathon à San Francisco et un 5K à Montreal.

Mes records:

  • 5K: 18mn17s
  • 10K: 37mn45s à Chalon-s-Saone (il faisait 50m de plus, 37mn56s à l'arrivée)
  • semi-marathon: 1h24mn38s au semi de SF

Pas de marathon en compétition encore (une sortie de 32km c'est ma plus longue distance).

Le bilan des compet': au top de ma forme j'ai un niveau "R5" environ (Régional 5 du barême FFA) - en gros je termine en général dans les 10% les plus rapides dans les petites courses locales, mais je ne pourrais jamais faire un "podium" (les 3 premiers).

J'ai le défaut classique du débutant: je pars trop vite et je fini trop lentement. C'est très difficile de conserver ses allures et ne pas se faire emporter par l'adrénaline du départ. J'y travaille.

Depuis le début du printemps, j'enchaine les courses tous les week-ends et je ne me repose plus assez. Tous mes chronos commencent à régresser. Le sur-entraînement est facile à atteindre quand on débute. Pareil, il faut que le métier rentre.

Bilan et suite

La course me convient bien. Ca se goupille bien avec le télé-travail et je suis en meilleur forme physique. C'est une activité qui évacue bien le stress.

Je bloguerais dans un an environ sur ce même sujet, pour voir l'évolution.

[cubicweb] What's new in CubicWeb 3.19

Publié le 2014-05-06 12:51:00

New functionalities

  • implement Cross Origin Resource Sharing (CORS) (see #2491768)
  • system_source.create_eid can return a range of IDs, to reduce overhead of batch entity creation

Behaviour Changes

  • The anonymous property of Session and Connection is now computed from the related user login. If it matches the anonymous-user in the config the connection is anonymous. Beware that the anonymous-user config is web specific. Therefore, no session may be anonymous in a repository only setup.

New Repository Access API

Connection replaces Session

A new explicit Connection object replaces Session as the main repository entry point. A Connection holds all the necessary methods to be used server-side (execute, commit, rollback, call_service, entity_from_eid, etc...). One obtains a new Connection object using session.new_cnx(). Connection objects need to have an explicit begin and end. Use them as a context manager to never miss an end:

with session.new_cnx() as cnx:
    cnx.execute('INSERT Elephant E, E name "Babar"')
    cnx.commit()
    cnx.execute('INSERT Elephant E, E name "Celeste"')
    cnx.commit()
# Once you get out of the "with" clause, the connection is closed.

Using the same Connection object in multiple threads will give you access to the same Transaction. However, Connection objects are not thread safe (hence at your own risks).

repository.internal_session is deprecated in favor of repository.internal_cnx. Note that internal connections are now safe by default, i.e. the integrity hooks are enabled.

Backward compatibility is preserved on Session.

dbapi vs repoapi

A new API has been introduced to replace the dbapi. It is called repoapi.

There are three relevant functions for now:

  • repoapi.get_repository returns a Repository object either from an URI when used as repoapi.get_repository(uri) or from a config when used as repoapi.get_repository(config=config).
  • repoapi.connect(repo, login, **credentials) returns a ClientConnection associated with the user identified by the credentials. The ClientConnection is associated with its own Session that is closed when the ClientConnection is closed. A ClientConnection is a Connection-like object to be used client side.
  • repoapi.anonymous_cnx(repo) returns a ClientConnection associated with the anonymous user if described in the config.

repoapi.ClientConnection replaces dbapi.Connection and company

On the client/web side, the Request is now using a repoapi.ClientConnection instead of a dbapi.Connection. The ClientConnection has multiple backward compatible methods to make it look like a dbapi.Cursor and dbapi.Connection.

Sessions used on the Web side are now the same as the ones used Server side. Some backward compatibility methods have been installed on the server side Session to ease the transition.

The authentication stack has been altered to use the repoapi instead of the dbapi. Cubes adding new elements to this stack are likely to break.

New API in tests

All current methods and attributes used to access the repo on CubicWebTC are deprecated. You may now use a RepoAccess object. A RepoAccess object is linked to a new Session for a specified user. It is able to create Connection, ClientConnection and web side requests linked to this session:

access = self.new_access('babar') # create a new RepoAccess for user babar
with access.repo_cnx() as cnx:
    # some work with server side cnx
    cnx.execute(...)
    cnx.commit()
    cnx.execute(...)
    cnx.commit()

with access.client_cnx() as cnx:
    # some work with client side cnx
    cnx.execute(...)
    cnx.commit()

with access.web_request(elephant='babar') as req:
    # some work with web request
    elephant_name = req.form['elephant']
    req.execute(...)
    req.cnx.commit()

By default testcase.admin_access contains a RepoAccess object for the default admin session.

API changes

  • RepositorySessionManager.postlogin is now called with two arguments, request and session. And this now happens before the session is linked to the request.
  • SessionManager and AuthenticationManager now take a repo object at initialization time instead of a vreg.
  • The async argument of _cw.call_service has been dropped. All calls are now synchronous. The zmq notification bus looks like a good replacement for most async use cases.
  • repo.stats() is now deprecated. The same information is available through a service (_cw.call_service('repo_stats')).
  • repo.gc_stats() is now deprecated. The same information is available through a service (_cw.call_service('repo_gc_stats')).
  • repo.register_user() is now deprecated. The functionality is now available through a service (_cw.call_service('register_user')).
  • request.set_session no longer takes an optional user argument.
  • CubicwebTC does not have repo and cnx as class attributes anymore. They are standard instance attributes. set_cnx and _init_repo class methods become instance methods.
  • set_cnxset and free_cnxset are deprecated. The database connection acquisition and release cycle is now more transparent.
  • The implementation of cascading deletion when deleting composite entities has changed. There comes a semantic change: merely deleting a composite relation does not entail any more the deletion of the component side of the relation.
  • _cw.user_callback and _cw.user_rql_callback are deprecated. Users are encouraged to write an actual controller (e.g. using ajaxfunc) instead of storing a closure in the session data.
  • A new entity.cw_linkable_rql method provides the rql to fetch all entities that are already or may be related to the current entity using the given relation.

Deprecated Code Drops

  • The session.hijack_user mechanism has been dropped.
  • EtypeRestrictionComponent has been removed, its functionality has been replaced by facets a while ago.
  • the old multi-source support has been removed. Only copy-based sources remain, such as datafeed or ldapfeed.

[gvaroquaux] Google summer of code projects for scikit-learn

Publié le 2014-04-23 05:56:46
I’d like to welcome the four students that were accepted for the GSoC this year: Issam: Extending Neural networks Hamzeh: Sparse Support for Ensemble Methods Manoj: Making Linear models faster Maheshakya: Locality Sensitive Hashing Welcome to all of you. Your submissions were excellent, and you demonstrated a good will to integrate in the project, with its social and coding dynamics. It is [...]

[afpyro] AFPyro à Lyon - mercredi 23 avril

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

Un Afpyro aura lieu le mercredi 23 avril à partir de 20h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Une présentation sur WTForms sera donnée. WTForms est une librairie permettant de simplifier la gestion des formulaires au sein d’une application web.

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

[logilab] Pylint 1.2 released!

Publié le 2014-04-22 12:56:00

Once again, a lot of work has been achieved since the latest 1.1 release. Claudiu, who joined the maintainer team (Torsten and me) did a great work in the past few months. Also lately Torsten has backported a lot of things from their internal G[oogle]Pylint. Last but not least, various people contributed by reporting issues and proposing pull requests. So thanks to everybody!

Notice Pylint 1.2 depends on astroid 1.1 which has been released at the same time. Currently, code is available on Pypi, and Debian/Ubuntu packages should be ready shortly on Logilab's acceptance repositories.

Below is the changes summary, check the changelog for more info.

New and improved checks:

  • New message 'eval-used' checking that the builtin function eval was used.
  • New message 'bad-reversed-sequence' checking that the reversed builtin receive a sequence (i.e. something that implements __getitem__ and __len__, without being a dict or a dict subclass) or an instance which implements __reversed__.
  • New message 'bad-exception-context' checking that raise ... from ... uses a proper exception context (None or an exception).
  • New message 'abstract-class-instantiated' warning when abstract classes created with abc module and with abstract methods are instantied.
  • New messages checking for proper class __slots__: 'invalid-slots-object' and 'invalid-slots'.
  • New message 'undefined-all-variable' if a package's __all__ variable contains a missing submodule (#126).
  • New option logging-modules giving the list of module names that can be checked for 'logging-not-lazy'.
  • New option include-naming-hint to show a naming hint for invalid name (#138).
  • Mark file as a bad function when using python2 (#8).
  • Add support for enforcing multiple, but consistent name styles for different name types inside a single module.
  • Warn about empty docstrings on overridden methods.
  • Inspect arguments given to constructor calls, and emit relevant warnings.
  • Extend the number of cases in which logging calls are detected (#182).
  • Enhance the check for 'used-before-assignment' to look for nonlocal uses.
  • Improve cyclic import detection in the case of packages.

Bug fixes:

  • Do not warn about 'return-arg-in-generator' in Python 3.3+.
  • Do not warn about 'abstract-method' when the abstract method is implemented through assignment (#155).
  • Do not register most of the 'newstyle' checker warnings with python >= 3.
  • Fix 'unused-import' false positive with augment assignment (#78).
  • Fix 'access-member-before-definition' false negative with augment assign (#164).
  • Do not crash when looking for 'used-before-assignment' in context manager assignments (#128).
  • Do not attempt to analyze non python file, eg '.so' file (#122).
  • Pass the current python path to pylint process when invoked via epylint (#133).

Command line:

  • Add -i / --include-ids and -s / --symbols back as completely ignored options (#180).
  • Ensure init-hooks is evaluated before other options, notably load-plugins (#166).

Other:

  • Improve pragma handling to not detect 'pylint:*' strings in non-comments (#79).
  • Do not crash with UnknownMessage if an unknown message identifier/name appears in disable or enable in the configuration (#170).
  • Search for rc file in ~/.config/pylintrc if ~/.pylintrc doesn't exists (#121).
  • Python 2.5 support restored (#50 and #62).

Astroid:

  • Python 3.4 support
  • Enhanced support for metaclass
  • Enhanced namedtuple support

Nice easter egg, no?

[logilab] Open Science à Toulouse : barcamp sur les Biens Communs

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

Le deuxième apéritif et barcamp de la communauté Open Science Toulousaine aura lieu le 24 avril à 19h00 au bar El Deseo, 11 rue des Lois, à deux pas du Capitole et de St Sernin sur le thème des biens communs.

Plus d'informations sur http://hackyourphd.org/2014/04/aperitif-open-science-toulouse-les-biens-communs/

[afpyro] AFPyro à Montreal - le 12 Avril

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

A l’occasion de Pycon U.S., l’AFPy organise son premier AFPyro à Montréal ! Venez échanger autour d’une bonne bière artisanale avec la comunauté francophone python !

AFPy is organizing its first AFPyro at PyCon U.S. in Montreal! Come and meet the french python community around a good craft beer!

Quand ? When ?

Le Samedi 12 Avril, vers 19h

Saturday 12th of April at 7PM

Ou ? / Where ?

Le Benelux Sherbrooke (map)

25, rue Sherbrooke Ouest

Montréal, QC H2X 1X7

[j-mad] DjangoIsland, parce que les poneys savent nager

Publié le 2014-04-10 15:41:02
Vous êtes djangonautes ? Et vous n’avez pas encore acheté votre billet pour DjangoCon Europe ? Alors peut-être que vous ne le saviez pas. Après tout, même si on a essayé de faire un maximum de com sur le sujet, on n’en fait jamais assez et il est fort possible que vous soyez passé à coté. Donc, [...]

[logilab] Deuxième hackathon codes libres de mécanique

Publié le 2014-04-07 17:12:00

Organisation

Le 27 mars 2014, Logilab a accueilli un hackathon consacré aux codes libres de simulation des phénomènes mécaniques. Etaient présents:

  • Patrick Pizette, Sébastien Rémond (Ecole des Mines de Douai / DemGCE)
  • Frédéric Dubois, Rémy Mozul (LMGC Montpellier / LMGC90)
  • Mickaël Abbas, Mathieu Courtois (EDF R&D / Code_Aster)
  • Alexandre Martin (LAMSID / Code_Aster)
  • Luca Dall'Olio, Maximilien Siavelis (Alneos)
  • Florent Cayré, Nicolas Chauvat, Denis Laxalde, Alain Leufroy (Logilab)

DemGCE et LMGC90

Patrick Pizette et Sébastien Rémond des Mines de Douai sont venus parler de leur code de modélisation DemGCE de "sphères molles" (aussi appelé smooth DEM), des potentialités d'intégration de leurs algorithmes dans LMGC90 avec Frédéric Dubois du LMGC et de l'interface Simulagora développée par Logilab. DemGCE est un code DEM en 3D développé en C par le laboratoire des Mines de Douai. Il effectuera bientôt des calculs parallèles en mémoire partagée grâce à OpenMP. Après une présentation générale de LMGC90, de son écosystème et de ses applications, ils ont pu lancer leurs premiers calculs en mode dynamique des contacts en appelant via l'interface Python leurs propres configurations d'empilements granulaires.

Ils ont grandement apprécié l'architecture logicielle de LMGC90, et en particulier son utilisation comme une bibliothèque de calcul via Python, la prise en compte de particules de forme polyhédrique et les aspects visualisations avec Paraview. Il a été discuté de la réutilisation de la partie post/traitement visualisation via un fichier standard ou une bibliothèque dédiée visu DEM.

Frédéric Dubois semblait intéressé par l'élargissement de la communauté et du spectre des cas d'utilisation, ainsi que par certains algorithmes mis au point par les Mines de Douai sur la génération géométrique d'empilements. Il serait envisageable d'ajouter à LMGC90 les lois d'interaction de la "smooth DEM" en 3D, car elles ne sont aujourd'hui implémentées dans LMGC90 que pour les cas 2D. Cela permettrait de tester en mode "utilisateur" le code LMGC90 et de faire une comparaison avec le code des Mines de Douai (efficacité parallélisation, etc.).

Florent Cayré a fait une démonstration du potentiel de Simulagora.

LMGC90 et Code_Aster dans Debian

Denis Laxalde de Logilab a travaillé d'une part avec Rémy Mozul du LMGC sur l'empaquetage Debian de LMGC90 (pour intégrer en amont les modifications nécessaires), et d'autre part avec Mathieu Courtois d'EDF R&D, pour finaliser l'empaquetage de Code_Aster et notamment discuter de la problématique du lien avec la bibliothèque Metis: la version actuellement utilisée dans Code_Aster (Metis 4), n'est pas publiée dans une licence compatible avec la section principale de Debian. Pour cette raison, Code_Aster n'est pas compilé avec le support MED dans Debian actuellement. En revanche la version 5 de Metis a une licence compatible et se trouve déjà dans Debian. Utiliser cette version permettrait d'avoir Code_Aster avec le support Metis dans Debian. Cependant, le passage de la version 4 à la version 5 de Metis ne semble pas trivial.

Voir les tickets:

Replier LibAster dans Code_Aster

Alain Leufroy et Nicolas Chauvat de Logilab ont travaillé à transformer LibAster en une liste de pull request sur la forge bitbucket de Code_Aster. Ils ont présenté leurs modifications à Mathieu Courtois d'EDF R&D ce qui facilitera leur intégration.

Voir les tickets:

Suppression du superviseur dans Code_Aster

En fin de journée, Alain Leufroy, Nicolas Chauvat et Mathieu Courtois ont échangé leurs idées sur la simplification/suppression du superviseur de commandes actuel de Code_Aster. Il est souhaitable que la vérification de la syntaxe (choix des mots-clés) soit dissociée de l'étape d'exécution.

La vérification pourrait s'appuyer sur un outil comme pylint, la description de la syntaxe des commandes de Code_Aster pour pylint pourrait également permettre de produire un catalogue compréhensible par Eficas.

L'avantage d'utiliser pylint serait de vérifier le fichier de commandes avant l'exécution même si celui-ci contient d'autres instructions Python.

Allocation mémoire dans Code_Aster

Mickaël Abbas d'EDF R&D s'est intéressé à la modernisation de l'allocation mémoire dans Code_Aster et a listé les difficultés techniques à surmonter ; l'objectif visé est un accès facilité aux données numériques du Fortran depuis l'interface Python. Une des difficultés est le partage des types dérivés Fortran en Python. Rémy Mozul du LMGC et Denis Laxalde de Logilab ont exploré une solution technique basée sur Cython et ISO-C-Bindings. De son côté Mickaël Abbas a contribué à l'avancement de cette tâche directement dans Code_Aster.

Doxygen pour documentation des sources de Code_Aster

Luca Dall'Olio d'Alneos et Mathieu Courtois ont testé la mise en place de Doxygen pour documenter Code_Aster. Le fichier de configuration pour doxygen a été modifié pour extraire les commentaires à partir de code Fortran (les commentaires doivent se trouver au dessus de la déclaration de la fonction, par exemple). La configuration doxygen a été restituée dans le depôt Bitbucket. Reste à évaluer s'il y aura besoin de plusieurs configurations (pour la partie C, Python et Fortran) ou si une seule suffira. Une configuration particulière permet d'extraire, pour chaque fonction, les points où elle est appelée et les autres fonctions utilisées. Un exemple a été produit pour montrer comment écrire des équations en syntaxe Latex, la génération de la documentation nécessite plus d'une heure (seule la partie graphique peut être parallélisée). La documentation produite devrait être publiée sur le site de Code_Aster.

La suite envisagée est de coupler Doxygen avec Breathe et Sphinx pour compléter la documentation extraite du code source de textes plus détaillés.

La génération de cette documentation devrait être une cible de waf, par exemple waf doc. Un aperçu rapide du rendu de la documentation d'un module serait possible par waf doc file1.F90 [file2.c [...]].

Voir Code Aster #18 configure doxygen to comment the source files

Catalogue d'éléments finis

Maximilien Siavelis d'Alneos et Alexandre Martin du LAMSID, rejoints en fin de journée par Frédéric Dubois du LMGC ainsi que Nicolas Chauvat et Florent Cayré de Logilab, ont travaillé à faciliter la description des catalogues d'éléments finis dans Code_Aster. La définition de ce qui caractérise un élément fini a fait l'objet de débats passionnés. Les points discutés nourriront le travail d'Alexandre Martin sur ce sujet dans Code_Aster. Alexandre Martin a déjà renvoyé aux participants un article qu'il a écrit pour résumer les débats.

Remontée d'erreurs de fortran vers Python

Mathieu Courtois d'EDF R&D a montré à Rémy Mozul du LMGC un mécanisme de remontée d'exception du Fortran vers le Python, qui permettra d'améliorer la gestion des erreurs dans LMGC90, qui a posé problème dans un projet réalisé par Denis Laxalde de Logilab pour la SNCF.

Voir aster_exceptions.c

Conclusion

Tous les participants semblaient contents de ce deuxième hackathon, qui faisait suite à la première édition de mars 2013 . La prochaine édition aura lieu à l'automne 2014 ou au printemps 2015, ne la manquez pas !

[logilab] Naissance de la communauté Open Science Toulousaine

Publié le 2014-04-02 17:50:00

Ils étaient une vingtaine à se (re)trouver à l’occasion du premier apéritif & barcamp Open Science à Toulouse organisé par Logilab et Hack your PhD. La plupart étaient avant tout curieux de voir qui et quoi se cachaient derrière cette annonce :

un rendez-vous périodique, informel et sympathique a pour but de favoriser les échanges entre tous les acteurs intéressés par un aspect de l’Open Science : Open Data, les rapports Sciences & Société, Open Source, Open Access, Big Data & Data Science, etc.

Curieux souvent parce qu’ils s’étaient reconnus dans l’une ou l’autre – et souvent plusieurs – de ces facettes de l’Open Science sans avoir déjà rencontré l’étiquette Open Science pour autant.

Les échangent se nouent dans la communauté Open Science

Mais alors l’Open Science : c’est quoi ?

Heureusement personne n’a asséné de définition définitive. J’ai tenté de montrer, à travers une brève présentation de Hack your PhD et de Logilab comment l’Open Science est avant tout une démarche d’ouverture dans la pratique de la recherche scientifique qui s’étend au delà du cadre du laboratoire.

L’objectif de la soirée était de permettre à la communauté Open Science locale de se découvrir ; aux acteurs de science ou d’ouverture de faire connaissance. De fait les discussions et prises de contacts informelles allaient bon train autour d’un verre et quelques tapas… et c’est donc à chacun des participants de partager ses échanges sur le thème que fait-on à Toulouse ?

Le fournisseur d’accès associatif tetaneutral nous met à disposition une liste de diffusion à l’adresse open-science-toulouse@lists.tetaneutral.net. Merci à eux ! J’invite vivement les participants à l’apéro à s’y présenter en quelques mots : faites nous part de votre perception de cet événement et partager vos intérêts et projets.

On se retrouvera bientôt pour un prochain événement qui tiendra plus de l’atelier. Quelques suggestion qui sont dores et déjà apparues : un atelier sur les outils pratiques pour être ouvert, un séminaire dans un centre de recherche universitaire, un atelier sur les alignements de données publiques et l’évolutivité des schéma de données avec CubicWeb, …

Vos propositions sont très bienvenues : la communauté Open Science Toulousaine deviendra ce qu’ensemble nous en ferons !

Ce compte rendu a été initialement publié sur le site de hackyourphd : http://hackyourphd.org/2014/02/naissance-de-la-communaute-toulousaine/

[sciunto] Manuscript : Scikit-image : Traitement d'images en Python

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

Scikit-image est une bibliothèque de traitement d'images en Python. Nous venons de soumettre un manuscript à PeerJ dont le PrePrint est téléchargeable. EDIT: et le papier publié est ici version finale.

Je suis très heureux d'avoir eu l'occasion de participer à la rédaction de ce manuscript où j'ai pu illustrer un code utilisé à des fins de recherche académique dont j'ai implémenté l'algorithme dans la bibliothèque. L'histoire a voulu qu'ayant en tête cette application précise, j'ai cherché un algorithme et ne trouvant pas une implémentation qui me plaisait en Python, j'en ai proposé une à scikit-image. J'en parlais il y a un an dans cet article (transformée de Hough). La boucle est bouclée !

J'ai aussi écrit la partie "getting started" pour découvrir la bibliothèque en douceur, si vous ne la connaissez pas.

Le manuscript a l'avantage de présenter des cadres divers d'utilisation de scikit-image, grâce à la diversité des auteur(e)s. On trouve de la recherche en biologie, une application en entreprise pour détecter des défauts sur des surfaces, l'utilisation de la bibliothèque dans l'enseignement et enfin, une belle illustration du recollement d'images, le résultat est vraiment impressionnant.

Outre ces usages, on mets en avant le fait que scikit-image s'appuie fortement sur NumPy, ce qui permet facilement d'appliquer d'autres algo disponibles dans SciPy, Scikit-learn, etc.

C'est la première fois que j'écris un papier de manière collaborative avec git et le mécanisme de pull requests de github, et je dois dire que c'est très efficace. Le commentaire ligne à ligne avant l'inclusion permet d'atteindre très rapidement un document de qualité. Merci aux co-auteurs pour cette expérience !

[hautefeuille] Programmation asynchrone avec Python 3.4 et le module asyncio

Publié le 2014-03-28 16:50:00

Introduction

Le module Python Asyncio est un module qui fournit une infrastructure pour écrire du code monothreadé concurrent en utilisant des coroutines, en multiplexant les Entrées/Sorties au-dessus de sockets ou d’autres ressources, et en démarrant des clients et des serveurs.

Les coroutines

Une coroutine est exécutée par l’expression yield from. Une coroutine est une fonction qui contient au moins une expression yield from.

Les tâches

Une tâche n’est pas exécutée par l’expression yield from. Une tâche est un objet qui gère une coroutine. Une tâche permet d’annuler une coroutine déjà exécutée. Une tâche permet d’exécuter une coroutine sous une coroutine existante.

Exemple de communication avec des websockets

Le projet Websockets permet d’utiliser simplement les websockets au-dessus du module asyncio. Ce sont ces websockets que nous allons utiliser pour réaliser le pattern consommateur/producteur.

Pour son installation :

sudo pip3.4 install websockets

Exemple :

import asyncio
import websockets

# Server
@asyncio.coroutine
def producer(websocket, uri):
    count = 0
    while websocket.open:
        yield from asyncio.sleep(1)
        count = count + 1
        yield from websocket.send(str(count))

# Client
@asyncio.coroutine
def consumer():
    websocket = yield from websockets.connect('ws://localhost:8765/')
    while websocket.open:
        count = yield from websocket.recv()
        print("%s" % count)

start_server = websockets.serve(producer, 'localhost', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_until_complete(consumer())
asyncio.get_event_loop().run_forever()

Ce qui est intéressant dans ce cas, est que le consommateur peut être un client Javascript.

Exemple de communication avec une file d’attente

Dans cet exemple, nous allons utiliser une file d’attente illimitée pour échanger entre les coroutines. Si l’on choisit une file d’attente de taille fixe, celle-ci est bloquante si elle n’est pas vidée.

Exemple :

import asyncio

q = asyncio.Queue(maxsize=0)

@asyncio.coroutine
def producer():
    for elem in range(5):
        yield from q.put(elem)

@asyncio.coroutine
def consumer():
    while True:
        elems = yield from q.get()
        print(elems)

asyncio.get_event_loop().run_until_complete(producer())
asyncio.get_event_loop().run_until_complete(consumer())
asyncio.get_event_loop().run_forever()

L’intérêt ici, est l’utilisation d’une file d’attente sur laquelle on peut s’appuyer pour un contrôle de flux.

Liens

doc asyncio module

[afpyro] AFPyro à Paris - le 27 Mars

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

C’est l’été ou presque. Il est temps de profiter des terrasses!

Venez discuter de votre langage de programmation favori autour d’un verre et plus si affinités.

Quand ?

Le Jeudi 27 Mars, vers 19h00.

Où ?

Café Chéri(e) (plan)

44 bd de la Villette, 75019 Paris (FR).

Métro: Belleville / Colonel Fabien

[afpyro] AFPyro à Lyon - mardi 25 mars

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

Un Afpyro aura lieu le mardi 25 mars à partir de 19h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Cet apéro Python sera commun avec l’apéro Php.

Une présentation sera faite sur la sécurité web. Après un aperçu des principales failles présentes dans les applications web, une réflexion sur les failles XSS sera faite et une méthode de protection efficace contre une partie de celles-ci sera présentée. Enfin, le thème de la sécurité sera abordé de façon plus général (politique de sécurité, bonnes pratiques...).

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