Le petit coin de Nicolas

Aller au contenu | Aller au menu | Aller à la recherche

Couchapp : créer votre première application CouchDB (Partie 2)

La dernière fois, je vous ai laissé avec pas grand chose, à savoir couchapp installé et une squelette d'application.

Aujourd'hui, nous allons être nettement plus ambitieux en prenant comme prétexte une application de gestion de favoris (à la delicious, en mode mono-utilisateur). Nous allons aborder le rendu d'un document en tant que tel (aka "show") et les listes de documents (aka "list").

Avant toute chose... couchapp !

Générons notre petite application :

couchapp-cloned	mycouchapp
tetram:CouchDB nicolas$ couchapp generate mycouchfav
[INFO] Generating a new CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav

Et poussons notre application dans notre instance CouchDB (que vous avez démarré par ailleurs) :

tetram:CouchDB nicolas$ cd mycouchfav/
tetram:mycouchfav nicolas$ couchapp push myfav
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Vinrent ensuite les documents

Commençons par nous créer trois favoris depuis Futon ( http://localhost:5984/_utils/) avec la structure suivante :

  • title
  • url
  • description
  • tag

Ci-après mon jeu d'exemple au format json :

{
   "_id": "couchdb",
   "_rev": "3-1834349775",
   "title": "CouchDB Official site",
   "url": "http://couchdb.apache.org/",
   "description": "Apache CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API",
   "tag": [
       "couchdb",
       "database",
       "document"
   ]
}
 
{
   "_id": "couchdbkit",
   "_rev": "2-1087649587",
   "title": "Couchdbkit",
   "description": "Couchdbkit goal is to provide a framework for your Python application to access and manage Couchdb.",
   "url": "http://www.couchdbkit.org/",
   "tag": [
       "couchdb",
       "python",
       "framework"
   ]
}
 
{
   "_id": "couchapp",
   "_rev": "2-3730993466",
   "title": "couchapp",
   "description": "Utilities to make standalone CouchDB application development simple",
   "url": "http://github.com/couchapp/couchapp/tree/master",
   "tag": [
       "couchdb",
       "python",
       "ruby"
   ]
}


Tu me le montres ton document ?

L'url pour accéder à un document est du type :

http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_show/<nom_du_show>/<id_du_document>

Dans notre cas, par ex : http://localhost:5984/myfav/_design/mycouchfav/_show/fav/couchdbkit (si je prends le favori ayant pour id "couchdbkit".

Vous venez de déduire que mon "show" se nomme "fav". Plus exactement, il s'agit du fichier show/fav.js avec le contenu suivant :

function(doc, req) {  
    // !json templates.fav
    // !code vendor/couchapp/template.js
    // !code vendor/couchapp/path.js
 
    return template(templates.fav, {
        title : doc.title,
        url : doc.url,
        description : doc.description,
        assets : assetPath(),
       }
    );
}

Expliquons ce qu'il contient :

  • Pour un show, la fonction js prend 2 arguments : doc et req ; ce dernier content la requête et va trouver le document associée à cette requête.
  • On initialise une variable json, qui est utilisée ensuite pour appelé le template templates/fav.html
  • On inclut ensuite 2 fichiers js fournis par couchapp
  • Le return indique que l'on va charger le fichier templates/fav.html avec 4 variables qui sont le titre (title), l'url, la description du favori, ainsi qu'une variable assets qui permet de renseigner un chemin vers différents fichiers (css, js, etc).

Il nous resque plus qu'à construire le fichier templates/fav.html :

<!DOCTYPE html>
<html>
    <head> 
        <title><%= title %></title>
    </head>
    <body>
    <div id="header"></div>
    <div id="content">
        <h1><a href="<%= url %>"><%= title %></a></h1>
        <div class="body"><%= description %></div>
    </div>    
</body>
<script src="/_utils/script/json2.js"></script>
<script src="/_utils/script/jquery.js?1.2.6"></script>
<script src="/_utils/script/jquery.couch.js"></script>
<script src="<%= assets %>/vendor/couchapp/jquery.couchapp.js"></script>
</html>

Il ne nous reste plus qu'à .... et non pas visualiser votre page mais au préalable pousser vos fichiers dans votre instance CouchDB :

tetram:mycouchfav nicolas$ couchapp push myfav
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Maintenant, ouvrez votre navigateur sur l'url http://localhost:5984/myfav/_design/mycouchfav/_show/fav/couchdbkit et vous retrouvez le contenu très sommairement présenté de votre favori avec son titre, son url et sa description.

En conclusion, pour afficher un document, il nous faut :

  • Un template (ici : templates/fav.html)
  • Une fonction en javascript qui nous permet de manipuler les attributs du documents en vue de leur rendu. La fonction est de type function(doc,req). La fonction est située dans un fichier shows/nom_du_show.js (ici shows/fav.js)
  • Ne pas oublier de faire un "couchapp push" pour envoyer vos fichiers dans votre instance CouchDB
  • Une url du type : http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_show/<nom_du_show>/<id_du_document>

Et ta liste, tu me la montres aussi ?

Pour les listes, c'est un peu plus complexe mais pas insurmontable :-)

L'url est du type :

http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_list/<nom_de_la_liste>/<nom_de_la_vue>?<paramètres>

Supposons que je veuille créer la page d'accueil de mon application, celle-ci listant tous les favoris stockés. Le nom de la liste pourrait donc tout naturellement s'appeller "all" et le nom de la vue "favs". On pourrait imaginer avoir une liste "search" par ex pour afficher les résultats d'une recherche sur les favoris avec des paramètres de recherche.

Il faut donc bien avoir en tête qu'une liste est un moyen d'afficher une vue. Une même vue peut donc partager plusieurs listes.

Ex :

http://localhost:5984/myfav/_design/mycouchfav/_list/all/favs
http://localhost:5984/myfav/_design/mycouchfav/_list/search/favs?limit=25&key=%22python%22

Commençons donc par créer notre vue, avec le fichier views/favs/map.js

function(doc) {
    emit(doc._id, {title: doc.title, description: doc.description, url:doc.url })   
};

Cette fonction me renvoi tous les documents de mon instance, trié par "_id" et avec une série de variables (title, description, url - je ne les réexplique pas, ce sont les mêmes que précédemment).

Passons à notre liste : lists/all.js

function(head, row, req, info) {
  // !json templates.all
  // !code vendor/couchapp/path.js
  // !code vendor/couchapp/template.js
 
  return respondWith(req, {
    html : function() {
      if (head) {
        return template(templates.all.head, {
          assets : assetPath(),
        });
      } else if (row) {
        return template(templates.all.row, {
          fav: row.value,
        });
      } else {
        return template(templates.all.tail, {
            assets : assetPath(),
        });
      }
    },
  })
};

La nouveauté ici tient dans la fonction qui prend différents paramètres en compte (contenus honteusement récupérés de benoitc "Légo 2 : les listes"):

  • head: est renseigné lorsque couchdb envoie la tête de la vue. head est un objet contenant les paramètres "total-rows" et "offset" correspondant au résultat de la vue. Cela nous permet, par exemple comme dans l'exemple ci-dessus, afficher l'entête d'une page html en chargeant un template particulier.
  • row : la ligne de la vue actuellement envoyée par CouchDB.
  • req : un objet contenant les paramètres de la requête
  • row_info : un objet contenant les infos sur la ligne en cours, sa position, quel était la ligne précendente, quelle est la première ligne de la vue.

L'autre nouveauté tient dans la gestion des templates HTML :

  • Pour head, on va charger templates/all/head.html
  • Pour chaque ligne de résultat, on va charger templates/all/row.html
  • Une fois que les résultats de la requête sont épuisés, on va charger templates/all/tail.html (qui fait donc office de voiture-balai).

Contenu de templates/all/head.html :

<!DOCTYPE html>
<html>
  <head>
    <title>My favs</title>
    <link rel="stylesheet" href="../../screen.css" type="text/css"/>
  </head>
  <body>
    <div id="header">
      <h2>My favs...</h2>
    </div>
    <div id="content">
      <h1>Recently...</h1>
      <dl id="bookmarks">

Contenu de templates/all/row.html :

  <dt><a href="<%= fav.url %>"><%= fav.title %></a></dt>
  <dd><%= fav.description %></dd>

Contenu de templates/all/tail.html :

    </dl>
  </div>
</body>
<script src="/_utils/script/json2.js"></script>
<script src="/_utils/script/jquery.js"></script>
<script src="/_utils/script/jquery.couch.js"></script>
<script src="<%= assets %>/vendor/couchapp/jquery.couchapp.js"></script>
</html>

Il ne vous reste plus qu'à pousser vos modifications dans votre instane CouchDB (ici en mode verbeux pour bien voir ce qui est poussé) :

tetram:mycouchfav nicolas$ couchapp push -v myfav
[INFO] push lists/all.js
[INFO] push shows/fav.js
[INFO] push templates/all/head.html
[INFO] push templates/all/row.html
[INFO] push templates/all/tail.html
[INFO] push templates/fav.html
[INFO] push vendor/couchapp/_attachments/jquery.couchapp.js
[INFO] push vendor/couchapp/couchapp.js
[INFO] push vendor/couchapp/date.js
[INFO] push vendor/couchapp/path.js
[INFO] push vendor/couchapp/README.md
[INFO] push vendor/couchapp/template.js
[INFO] push views/favs/map.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/template.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/path.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/path.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/template.js
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Rendez vous ensuite sur : http://localhost:5984/myfav/_design/mycouchfav/_list/all/favs

Au bout du compte, nous venons de voir pour les listes :

  • Les listes comme moyen d'afficher une vue,
  • Cela se traduit par un fichier de vue (views/mon_de_ma_vue/map.js) et un fichier liste (lists/<nom_de_ma_liste>.js)
  • La liste est une fonction de type function(head, row, req, info)
  • On peut spliter les templates en head.html / row.html / tail.html
  • url de type : http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_list/<nom_de_la_liste>/<nom_de_la_vue>?<paramètres>

Au bout de cette "journée"

Nous avons vu aux termes des parties 1 et 2 :

  • Comment installer couchapp et générer le squelette d'une application Couchdb
  • Jouer un peu avec Futon pour créer des enregistrements dans CouchDB (même si je ne le couvre pas directement, voir pas du tout en fait)
  • Comment afficher des documents sous forme de "list/views" pour une collection de documents et de "show" pour un document de façon unitaire

Il reste encore plein de choses à voir (au moins à mon niveau) :

  • Voir comment on peut remplacer le "My favs ... " dans head.html par une variable extérieure au template (facile - déjà fait mais cela rajoutait une grande quantité d"infos à ce post déjà très long je pense...)
  • Mieux comprendre les "!json" et "!code"
  • Les options de tri
  • <insérer votre sujet ici via un commentaire>
  • ...

Sources utiles

Les lectures indispensables pour faire ce tutoriel :

Au passage, les nouveautés de CouchDB / Couchapp mentionnées pat Benoit sont des plus intéressantes (surtout pour les listes, plus souple/flexible a priori).

Merci à benoitc pour éclairer ma lanterne sur couchdb/couchapp ces derniers jours :-)

Couchapp : créer votre première application CouchDB (Partie 1)

Je continue ma découverte de CouchDB avec Couchapp, logiciel qui se définit comme un ensemble d'outils pour simplifier le développement d'une application avec CouchDB.

Ce billet chercher à compléter / mettre à jour le billet de Benoit Chesneau : "Et les légos s'emboitèrent" que je vous conseille de lire par ailleurs.

Installation de Couchapp

tetram:CouchDB nicolas$ sudo easy_install couchapp

Cela vous installe couchapp 0.3.2 à ce jour.

Génération du squelette de votre application

tetram:CouchDB nicolas$ couchapp generate mycouchapp
[INFO] Generating a new CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchapp

Le contenu est le suivant :

tetram:CouchDB nicolas$ ls mycouchapp/
_attachments	lists		vendor
lib		shows		views

Pour pousser votre application dans votre instance CouchDB dans une base "monapp" :

tetram:CouchDB nicolas$ cd mycouchapp/
tetram:mycouchapp nicolas$ couchapp push monapp -v
[INFO] push vendor/couchapp/_attachments/jquery.couchapp.js
[INFO] push vendor/couchapp/couchapp.js
[INFO] push vendor/couchapp/date.js
[INFO] push vendor/couchapp/path.js
[INFO] push vendor/couchapp/README.md
[INFO] push vendor/couchapp/template.js
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchapp to design doc:
http://127.0.0.1:5984/monapp/_design/mycouchapp
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/monapp/_design/mycouchapp/index.html
[INFO] Attaching index.html (413)
[INFO] Attaching style/main.css (21)
[INFO] Attaching vendor/couchapp/jquery.couchapp.js (6984)

Si vous ouvrez votre navigateur sur http://127.0.0.1:5984/monapp/_design/mycouchapp/index.html, vous voyez l'écran suivant :

Couchapp-1.png

A ce stade, 2 commandes ont été utilisées :

  • generate : crée le squelette d'application
  • push : envoie l'application dans couchdb

Si vous voulez récupérer une application de couchdb, il faut utiliser la commande "clone". Cela permet d'éditer votre application couchdb depuis votre disque dur et non plus depuis futon par ex. Au passage, vous ne pouvez pas cloner votre application dans le même répertoire que l'initial :

tetram:mycouchapp nicolas$ cd ..
tetram:CouchDB nicolas$ couchapp clone http://127.0.0.1:5984/monapp/_design/mycouchapp
[CRITICAL] an app already exist here: mycouchapp

Il vous faut donc spécifier un chemin différent :

tetram:CouchDB nicolas$ couchapp clone http://127.0.0.1:5984/monapp/_design/mycouchapp mycouchapp-cloned
[INFO] Cloning mycouchapp to mycouchapp-cloned...
tetram:CouchDB nicolas$ ls mycouchapp-cloned/
_attachments	lib		shows		views
couchapp.json	lists		vendor

A noter que la version clonée a un fichier couchapp.json en plus et donc je ne connais pas encore l'intérêt / l'utilité à ce stade.

Si on revient un instant sur ces répertoires :

  • _attachments contiendra les fichiers attachés à votre application
  • views contient les vues
  • lists contient les listes de vues ; utilisées par ex pour une page listant les 10 derniers documents par ex style page d'accueil d'un blog.
  • shows contient les rendus d'un document ; la visualisation d'un article d'un blog par ex.
  • lib contient les modèles et macros
  • vendor contient des composants tiers fournis par couchapp pour le moment mais on peut imaginer je suppose d'autres briques tierces dans cet espace .

Voilà pour un début, dès que je suis plus clair sur les listes / vues / rendus, vous aurez droit à un autre billet :-)

