December 2006

RDF Schema mapping in OO paradigm

Sat 30 December 2006, , , , ,

I tried to dompt ActiveRDF to manager a real inheritance model but with a lot of pain. It’s a hard issue. Today, I try to play with Redland in Python, only to feel the pain that it is. I’ve first played with RDF in Java with Jena, so it’s a little pain today.

What’s hard ? A true OOP model is difficult to manage because a parent class need to know his sons to do a find_all for example. In SPARQL, to find all elements that are a Dad:

PREFIX rdf: \
  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX my: http://example.org/
SELECT ?node WHERE
  { ?node rdf:type my:Dad . }
  UNION
  { ?node rdf:type my:Son . }

Here, you get every element that is a Dad and a Son (if you have in mind that my:Son rdfs:subClassOf my:Dad, it’s logical I think)

With OOP in mind, it means that the Dad knows all sons he have at every degree. It’s counter-intuitive for every programming language. It’s counter intuitive if you put this searching feature in the Dad itself like I did. The model is the only thing that knows everything. Why not delegated this feature to it?

I wrote a piece of code (source, rdf) to experiment this. It’s not very clean but you can show the problem (and test it of course).

N’arrivant pas à mes fins avec ActiveRDF, j’ai eu envie d’essayer avec Python et l’API offerte par Redland pour manipuler du RDF.

Le grand problème est que le modèle du schéma RDF n’est pas aisément traductible en orienté-objet pour la raison suivante : l’héritage (qui peut être simple comme multiple, hein Fabio!). En effet, un élément parent doit pour, par exemple, permettre à l’utilisateur d’obtenir tous les éléments de son type, connaître tous ses fils (et petits-fils). De dire : « Je veux tous les éléments étant des pères ! » implique qu’il faut connaître tous les éléments dérivant de ce type là. Choses assez contre-intuitive dans la programmation orientée-objet.

J’ai joué avec la bête (source, rdf) risquer vous-y seulement. Le travail qui est fait par Eyal Loren, dans le cadre d’ActiveRDF, est ardu car faire le mapping d’un modèle RDF (donc un graphe) dans un modèle orienté-objet est extrêment complexe. Ruby est ici certainement plus flexible que Python. Je n’ai pas trouvé comment créer une classe à la volée en Python.

Je serais intéressé par voir ce qu’il est possible d’obtenir avec CherryPy et Redland, vis-à-vis d’ActiveRDF. La force de Redland est que, comme il faut tout faire soi-même, il n’a a pas de barrière « logicielle », j’ai pour l’instant laissé en suspens mes projets de jouer avec FOAF et ActiveRDF.

Minimal OpenID authentication system with RoR

Thu 28 December 2006, , , ,

I’ve talked to you about OpenID a couple of time ago, now I gonna show you how to do an OpenID authentication with Rails.

First step install rails and start a rails website.

# gem install rails

$ rails openid

Now install the OpenID login generator and run it.

# gem install openid_login_generator

$ cd openid
$ script/generate openid_login auth

Open the README_LOGIN file and read it, I’ll resume it here. The file app/controller/application.rb should look like.

require_dependency "openid_login_system"

class ApplicationController < ActionController::Base
	include OpenidLoginSystem
end

The database configuration (config/database.yml). SQLite: keep it stupid simple, but continue to use MySQL maybe more reliable but it’s not the purpose here.

development:
  adapter: sqlite
  database: db/openid_dev.db

Init the database :

$ sqlite3 db/openid_dev.db "CREATE TABLE 'users' \
( \
  'id' INTEGER PRIMARY KEY NOT NULL, \
  'openid_url' VARCHAR(256) DEFAULT NULL \
);"

And test it!

$ script/server

Open your browser at http://localhost:3000/auth/login/ enter your OpenID id. You should log in. Now you can verify that it worked in the backend too.

$ sqlite3 db/openid_dev.db
> .dump

You’ll se a line like this one.

INSERT INTO "users" VALUES(1, \
  'https://yoan.blanc.myopenid.com/');

Marvellous! Every Rails applicaiton can be OpenID compatible in very easy way. Don’t forget to RTFM and have fun.

