Le service Vélib' de location de vélos à
Paris est un grand succès sur
l'Internet. D'innombrables sites le discutent et proposent des
mashups à partir des données
Vélib'. En effet, le service Vélib' a une APIREST qui permet facilement de trouver des
informations.
Les grand succès du Web sont souvent les services qui exposent une
API, permettant ainsi au reste du monde de
bâtir des services à valeur ajoutée. Vélib' a une API qui permet de
connaitre l'état des stations (combien de vélos libres ? combien
d'emplacements libres ?). On peut alors assez facilement construire
des services indiquant cet état, ou faisant des statistiques sur le
long terme, par exemple avec des outils comme
RRDtool. Voir par exemple ou . On peut aussi trouve un amusant
gadget Netvibes (qui marche aussi avec le
service personnalisé de Google) en .
Ainsi, pour récupérer l'état d'une station, il faut interroger
http://www.velib.paris.fr/service/stationdetails/paris/NNN
où NNN est le numéro de la station. Essayons avec un client REST
classique, curl :
168241
]]>
16 vélos sont donc disponibles.
Quant à
http://www.velib.paris.fr/service/carto, il
permet de récupérer la liste des stations.
Où est documentée cette API ? Eh bien justement, il semble qu'elle
ne l'est nulle part. Il faut apparemment l'extraire par
rétro-ingéniérie du code source
Javascript des pages de . Par exemple, la page
appele le script Javascript
gmaps_search_station.js qui contient :
request.open("GET", stationDetailsUrl + "/"+ this.number,
true);
et, un peu plus loin, l'explication des éléments
XML retournés :
instance.availableBikes = xmlDoc.getElementsByTagName('available')[0].firstChild.nodeValue;
instance.freeCapacity = xmlDoc.getElementsByTagName('free')[0].firstChild.nodeValue;
instance.totalCapacity = xmlDoc.getElementsByTagName('total')[0].firstChild.nodeValue;
Merci à Mathieu Arnold pour ses explications sur ce point.
Voyons maintenant un client pour accéder à ce service. Je l'écris
en C pour montrer que C ne
signifie pas forcément manipulations de bas niveau des
prises et travail XML
difficile. Pour le réseau , j'utilise l'excellente
libcurl (qui gère tous les détails,
y compris IPv6, SSL,
etc) et pour le XML la non moins excellente
libxml2. Le résultat est disponible en . Il se compile ainsi :
% gcc -Wall `curl-config --cflags` `xml2-config --cflags` -c get-station.c
% gcc -o get-station get-station.o `curl-config --libs` `xml2-config --libs`
et s'utilise ainsi (la station 15068 est située boulevard Victor près de la gare du RER) :
% ./get-station 15068
Available bikes - Free slots - Total slots at station 15068
14 4 20
(Le total ne correspond pas car un emplacement peut être en maintenance.)
Un autre programme équivalent a été développé en Haskell, en utilisant la bibliothèque
standard Network.HTTP et le paquetage HaXML pour traiter
l'XML. Ce programme prend les mêmes
arguments et affiche les mêmes résultats que le programme en C.
Si on préfère Java, j'ai noté que ce
message en parlait.
Mais, au fait, pourquoi est-il nécessaire de faire de la
rétro-ingéniérie, plutôt que de simplement lire la documentation,
comme c'est le cas avec le Vélo Star de Rennes cité plus loin ? Parce que la
Ville de Paris ne pense pas que le citoyen puisse avoir envie de créer
lui-même. Elle le voit comme un simple consommateur. Résultat, il
existe une application Vélib « officielle » sur iPhone
mais les développeurs qui voudraient essayer de faire pareil pour
d'autres plate-formes comme Android ne peuvent
pas lutter à armes égales, puisqu'ils n'ont pas accès à la
documentation. Bref, la Mairie de Paris privilégie hélas le système
fermé d'Apple. Pire, il semble que le
sous-traitant de la Mairie, JCDecaux, harcèle
activement ceux qui essaient de développer des applications
non-officielles (voir aussi ce qui est arrivé à Vélibérator).
Oublions cette triste attitude d'une mairie et de son sous-traitant (en février 2013, la Mairie de Paris a d'ailleurs annoncé un changement radical de politique dont il reste à voir s'il se concrétisera) et
voyons si on peut appliquer la même méthodologie au service Vélov de Lyon. Si on
regarde le source HTML des pages Web de , on trouve la mention du script Javascripthttp://velov.grandlyon.com/velov/zhp/js/velov.js
qui, une fois téléchargé et étudié, nous indique que l'API est très
proche de celle de Paris (ce qui n'est pas étonnant, c'est la même
société). Développons donc un client REST, cette fois en Python. Ce programme s'utilise de la même façon :
% python get-station.py 1023
Available bikes - Free slots - Total slots at station 1023 - CROIX ROUSSE / PERFETTI
7 11 20
Le service déployé à Marseille, Le vélo, est techniquement
identique à celui de Paris. On peut utiliser les mêmes programmes,
avec l'URL http://www.levelo-mpm.fr/service/stationdetails/marseille/NNNN.
Testons un dernier langage sur ce service, celui du
shellUnix. Comme le shell n'a pas de mécanisme
incorporé pour analyser le XML, nous utiliserons un script
XSLT :
Statistiques pour la station Vélos libres : Bornes libres : Nombre total de bornes : Bornes en panne :
]]>
et le script contient :
#!/bin/sh
# Recuperer des informations sur une station du service de vélos en
# libre-service Le Velo a Marseille
URL="http://www.levelo-mpm.fr/service/stationdetails/marseille"
STYLESHEET="format.xsl"
set -e
if [ "$1" = "" ]; then
echo "Usage: $0 station-number" > /dev/stderr
exit 1
fi
num=$1
output=`mktemp /tmp/levelo-$num.XXXXX`
curl --silent --output $output $URL/$num
xsltproc --stringparam num $num $STYLESHEET $output
rm -f $output
et s'utilise ainsi (sur la station la plus proche du Vieux
Port) :
% ./get-station.sh 1156
Statistiques pour la station 1156
Vélos libres : 3
Bornes libres : 4
Nombre total de bornes : 8
Bornes en panne : 1
Ce programme marcherait probablement sans problème avec le service
Vélô à
Toulouse, qui utilise encore le même logiciel
(on trouve même /marseille dans les URL de ).
D'autres systèmes de location de vélos en libre-service utilisent
apparemment une interface bien différente. Ainsi, le service
BIXI de Montréal
fonctionne en publiant un seul fichier,
https://profil.bixi.ca/data/bikeStations.xml, qui
contient à la fois l'information sur les stations et l'état actuel de
leur occupation. (Merci à Gérôme Sauve pour avoir attiré mon attention
sur ce service et à Pascal Courtois pour son analyse de
l'application avec Firebug.)
Le programme « montréalais » est
également en Python mais avec une autre bibliothèque (d'API très
semblable à ElementTree), lxml. Voici des exemples
d'utilisation :
% python bixi.py 'Cartier / des Carrières'
Cartier / des Carrières: 0 bikes, 7 empty docks
% python bixi.py 'Mozart / St-Laurent'
Mozart / St-Laurent: 4 bikes, 3 empty docks
% python bixi.py 'Holt / Fullum'
Holt / Fullum: not yet installed
Autre cas, celui du Vélo
Star de Rennes. Il faut s'enregistrer
auprès de l'entrepôt de
données de la ville et obtenir une clé. Ensuite, on lit la
documentation
de l'API (plus besoin de rétro-ingéniérie) et on peut
programmer. Il faut envoyer une requête HTTP et on récupère du XML.
Trivial à faire en Go, dans le programme en utilisant les bibliothèques standard Go http et xml :
% ./gostar 42
Station PONT DE STRASBOURG
Bikes available: 3
Slots available: 12