Lecture : High Performance MySQL

L'intranet du groupe JCDecaux utilisant MySQL comme base de données, et devant travailler sur les problématiques de scalabilité / Plan de reprise d'activité, je m'étais acheté le livre "High Performance MySQL", considéré comme la référence en la matière. Autant le dire de suite, je n'ai pas été déçu et s'il avait été publié chez Apress, il aurait été appelé sans aucun doute : "MySQL : The definitive guide".

Contrairement à ce que pourrait laisser croire le titre, il ne se focalise pas uniquement sur la performance. Ou sinon il faut l'entendre comme utiliser MySQL de façon performante à tous les niveaux (code, infrastructure, sécurité, backup, etc).

Le livre couvre les sujets suivants :

  • Architecture de MySQL (architecture logique, moteurs de stockage, etc)
  • Benchmark et profilage en vue de trouver les goulots d'étranglements
  • Optimisation des schema et des index
  • Optimisation des requêtes
  • Fonctionnalités avancées de MySQL (Vues, Cache, Partitionnement, Clés étrangères, etc)
  • Optimisation de la configuration du serveur MySQL
  • Optimisation système et logicielle d'un serveur MySQL
  • Réplication
  • Montée en charge et/ou haute dispo
  • Optimisation applicatives (Serveur web, Cache, etc)
  • Sauvegarde et restauration
  • Sécurité
  • Les status d'un serveur MySQL (Show status & co)
  • Outils de consultation, surveillance, analyse, etc d'un serveur MySQL

