Comment utiliser le module starapi

Après avoir installé le module starapi vous avez besoin de deux choses :

  • Une clé d’API fournie par Keolis,
  • Faire un import du module starapi et utiliser les classes dont vous avez besoin.

La façon la plus simple pour utiliser le module est ensuite de profiter des clients d’API (l’un pour Levelo Star, et l’autre pour tout ce qui est bus et métro), qui sont décrits ci-après.

Une façon plus avancée consiste à utiliser (voire à écrire vous-même) un Handler dit de “bas niveau”, qui vous permet une meilleure granularité.

Client API

Il existe deux clients pour l’API, dit de “haut-niveau” :

Chacune des méthodes de ces clients permets de faire des requêtes en obtenant directement des objets pythons : dict, list, etc. ; n’hésitez pas à en lire la documentation pour savoir ce qui est disponible.

Shortcuts

Vous pouvez simplement obtenir un client pour ces API avec les fonctions starapi.levelostar() et starapi.networkstar() en fournissant votre clé d’API en paramètre, comme ceci :

>>> import starapi
>>> star_busmetro_client = starapi.networkstar('YOUR_API_KEY')
>>> star_velo_client = starapi.levelostar('YOUR_API_KEY')

Exemple

Prenons un cas simple, pas à pas : obtenir la liste des districts du réseau Le Vélo Star. Tout d’abord, il faut créer un client pour l’API :

>>> import starapi
>>> client = starapi.levelostar('YOUR_KEOLIS_KEY_HERE')

Ensuite, obtenir la liste des districts. Cette ligne fait appel HTTP “GET” pour obtenir le résultat :

>>> districts = client.get_districts()

Enfin, districts est une liste (comme l’indique la documentation de starapi.LeveloStar.get_districts()) qui se dévoile comme toute les listes : avec une boucle for :

>>> for district in districts:
...     print('[%s] %s' % (district.get('id'), district.get('name')))
...
[34] Sud-Gare
[35] Francisco Ferrer-Vern-Poterie
[36] Jeanne d'Arc-Longs Champs-Atalante
[37] Bréquigny
[38] Le Blosne
[39] Villejean-Beauregard
[40] St Martin
[41] Maurepas - Patton
[42] Bourg l'Evêque-La Touche-Moulin du Comte
[43] Thabor - St Hélier
[44] Cleunay-Arsenal-Redon
[45] Centre-Ville

Maintenant que vous avez cette liste de “quartier” utilisé par Levelostar, vous pourriez rechercher la liste des stations de l’un de ces quartiers.

Voici donc les stations du quartier “Sud-Gare” :

>>> bike_stations = client.get_stations_in_district('Sud-Gare')
>>> for bike_station in bike_stations:
...     print('%s (%s)' % (bike_station.get('name'), bike_station.get('number')))
STE THERESE (71)
MERMOZ (70)
JACQUES CARTIER (61)
GARES (SUD) (45)
CLEMENCEAU (62)
BINQUENAIS (67)

La couche basse : handler et python

Si vous préférez maîtriser plus finement le traitement des réponses, vous avez accès à un “handler” de bas niveau muni de vôtre clé d’API, vous pouvez instancier un Handler qui formatera les requêtes pour vous - et qui ne fera que ça d’ailleurs.

Lorsque vous appelez une fonction du Handler, les paramètres sont vérifiés, puis une url est construite avec les paramètres formatés comme il faut. Enfin, un appel HTTP est effectué, et le résultat est directement retourné comme réponse à l’appel de la fonction.

Comme le module requests est utilisé, c’est donc un objet Response de ce même module qui est retourné à chaque appel.

Format de réponse

Le format de réponse des handlers est un objet Response du module requests. Le contenu de l’attribut text est alors le résultat de la requête.

Dans le cas du Handler de base, il s’agit d’une réponse formatée en XML, qui peut être interprétée (par exemple) avec lxml :

>>> r = api.getlines()
>>> root = root.fromstring(r.text.encode('utf-8'))
>>> root.xpath('/opendata/answer/status')
[<Element status at 0x1ed2eb0>]
>>> status = root.xpath('/opendata/answer/status')[0]
>>> status.get('code')
'0'
>>> status.get('message')
'OK'

Remarque importante : la valeur de l’attribut text est une chaîne de caractère unicode. Comme lxml.etree attend une chaîne encodée lorsque le XML contient une entête, pensez à encoder d’abords le résultat en utf-8.

Structure du XML de réponse

La structure de la réponse XML est toujours la même lorsque la requête a aboutie correctement :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<opendata>
    <request><!-- REQUEST URL --></request>
    <answer>
        <status code="0" message="OK"/>
        <data>
            <!-- DATA RESPONSE -->
        </data>
    </answer>
</opendata>

La balise request contient l’url de la requête appelée, avec tous ses paramètres.

La balise data contient le contenu XML de la réponse, en tant que noeud normal du document XML (ce n’est donc pas du CDATA à interprété, mais bien une suite de noeud XML valide).

En cas d’erreur, l’élément /opendata/answer/data n’existe pas, et un code d’erreur est présent dans la balise status.

Status code

Les codes de retour de l’API les plus fréquents sont les suivants :

Code Message Signification
0 OK Tout va bien.
3 The requested command could not be found. Please check spelling. Commande introuvable : probablement un bug du client à signaler.
103 A required parameter is not filled. Please, check parameters. Paramètre non fourni, le bug est de vôtre côté !