...for the Djangoists, they can follow this tutorial CookBook Shortcuts OpenID Authentication.

Il de ça quelques temps, je vous avais parlé de OpenID, la petite révolution en marge des Microsoft Passports. Aujourd’hui, nous allons voir ensemble par un tutoriel aussi ludique de trivial comment créer sa première application web (si c'est le cas) avec Ruby On Rails permettant l’authentification via OpenID, donc une authentification décentralisée, merveilleux.

Les prérequis sont d’avoir installé RoR, SQLite et OpenID Login Generator. À priori, il y a tout ce ses pages pour vous en sortir seul, mais rien ne vaut de se faire prendre par la main (non non pas de screencast, faut pas pousser).

# gem install rails \
  openid_login_generator sqlite3-ruby

Allez, au lieu de faire la moue, sortez-moi un term et hop ! (La version anglaise est plus light, n’hésitez pas à vous y référer si je vais trop vite.)

$ rails openid
$ cd openid
$ script/generate openid_login auth
$ sqlite3 db/openid_dev.db "CREATE TABLE 'users' \
( \
  'id' INTEGER PRIMARY KEY NOT NULL, \
  'openid_url' VARCHAR(256) DEFAULT NULL \
);"
$ (echo <<EOF
development:
  adapter: sqlite3
  database: db/openid_dev.db
EOF
) > config/database.yml
$ script/server
		

Maintenant, ouvrez la page http://localhost:3000/auth/login entrez-y votre OpenID, et vous devriez arriver sur la page /auth/welcome vous félicitant car vous le méritez bien.

Une petite vérification de notre base de donnée.

$ sqlite3 db/openid_dev.db .dump | grep "INSERT"
INSERT INTO "users" VALUES(1, \
  'https://yoan.blanc.myopenid.com/');

Que dire: « merveilleux ! »

Que les Djangoïstes ne soient en reste, on trouve plus ou moins la même fonctionnalité à moindre coût également pour ce merveilleux framework en Python : CookBook Shortcuts OpenID Authentication.

Some Queries with Active RDF

Tue 26 December 2006, , ,

Let’s start with the Query API of ActiveRDF that match SPARQL. If you don’t understand a word, start reading the related entries or drop me a mail.

First of everything, the model (rdfs). I’ve made a little UML schema to help you. RDF Schema is similar to UML, but it’s a graph.

RDF Schema

There is:

a Person
with a name
a Student
who is a Person
a Teacher
who is a Person too
a Course
with a name, one Teacher and zero or more Students

The cardinality cannot be achieved with RDF Schema, OWL is the right (but not the only) way to put cardinality on a schema.

Now the data, a nice graph with two students, a professor and a course :

Data

Our first query gonna be very trivial. (Already done by ActiveRDF in fact)

Namespace.register :simples, \
	'http://yoan.dosimple.ch/beta/simple.rdfs#'

# rdf:type and simples:Teacher
type = Namespace.lookup(:rdf,:type)
teacher = Namespace.lookup(:simples, :Teacher)

# the same than: SIMPLES::Teacher.find_all
puts Query.new.distinct(:name) \
	.where(:name, type, teacher) \
	.execute

# output:
#<http://yoan.dosimple.ch/beta/simple.rdf#professor>
		

Query 1

Find every teacher. Now we gonna try to find the students’ name :

# simples:Student and simples:name
student = Namespace.lookup(:simples, :Student)
name = Namespace.lookup(:simples, :name)

puts Query.new.distinct(:name) \
	.where(:s, type, student) \
	.where(:s, name, :name) \
	.execute

# output:
#Yoan Blanc
#Batiste Bieler
		

Query 2

So easy ! Next, a bigger query on the whole graph!

 # simples:teacher, simples:students
teach = Namespace.lookup(:simples, :teacher)
study = Namespace.lookup(:simples, :student)

puts Query.new.distinct(:cname, :tname). \
	where(:s, name, "Yoan Blanc"). \
	where(:c, study, :s). \
	where(:c, name, :cname). \
	where(:c, teach, :t). \
	where(:t, name, :tname). \
	execute

# output:
#RDF and RDF Schema
#Professor’s name
		

Query 2

Find every courses of the student called “Yoan Blanc” and return the name of the course and the teacher’s name of them.

Next step of that is to build a Web Application that use a Semantic Database as backend. I wanna play with FOAF (for the social part), SKOS (for the tagging) and maybe a homemade RDF Schema inspired by Annotea. Sounds like the first web 2.0 application I’ve met years ago. Keep it touch.

Fonçons dans une fonctionnalité de ActiveRDF, les requêtes (Query) qui permettent à la manière de SQL d’extraire une vue de nos données. L’écriture est très similaire à SPARQL car la philosophie derrière est la même. Si vous n’avez pas compris un traitre mot de la phrase ci-dessus, cette entrée fait partie d’une série, lisez donc les articles relatifs (voir à la fin).

Pour faire des requêtes, il est bien important de connaître le modèle. J’ai réalisé une schéma selon le formalisme UML ci-contre. RDF Schema remplit plus ou moins la fonction de UML, mais avec la contrainte du graphe. Le modèle contient des étudiants, des professeurs (qui sont des personnes) ainsi que des cours. Un cours possède un professeur et n étudiants. En passant, les contraintes de cardinalité ne peuvent être satisfaite avec RDF Schema seul, OWL permet lui de les décrire.

Ensuite, selon ce modèle, nos données. Donc au plus simple avec deux étudiants qui assistent à un cours dispensé par un professeur. Sur ces données qui respectent notre modèle, nous allons effectuer des requêtes simples. Merci de basculer sur la zone anglophone pour les détails du code et les schémas.

La première requête qui est un fonction incluse dans ActiveRDF (.find_all) va retourner tous les professeurs.

La seconde, le nom de tous les étudiants.

Et la dernière, qui est intéressante car elle touche tous le graphe, tous les cours que suit l’étudiant « Yoan Blanc » en retournant le nom du cours ainsi que le nom du professeur dispensant ce dernier.

Je pense qu’il y a maintenant tous les outils nécessaire à la création d’une application web avec un backend sémantique. J’ai l’envie de me lancer avec FOAF, SKOS et un dérivé d’Annotea... Que cela vous inspire-t-il ? Plus de détails tantôt.

Catch the ball and run

Mon 18 December 2006,

One day, a smart guy asked me if I am that sort of developer, a guy who can catch the ball and run. A developer with a sharped-eye and big balls. It was not an easy question because I known that my major bad point is to be that young. It’s hard to be trusted and harder when the guy in front of you knows already that technically you’re good, obviously an eager-to-learn and critical mind. You have to show him that there is no fear in your eyes, just the fire of achieving great and beautiful things. The beauty is the most important point for a developer. He needs to love his creature to take care of it and days after days embellish it.

In every successful work, there is a bit of love, passion.

An other meaning of that expression is the idea of a team, like a rugby team (or whatever full-of-men ball game), focused on the same target, looking in the same way. This team isn’t only your colleagues, but your manager, your trainer, your family, your social life, your physical preparation, ... So, are you ready to join this team and become the brother, friend, son, dad of every person in here. Are you a kid or a man ? One drunk Norwegian guy told me some weeks ago that if you’ve got the balls, you can go everywhere and do whatever you want.

Actually I don’t know if I’ve got the balls but I know that I’m not using them as often as they should be. Where is the fight ? Where is my fight, my game, my challenge ? Where is the place where I can give my best and go further the known limits. Like in love, I want to be stomached every day to fell the passion not only a we-fuck-we-are-happy relation, passion.

I wanna to build something. I haven’t the idea, neither the sight or the credibility, just my hands and they are ready to accomplish something. If you are a manager for Dublin, I thank you for asking me this question.

Lors d’un entretien, un manager m’a demandé si j’étais une personnalité capable d’attraper la balle et de courir, de toute mon énergie pour aller placer le point. Si j’étais ce type de développeur avec l’oeil aiguisé et une bonne paire pour foncer dans le tas. Cette question m’a un peu déroutée, car je savais que mon mauvais point était ma relative jeunesse en ce bas monde. Et même si j’avais relativement bien démontré mes aptitudes techniques auparavant, il était là question de montrer comment, moi, je pourrai leur donner mieux qu’ils n’osent imaginer. Montrer que dans mon regard vivait une flamme et pas non que se terrait la peur, qu’il y avait l’énergie de faire de belles choses.

Un projet n’est pas une balle qu’on va placer en touche, c’est une balle que l’on va pousser en touche. Lui donner la force et l’ampleur nécessaire pour qu’avec toute la beauté d’un trick shot tout soit parfait, juste bien.

La métaphore de la balle, du sport d’équipe plein de testostérone en ébullition, d’une équipe de rugby par exemple, est que pour qu’une personne, moi, arrive à mettre en touche, il faut le collaboration de l’équipe entière, le soutien, la direction et les conseils d’un entraîneur, l’amitié de potes, l’oreille confidente d’une mère, d’une amie, etc. Et il faut savoir et pouvoir s’appuyer sur cette équipe. Et ça, c’est le plus difficile à faire passer, à en obtenir le crédit. Je n’y ai pas réussi d’ailleurs.

Plus personnellement, j’aime la programmation pour ses aspects de mécaniques, de tortures de l’esprit, son insolvabilité apparente, pour ses solutions géniales et le bonheur qu’il en résulte lors de l’accouchement du bébé. J’aime faire un élément qui va servir, qui est requis où il y a un appel. Ainsi, je peux penser en conséquent, me mettre dans la peau du demandant, lui amener ce dont il a besoin.

First step with ActiveRDF

Mon 11 December 2006, , ,

After the Pain-in-the-a** issue of yesterday. I’ll try to be more practical today with a gentle introduction to ActiveRDF.

First, install it. You need Ruby and Ruby Gems (it’s just like the Pythonic eggs).

gem install activerdf
gem install activerdf_rdflite
gem install sqlite3-ruby

Now, pick up a RDF Schema somewhere (sucked from there) convert it into NTriples (with rapper).

Now create some datas.

<?xml version="1.0"?> 
<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:foaf="http://xmlns.org/foaf/0.1/"
 xmlns:simple="http://yoan.dosimple.ch/beta/simple.rdfs#"
 xml:base="http://yoan.dosimple.ch/beta/simple.rdf#">

 <simple:Teacher rdf:ID="professor">
  <simple:name>Professor</simple:name>
 </simple:Teacher>
 
 <simple:Course rdf:ID="rdf">
  <simple:name>RDF and
   RDF Schema</simple:name>
  <simple:teacher rdf:resource="#professor" />
  <simple:students>
   <rdf:Seq>
    <rdf:li rdf:resource="#yoan" />
    <rdf:li rdf:resource="#batiste" />
   </rdf:Seq>
  </simple:students>
 </simple:Course>
 
 <simple:Student rdf:ID="yoan">
  <simple:name>Yoan Blanc</simple:name>
  <foaf:weblog>http://yoan.dosimle.ch/blog/
   </foaf:weblog>
  <foaf:know rdf:resource="#batiste" />
 </simple:Student>
 
 <simple:Student rdf:ID="batiste">
  <simple:name>Batiste Bieler</simple:name>
  <foaf:weblog>http://batiste.dosimle.ch/blog/
   </foaf:weblog>
  <foaf:know rdf:resource="#yoan" />
 </simple:Student>
</rdf:RDF>

And do a Triple with it. The RDF Validator and Converter can help you.

So we can start.

$ irb

We are into the interactive ruby shell.

require 'active_rdf'

ActiveRDF is loaded

pool = ConnectionPool.add_data_source :type => :rdflite, \
 :location=> 'database.db', :keyword=>true

There is our pool, you can change to :redland if you prefer.

pool.load 'schema.nt'
pool.load 'data.nt'

Then our datas are loaded, in NTriple format, not RDF/XML.

Namespace.register :simple 'http://yoan.dosimple.ch/test/simple.rdfs#'
ObjectManager.construct_classes

Register our namespace (you’ll understand) and build the classes, like ActiveRecord do.

SIMPLE::Person.find_by_name("Professor")

Get a person.

SIMPLE::Person.find_by_name("Yoan Blanc").weblog

Yeah, we’ve got it. Of course, I helped myself with this article : “Getting Started Guide” from the ActiveRDF wiki.

Next step is to do some queries, it’s not very trivial, some I need some time to achieve this...

Pour faire contraste avec l’article d’hier où j’ai peut-être un peu survolé certains points, voici comment techniquement se lancer dans du web sémantique avec Ruby et ActiveRDF.

Merci de suivre la partie anglaise, je ne vais pas tout répéter (tout de même).

Première étape avoir les outils éléments installés : Ruby, ActiveRDF, RubyGems et SQLite ou Redland. (aïe, ça commence mal). Le chenit pour Ruby s’installe comme deux coups de cuillère-à-pot via l’outil gem.

Ensuite, prenez, un schema RDF au format N-Triple (pas le plus lisible, je vous l’accorde) et un tas de données dans le même format.

En suivant les commandes ci-contre, vous allez d’abord initialiser la base de donnée de triples et lui charger vos données. À ce moment là ActiveRDF entre en jeu et va créer automatiquement des objets Ruby qui mappent directement le modèle RDF (d’où le schema).

Enfin, il est aisément possible d’obtenir tel ou tel élément selon un critère de recherche.

Nous avons ici, les éléments basiques fournis par ActiveRDF, je tâcherai de me débattre avec les requêtes pour vous fournir prochainement un aperçu de leur possibilité. Pourvu que ça dure...

Putting Web Semantic into your Web App

Sun 10 December 2006, , , , ,

Guys who are talking about the Web 3.0 are talking about web semantic. But what is this so hoped upcoming web. Just another hype buzzword of course.

The idea of Web Semantic is to have a knowledge network you can browse, a big picture you can navigate in and discovering resources. This big picture, a graph, is achieved by added data to data, also knows as metadata. The standard way to describe resources is to use RDF. RDF isn’t a syntax. And one way to discover informations is SPARQL, a SQL-like for RDF. Let’s start with a example you can run on the Opera’s Community SPARQL querying tool:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?weblog WHERE  {
 ?hakon foaf:name "Håkon Wium Lie" .
 ?user foaf:knows ?hakon .
 ?user foaf:name ?name .
 ?user foaf:weblog ?weblog .
}

This query can be translated to : For every user who knows a guy named “Håkon Wium Lie” give me their name and weblog URL. Let’s decrypt it line after line.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

Define the foaf namespace, after this foaf:name is the same as http://xmlns.com/foaf/0.1/name.

SELECT ?name ?weblog WHERE  {

Select the variables called name and weblog.

 ?hakon foaf:name "Håkon Wium Lie" .

Define the variable hakon to be the user(s) who his name is “Håkon Wium Lie”.

 ?user foaf:knows ?hakon .

Define the variable user to be the user(s) who knows (foaf:knows) hakon.

 ?user foaf:name ?name .

Define the variable name to be the foaf:name of the user

 ?user foaf:weblog ?weblog .

Define the variable weblog to be the foaf:weblog of the user.

}

End of the WHERE statement.

Is there some prolog users, quite similar no?

Now go back to a web application, based on a kitchen-sink-included web framework. There is a powerful tool called ActiveRDF (if you know ActiveRecord, you’ll understand) that enable you to use a Triple Store backend (Redland, SQLite, SPARQL, ...) for your web app. I need to experiment it much more to explain it to you soon.

Watch this presentation to dive a little more into this.

Le web 3.0 est déjà dans certaines bouches, beaucoup espère voir arrivé le tant espéré Web Sémantique. Un buzzword en plus pour briller en société.

L’idée du Web Sémantique est d’avoir un réseau de connaissances que l’on peut naviguer pour en extraire de l’information. Pour ce faire, il faut ajouter des données sur des données, des métadonnées. Ces métadonnées s’appliquent à une ressource (identifiée par son URL) et se composent d’une clé, le titre de la métadonnée (prédicat) et d’une valeur qui peut être un élément littéral ou une autre ressource. Le résultat de ça est un graphe où les éléments sont décris et liés entre eux. Ce type de graphe peut-être retranscrit de manière à ce qu’une machine (un ordinateur) puisse en faire le traitement, le format choisit est RDF, qui peut s’écrire avec de multiple syntaxe. RDF/XML étant la plus courante sur le net. L’outil d’extraction d’information se nomme SPARQL, un langage de requête proche de SQL appliqué aux graphes.

Ci-contre, un exemple à essayer sur le site de la communauté d’Opera. RDF semble parfait pour l’idée du communautarisme où ce qui fait la force d’une communauté sont les liens entre les gens, les ressources. Le coeur de LinkedIn est un magnifique graphe je n’en doute pas, les relations sont hélas un peu pauvres à mon goût dans son état actuel.

Ensuite intégrer ceci dans son application web, n’est pas chose aisée même si au jour d’aujourd’hui, des outils existent. ActiveRDF (pour ceux qui connaissent ActiveRecord) permet d’avoir un backend RDF pour son site Ruby On Rails où une quelconque application Ruby (ActiveRecord n’étant pas lié à Rails). C’est un peu tricky mais ça fonctionne. Je vais tâcher de continuer mon exploration de la question afin de tenter de vous présenter une petit application Web faisant un usage intensif de RDF.

Approfondissez votre point de vue sur ce qu’il est possible de faire avec SPARQL avec cette présentation des auteurs de ActiveRDF.

Think simple for your web app

Tue 05 December 2006, , ,

Dailymotion, the French “YouTube” is, maybe a great tool but there is one point that they missed, regarding his great brother, YouTube, and his mother-in-law Google Video. Their REST structure. For a little website that loves to publish music, videos about bands, I’ve adapted a little script from del.icio.us to automatically replace a link to a mp3 to the Flash Player and, after that, the same idea was applied for the link to YouTube and Google Video.

Dailymotion hasn’t the cool URI I need to do this. Because you cannot do the match between the url of a page and the url of the Flash Player, so sad.

The lesson of this is, I think, always imagine what kind of application a crazy can do with your application and encourage this. If your application is cool, has a great API that is simple, simple.and simple, a crazy guy will code a Ruby library for it, a Firefox extension, a Wordpress plugin and many more. Keep is stupid simple is, today, a great point.

Offering an API could be seen has a opened hole to abuse. It’s an opened door, the ONLY one, and it's your work to lock this door to the people you cannot trust.

Aujourd’hui, une petit complainte vis-à-vis de Dailymotion, le petit frère français de YouTube. Face à son grand frère et à la mère adoptive de ce dernier, Google Video, le petit français a, à mon avis, raté un point : leurs URI.

Pour un site qui aime communiquer à ses visiteurs des sons et, depuis peu, des vidéos de leurs évènements futurs, j’ai adapté un script de del.icio.us qui remplace un lien sur un fichier mp3 par le lecteur Flash correspondant. Ce script JavaScript remplace également les liens sur YouTube et Google Video par leur player. Malheureusement pour tout le monde, les adresses de DailyMotion d’une page ne permettent pas de déduire l’adresse de l’animation Flash (fichier .swf) donc c'est raté pour faire ça à la volée.

Voici un exemple d’un point qui peut faire le succès ou pas d’une application web. Si elle est suffisamment simple et, à la limite documentée, donc qu’elle offre des outils à ses utilisateurs, il y aura un gars, qui dans son coin, va développer une extension firefox, un plugin wordpress ou je ne sais quoi encore.

Une bonne application doit dire aux développeurs du dimanche, “Voici les outils ! Faitent des trucs cools, on va s’y intéresser, en faire la promotion, faire votre promotion.” Offrir une API n’est pas une faille de sécurité béante dans un système, c’est le seul et unique moyen d’entrée qui va être mis en place pour communiquer avec l’extérieur. Plus de crainte que quelqu’un s’amuse avec les requêtes Ajax de votre site pour semer le trouble, tous (même vous) utilisent l’API qui est testée et documentée (des mots-clefs par forcément toujours évidents).