J'ai bien aimé :

  • La complétude du livre : même si je ne suis pas concerné par tous les chapitres, au moins on a au final une vue complète sur MySQL. Dans ce sens, il devrait être lu par toute personne touchant de près ou de loin à MySQL
  • La prudence / le pragmatisme / les conseils sur les aspects performance et sur les capacités de MySQL face à tel ou tel objectif.

J'aurais bien aimé :

  • Sur la réplication, un peu plus de détail sur l'implémentation de certaines typologies de réplication - seul le cas basique (maitre/esclave) est couvert techniquement. Pour les autres cas, c'est plus une présentation + SWOT qu'une implémentation qui est proposée dans le livre.
  • Peut être une meilleure formulation de certains ratios car pour réussir à en calculer certains, c'est pas aisé aisé.
  • Au niveau configuration, ils auraient pu parler de la surchage de la configuration par défaut (une mise à jour du tutoriel va arriver prochainement) via les directives include et/ou includedir.

Je n'ai pas aimé :

  • Rien :)

Par contre, moi qui était globalement un partisan de MySQL, j'avoue être un peu refroidi par certains cotés dans le cadre d'un déploiement en entreprise (lié à la lecture du livre et l'expérience d'intégration/production à JCDecaux) :

  • L'instructon "Stop Slave" jusqu'à la version 5.1.35 arrête la réplication sans attendre la fin de la transaction en cours.
  • La sauvegarde par copie physique des fichiers a l'air plus que fragile.
  • La sauvegarde par export logique (à la mysqldump) semble être la seule voie stable avec pour inconvénient de (re)jouer un grand nombre de requêtes SQL (et donc d'être plus longue qu'une sauvegarde physique)
  • La gestion des log innodb (/var/lib/mysql/ibdata* /var/lib/mysql/iblogfile*) que l'on ne peut pas purger sans reconstruire complètement son serveur. Le risque étant que ces fichiers remplissent la partition s'ils ne sont pas limitées en taille ou que si la taille est atteinte, alors votre applicatif est figé. Coté indisponibilité de service, c'est pas mal non plus...
  • Le fait de mixer des tables au format MyISAM et InnoDB créent des contraintes d'exploitation potentiellement assez intéressantes puisque suivant le type de table, il ne faudrait pas utiliser les mêmes options pour mysqldump par ex. De même au niveau tuning, vu les ressources limitées d'un serveur, l'arbitrage du tuning entre les 2 types de tables peut être globalement "sous-performant"

