Quantcast
Channel: AFPy's Planet
Viewing all 3409 articles
Browse latest View live

[Biologeek] Running LEAN

$
0
0

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

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

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

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

Pourquoi Running Lean ?

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

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

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

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

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


[cubicweb] Exploring the datafeed API in CubicWeb

$
0
0

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

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

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

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

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

Overview of the datafeed API

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

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

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

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

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

Case study: a news feeds parser

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

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

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

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

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

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

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

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

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

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

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

Testing datafeed parsers

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

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

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

Notes

[1]

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

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

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

$
0
0

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

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

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

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

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

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

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

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

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

[afpyro] AFPyro à Lyon - mercredi 22 octobre

$
0
0

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

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

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

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

Pour se rendre à l’Antre Autre :

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

[Biologeek] Cours IUT Arles

$
0
0

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

Manuel d’écriture et de survie, Martin Page

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

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

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

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

[AFPy-Nantes] Barcamp & micro-python

$
0
0

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

Compte rendu.

Présentation

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

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

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

Let's roll

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

Que la lumière soit

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

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

Moteur, ça tourne

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

brain = pyb.Servo(1)

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

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

Consulter l'angle courant :

servo1.angle()
-60

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

servo1.angle(50, 1000)

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

Digression

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

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

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

Les autres projets évoqués :

[Biologeek] Cours IUT : les bases

$
0
0

The plan is a lie.

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

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

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

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

Quelques réflexions en vrac :

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

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

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

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

[Biologeek] Enseignement et acquisition

$
0
0

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

EAFP

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

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

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


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

$
0
0

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

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

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

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

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

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

Les locaux de tinyclues c'est au

15, rue du Caire
75002 Paris
France

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

En espérant vous voir nombreux, saltez bien !

[afpyro] AFPyro à Lyon - vendredi 24 octobre

$
0
0

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

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

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

Pour se rendre à l’Antre Autre :

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

[logilab] PyconFR 2014 - on y va !

$
0
0

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

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

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

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

[afpyro] AFPyro à Lyon - samedi 25 octobre

[tarek] Web Application Firewall

$
0
0

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

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

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

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

Such a rule could look like this:

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

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

Note

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

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

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

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

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

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

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

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

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

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

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

And thanks to NginxTest our Lua script are fully tested.

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

$
0
0

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

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

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

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

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

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

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

[Biologeek] Données et secret

$
0
0

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

Le serment du Beffroi de Montrouge

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

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

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

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

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

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


[AFPy Salt-fr] Annonce : Logilab présente Saltstack le 3 novembre à la cantine Toulouse

$
0
0

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

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

[afpyro] AFPyro à Berlin - Vendredi 25 Juillet

$
0
0

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

[afpyro] AFPyro à Lyon - mercredi 26 novembre

$
0
0

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

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

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

Pour se rendre à l’Antre Autre :

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

[gvaroquaux] The 2014 international scikit-learn sprint

$
0
0
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 [...]

[afpyro] AFPyro à Berlin - Vendredi 25 Juillet

$
0
0

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

Viewing all 3409 articles
Browse latest View live