Du coup, je crains que MySQL, dans le contexte JCDecaux, se limite à des petits applicatifs ou avec une criticité pas trop élevée alors que SQL Server / Oracle sera utilisé pour le reste.

CouchDB - Premier tour d'horizon

Pour ceux qui ne connaissent pas (encore) CouchDB : c'est une base documentaire (et non pas relationnelle comme MySQL, PostgreSQL, Oracle, etc) qui possède les caractéristiques suivantes :

  • Pas de schéma ("schema-less") : contrairement aux bases de données relationnelles, la modification du schema de votre base ne revient pas à modifier votre schéma pour tout l'existant. Seulement pour le document en question, voir pour la révision du document en question. Vous êtes donc beaucoup plus libre dans la gestion de vos documents.
  • Tolérance à la panne ("Fault tolerant") avec en prime des mécanismes de réplication distribuée, une gestion des conflits, etc.
  • Accès aux données via une API RESTful JSON/HTTP
  • Peut être indexé/requêtée
  • Les requêtes se font en Javascript

Pour appréhender CouchDB, je vous invite à parcourir les slides données par J Chris Anderson, un des fondateur de couchdb. Accessoirement, CouchDB est maintenant un projet Apache, d'où l'url : http://couchdb.apache.org/.

J'avais lu des slides sur couchdb en février 2008. J'avais trouvé ça fort intéressant mais vu la jeunesse du projet et mes objectifs de l'époque, je l'avais laissé de coté. J'avais eu une piqure de rappel en lisant les slides de pycon-fr 2008 de Benoit Chesneau sur Couchdb et Python. J'ai eu ma dernière piqûre de rappel lors de pycon-fr 2009 toujours par Benoit lors de sa présentation Python et les bases de données non-SQL.

Tout ça pour dire que pour commencer à appréhender CouchDB, je vous conseille :

  • L'introduction et la vue technique (la fin peut être lue en diagonale éventuellement) sur le site du projet,
  • Le livre en ligne "CouchDB : the definitive guide. Même s'il n'est pas encore fini, les premiers chapitres permettent de se faire une idée plus claire sur l'écosystème CouchDB.
  • La série de billets de Benoit Chesneau sur CouchDB. Il en prévoyait 6, je n'en vois que 3 pour le moment... Cela permet de décanter un peu ce que l'on a lu en anglais et de mieux comprendre comment se positionnent les "couchapps" vis à vis de CouchDB.
  • Sous Mac OS X, plutôt que vous embêter avec les ports, il y a CouchDBX qui fait tout tout seul, le tout dans un unique package et avec une interface graphique dédiée à Futon (l'interface d'administration de CouchDB).

Dans ce que j'ai pu également glaner sur le web :

Questions résolues :

  • La connexion entre un framework MVC et le coté "Schema free" de CouchDB a-t-il du sens ? Niko m'a répondu : "model means business, not rdbms nor persistence"

Questions à élucider :

  • L'ajout d'un champ dans un document : comment se comporte la vue mise à jour pour les anciens documents ? Apparemment, le javascript fait un test d'existence lors de la fonction de type "Map"... donc pas de problème mais à confirmer.
  • A partir de quel moment il faut sortir du socle CouchDB pour y insérer un Django par ex ? Dès lors que l'on ne peut pas réaliser une action en javascript ?
  • Plein d'autres non formulées à ce stade

En tous cas, CouchDB m'a fait changer mon point de vue sur Javascript ;-)

Affaire à suivre...

Compte Rendu Pycon-FR 2009

Je me suis rendu cette année à la 1ère matinée de Pycon-FR ou j'ai pu revoir David et Samuel Martin notamment (et pour ce dernier, de récupérer un linutop 1ère génération en échange de mon reste de tour...)

Ci-après mes notes sur les confs auxquelles j'ai pu assister et mon avis sur l'événement en toute fin.

Les slides sont disponibles en ligne et les vidéos devraient arriver prochainement.

Comment python va dominer le monde ?

Sur le constat du manque de visibilité de python / php, java, ruby, 3 axes de travail :

  • Visibilité
    • Presse -> suppose un effort de rédaction
    • Blog / Planet pour faire le buzz
    • Conférences / Barcamp + retombées indirectes suite à la conf. --> idée en cours d'un "world python day" ???
    • Participer à des événements pour propager python
    • Sucess Stories (OLPC, Launchpad, etc)
  • Formation
    • Exemple du Python African Tour : formation sponsorisées où on envoit des volontaires dans une université en Afrique => 3/4 par an, déjà 1 session organisée - Senegal/Zambie sur S2.
  • Communication / Communauté
    • Sprints : découvrir / documenter / coder / screencasrts/ apprendre aux débutants
    • LUG

Correction d'un bug et naissance d'une nouvelle fonctionnalité dans CPython

  • Panorama des canaux d'échanges et sources d'info sur python (python-ideas, pep, tickets, etc)
  • Bonnes pratiques pour la remontée de bug (sur la doc, le language, etc)
  • Python 2.5 n'accepte plus les corrections de bug - uniquement les bugs de sécurité. (2.6 & 3.0 maintenus, 2.7 & 3.1 en dev)
  • >~ 90% du code de python est couvert par les tests
  • Les tests deviennent une sorte de spécification du langage - Pypy et Jython se sont appuyés sur les tests pour être implémentés.
  • 100 commiteurs sur python,

PyQuery - Manipuler du html/xml à la jQuery en python

  • Utilisateur de selecteur CSS plutot que XSLT/XPATH (trop verbeux ou complexe) / selecteur CSS
  • le $ de jsquery est remaplcé par un "d"
  • Utilisation possible : web scrapping, manipulation xml/html pure, web testing, temaplating
  • Pas sur de comprendre / voir l'intérêt de la chose par rapport à du jquery "dans le texte".

Skinner vos applications web avec Deliverance

  • Mécanisme de proxy intermédiaire entre l'internaute et l'application afin de pouvoir reskinner à la volée une partie d'une application (ajout / suppression / remplacement) d'éléments, sans toucher à l'application originale
  • Overhead estimée à 4/6% - Acceptable puisque cela évite de devoir reskinner chaque application (ce qui peut nécessiter de connaitre la techno sous-jacente à l'application).
  • Attention aux problématiques de reroutage d'url (Deliverance en gère un bout mais si vous avez plusieurs formulaires dans une même page qui pointent vers différentes choses, attention aux résultats...)
  • PyQuery utilisable dans Deliverance
  • Plutöt fait pour reprendre une application principale et rajouter des données à la marge que d'adopter une logique de portail

Bases de données Non SQL

  • Présentation des termes ACID / CAP / BASE
  • Panorama des bases non-sql (clé/valeur : memcached, tokyo cabinet, etc ; documentaire : monbo-db, couchdb ; misc : hbase, etc) et des outils python existants pour utiliser ces bases de données.
  • Gros intérêt des bases documentaires / bases relationnelles notamment au niveau des migrations (suffit de créer une nouvelle version d'un document...)

Bilan des courses

Mis à part le parking de la Vilette que j'ai eu un peu de mal à trouver à cause des travaux (la Vilette m'avait prévenu, j'ai été enchanté par cette matinée et bien frustré de ne pas avoir pu y assister davantage. J'aurais bien aimé voir notamment les confs sur django, atomisator, twisted et couchdbkit.

La grande hétérogénéité des sujets permet de voir plein de choses différentes, même si on n'y a pas un intérêt direct dans l'histoire. C'est toujours instructif.

Coté organisation, rien à redire, c'était nickel pour ce que j'en ai vu. J'ai (enfin) payé ma cotisation de membre et fait le plein de t-shirts, sans oublier un petit badge ;-)

Autre conclusion plus personnelle, il faut vraiment que je me pousse aux fesses pour assister à plus d'événements de ce type et ne pas me laisser faire par de fausses bonnes / mauvaises raisons. C'est vrai que de ma "campagne", j'ai pas toujours le courage de me rendre à l'autre bout de Paris... ;-)

Vivement l'année prochaine donc et à plus court terme que les vidéos soient en ligne que je puisse visualiser ce que j'ai manquer...

Apache : mutualisation, inclusion et ordre

Ordre

Une des fonctionnalités intéressante d'apache d'un point de vue administration est de pouvoir déposer des fichiers de configuration complémentaires sans avoir à toucher au fichier de configuration de base, et ce dans le répertoire /etc/httpd/conf.d/ ou /etc/apache/conf.d suivant la distribution utilisée.

Il faut néanmoins faire attention à un point, les fichiers sont chargés dans l'ordre alphabétique. Par ailleurs, dans une configuration avec une IP utilisant les virtualhost (qui ose ne pas les utiliser ?) il faut que le premier virtualhost chargé contienne la directive NameVirtualHost xxx.xxx.xxx.xxx:xx

Il vous faut donc adopter l'ordre suivant :

  1. Fichiers chargeant les modules apache requis pour le(s) site(s)
  2. Fichier chargeant le vhost avec la directive NameVirtualHost xxx.xxx.xxx.xxx:xx
  3. Reste des fichiers de configuration des virtualhosts
  4. Autres fichiers

Cela vous évitera de perdre comme moi 2h la semaine dernière à tenter de comprendre pourquoi l'authentification NTLM ne fonctionnait plus sur une url mais bien sur une autre. L'ordre alphabétique des fichiers faisait que j'avais inversé le point 1 et 2. Par contre, pour l'url d'un site situé en 3, comme le module avait été chargé en phase 2, alors l'authentification était fonctionnelle pour ce site...

Inclusion

Le module "core" d'apache fournit la directive Include très utile dans la cas où il faut reproduire une configuration identique pour plusieurs virtualhosts. Prenons le cas de deux sites réalisés avec le même outil et accessibles sous deux urls différentes (monsite.fr et monsite.com par ex). Ces deux sites possèdent le même jeu de réécriture d'url (ie celles fournit par le produit).

Une première et mauvaise façon de faire serait de créer 2 fichiers de configuration contenant à chaque fois l'ensemble de la configuration. En cas de modification d'une règle, il vous faut faire la modification à deux endroits.

Cela vous donnerait un fichier du type /etc/httpd/conf.d/www.monsite.fr.conf :

<VirtualHost *>
    ServerName www.monsite.fr
    DocumentRoot /var/www/monsite

    <Directory /var/www/monsite/>
        ...
        Ensemble d'instructions
        ...
    </Directory>

    ...
    [Jeu d'instrusctions de réécriture]
    ...

    ErrorLog ...
    AccessLog ...
</VirtualHost>

Idem pour monsite.com (/etc/httpd/conf.d/www.monsite.com.conf)

La bonne façon de faire est la suivante : /etc/httpd/conf.d/www.monsite.fr.conf

<VirtualHost *>
    ServerName www.monsite.fr
    Include /etc/httpd/application/directory.txt
    Include /etc/httpd/application/rewrite_rule.txt

    ErrorLog ...
    AccessLog ...
</Virtualhost>

et /etc/httpd/conf.d/www.monsite.com.conf

<VirtualHost *>
    ServerName www.monsite.com
    Include /etc/httpd/application/directory.txt
    Include /etc/httpd/application/rewrite_rule.txt

    ErrorLog ...
    AccessLog ...
</Virtualhost>

Avec /etc/httpd/application/directory.txt :

    DocumentRoot /var/www/monsite

    <Directory /var/www/monsite/>
        ...
        Ensemble d'instructions
        ...
    </Directory>

et /etc/httpd/application/rewrite_rule.txt :

    [Jeu d'instrusctions de réécriture]

Ainsi, on peut mutualiser au maximum au niveau de la configuration d'apache, sans se priver de pouvoir rajouter des directives propres à un virtual host en incluant des fichiers supplémentaires.

Ex si on a une couche SSO pour un site et une version anonyme :

/etc/httpd/conf.d/intranet.monsite.fr.conf

<VirtualHost *>
    ServerName intranet.monsite.fr
    Include /etc/httpd/application/directory.txt
    Include /etc/httpd/application/rewrite_rule.txt
    Include /etc/httpd/application/authentification_SSO.txt

    ErrorLog ...
    AccessLog ...
</Virtualhost>

et /etc/httpd/conf.d/intranet.monsite.com.conf

<VirtualHost *>
    ServerName intranet.monsite.com
    Include /etc/httpd/application/directory.txt
    Include /etc/httpd/application/rewrite_rule.txt
    # Include /etc/httpd/application/authentification_SSO.txt

    ErrorLog ...
    AccessLog ...
</Virtualhost>

Bien sur, vous pouvez mettre vos fichiers ailleurs que dans /etc/httpd/application :-)

Pycon FR 2009 - Le programme est disponible !

L'AFPy (Association Francophone Python - http://www.afpy.org/ ) organise le week-end du 30/31 mai à la Vilette la 3ème version de Pycon FR (aka Conférence Python, version française).

Le programme varié et riche est disponible ici : http://pycon.fr/sessions - Il me reste encore à affiner mon programme de la journée entre les différentes conf :-)

Pour ma part, j'y serais à coup sûr le samedi et de façon peu probable le dimanche - au plaisir de vous y retrouver :-)

Des choix techniques et d'infrastructure

Je discutais cet après-midi avec un de nos architectes sur les distributions Linux en lui faisant remarquer que CentOS 5.3 était sortie 2 mois après RHEL 5.3 et que Fedora Cora 11 (probable base de RHEL 6, à moins que cela ne soit Fedore Core 10) va sortir dans 15 jours. Personnellement, j'espère que ce sera Fedore Core 11 (PHP 5.2.9, voir 5.3 avec les updates ?) vu que PHP n'a pas été mis à jour depuis FC9 (PHP 5.2.6) et surtout parce que cela m'éviterait de recompiler les paquets PHP pour faire marcher notre intranet groupe sous eZ Publish 4.0.x

Tout ça pour aborder différents points :

De l'harmonisation / industrialisation des plate-formes

  • Personnellement, je préférerais utiliser autre chose que notre socle RHEL 5.2 car dans la mesure où je dois maintenir un certain nombre de paquets, je préférerais par exemple utiliser une Fedora ou une Slackware qui fournit nativement la (quasi) totalité des paquets dont j'ai besoin. Cela éviterait de payer des licences et un support, support auquel je ne peux surement pas ou peu faire appel vu que j'utilise des paquets autre que les paquets officiels.
  • A contrario, il y a une logique d'entreprise de capitaliser à ce jour sur 2 distributions Linux : RHEL pour l'applicatif et Slackware pour l'infrastructure.
  • En y repensant, Slackware, même si elle remplit les besoins de base pour une site LAMP classique, se verrait sûrement disqualifier dès lors qu'il faut se connecter à des bases Oracle / SQL Server (suis pas sur que les extensions Oracle / SQL Server soient fournis pour PHP par ex). Idem PostgreSQL ne fait malheureusement pas parti des paquets officiels Slack (il existe des slackbuilds certes).

Est-ce que l'infrastructure technique doit imposer des choix logiciels ou bien doit-elle s'adapter aux projets

  • A propos de se cantoner au paquets officiels, faut-il dire que l'infra pilote les pré-requis d'un projet ? Dans le cas de l'intranet groupe, si on ne s'était pas adapté aux pré-requis eZ Publish, il aurait fallu disqualifier le produit. La solution de monter une plate forme sur une autre distribution me parait exclue car n'allant pas dans la logique d'harmonisation / industrialisation.
  • Il peut certes être séduisant d'imposer une infrastructure pour des contraintes d'exploitabilité / de maîtrise du parc / ...
  • Personnellement, je pense que c'est à l'infrastructure de s'adapter dans la mesure du raisonnable. Passer à côté de solutions répondant aux problèmes des utilisateurs pour une histoire de version de composant me semble être une hérésie et symboliser l'échec de la mission d'une DSI à l'égard de ses utilisateurs. Ce doit être mon côté fonctionnel qui ressort...

Distribution commerciale vs opensource vs bleeding edge vs ...

  • Pour faire des économies en ces temps de crise, est-il judicieux par ex de monter des environnements de VABF / PREPROD sur du CentOS et la PROD sur du RHEL (Pour rappel et en schématisant CentOS == RHEL - logo Red Hat). Cela peut être séduisant mais à bien valider...
  • Pour les applis web requérant des versions "à jour / bleeding edge" de certains composants, peut-on imaginer une plate forme Fedora alors que pour les applicatifs de gestion (ie requérant des certifications RHEL comme SAP, Oracle, etc) on mise sur du RHEL (après tout, Fedora est la base / le laboratoire de RHEL et personne n'oblige à faire les mises à jour tous les matins)
  • Vaut-il mieux investir sur Fedora / RHEL plutôt que RHEL + paquets maison (un peu dans la même veine que précédemment) ? Il serait intéressant de déterminer à partir de quand le coup de possession de Fedora est moindre que celui de RHEL + Paquets maison + contexte d'infogéreur (ah les complexités de système...)
  • Ne me parlez pas d'investir sur Debian, c'est exclu ;-)

Avis ? Retours d'expériences ? Commentaires ? Questions ?

Dons / Echanges composants informatiques

Donne ou échange (cf wishlist amazon) :

  • 1 routeur Linksys WRT54GL 1.1 avec firmware officiel linksys
  • 1 serveur d'impression sans fil Linksys WPS54G
  • 1 Linutop 1 avec son alimentation + Clé USB 1 Go sous Xubuntu 08.04

Pour la livraison, idéalement région de Versailles / Saint Quentin en Yvelines / Plaisir. Pour des livraisons plus lointaines, a voir si vous prenez en charge les frais d'envoi ou en fonction de la "contrepartie" - l'idée étant que cela ne me coûte rien ou pas grand chose et que cela rende service à ceux que cela peut intéresser.

Avis aux amateurs...

Mis à jour le 27/6

Proposition de stage / contrat d'apprentissage eZ Publish chez JCDecaux

Si vous êtes à la recherche (ou connaissez des gens susceptibles d'être intéressés) d'un stage ou d'un contrat d'apprentissage pour travailler sur des projets web avec les outils eZ Publish (Intranet groupe principalement, Sites web vélos éventuellement) ou Symfony (probabilité plus faible mais sait-on jamais), n'hésitez pas à me contacter à l'adresse : nsteinmetz AT gmail POINT com.

Le stage / contrat d'apprentissage se déroulerait à Plaisir (78)

- page 1 de 18

Bienvenue

Ce blog en actuellement en cours de travaux :-)

Pour les liens en tous genre, voir en haut & pied de page