Configurer un traitement Import depuis une API JSON

Le plugin Import depuis une API JSON interroge une API HTTP qui répond en JSON, et transforme le résultat en un jeu de données de la plateforme. Ce cours le configure pour récupérer l'agenda public OpenAgenda de Bordeaux Métropole : une source protégée par une clé, et dont la réponse impose de naviguer dans des champs imbriqués — deux mécaniques à comprendre avant de remplir le formulaire.

💡 Ce cours ne décrit que ce qui est propre à ce plugin. Pour la mécanique commune à tous les traitements — créer un traitement, choisir l'action, planifier, suivre les exécutions, gérer les permissions et les notifications — consultez le cours Programmer des mises à jour automatiques de données.

1. Explorer l'API source

1.1 Obtenir une clé OpenAgenda

L'API OpenAgenda nécessite une clé : sans elle, chaque appel échoue avec une erreur 403. Créez un compte sur openagenda.com, puis ouvrez Paramètres → Clés API pour la récupérer. Elle s'utilise en l'ajoutant à l'en-tête HTTP key de chaque requête — c'est justement ce que permet la méthode d'authentification API key du traitement, configurée plus bas.

Chaque agenda a son propre identifiant dans l'URL — ici bordeaux-metropole : remplacez-le par le vôtre pour interroger un autre agenda OpenAgenda.

1.2 Repérer la structure de la réponse

Tout le paramétrage du plugin consiste à décrire des chemins dans la réponse JSON. Il faut donc commencer par la regarder. Un appel à l'API renvoie un objet englobant : le nombre total de résultats, puis le tableau des évènements sous la clé events [1] — c'est ce chemin qu'il faudra indiquer comme chemin des résultats.

Chaque évènement mélange trois formes de données, et c'est cette diversité qui rend l'exemple intéressant :

  • des objets imbriqués — le titre n'est pas une chaîne mais un objet par langue [2] (OpenAgenda est multilingue), et le lieu regroupe nom, ville et coordonnées sous location [4] ;
  • un tableau de chaînes — les mots-clés [3], sous keywords.fr ;
  • des tableaux d'objets — les liens [5], et surtout les séances [6] : un même évènement peut se tenir plusieurs jours, chaque créneau ayant son début et sa fin sous timings.
Extrait de la réponse JSON de l'API OpenAgenda
Extrait réel de la réponse, réduit aux champs utilisés dans ce cours.

Les champs keywords, links et timings ne sont renvoyés que si la requête porte le paramètre detailed=1 — d'où sa présence dans l'URL configurée ci-dessous.

2. Configurer le traitement

La configuration propre au plugin se répartit sur deux onglets : Source des données (où aller chercher le JSON) et Champs à récupérer (comment le transformer en colonnes).

2.1 Source des données

Renseignez l'URL de l'API [1] : https://api.openagenda.com/v2/agendas/bordeaux-metropole/events?detailed=1. Elle ne contient aucun secret, elle reste donc lisible et partageable.

Choisissez ensuite la méthode d'authentification [2] : API key. Deux champs apparaissent : la Clé [3], le nom de l'en-tête HTTP attendu par la source (key pour OpenAgenda), et la Valeur [4], la clé elle-même — un champ de type mot de passe, jamais affiché en clair. Cela permet de documenter et de partager la configuration sans jamais exposer le secret.

Onglet Source des données du traitement
URL, authentification par clé d'API et pagination.

Reste la pagination [5]. La plupart des API ne renvoient qu'une page de résultats à la fois : sans pagination, le traitement n'importera que cette première page. Le plugin propose trois méthodes.

Les trois méthodes de pagination
La liste déroulante Pagination, dépliée.

[1] Pas de pagination. Un seul appel, une seule page. C'est le bon choix quand la source renvoie tout d'un coup (petit fichier JSON, API de configuration), ou pour un premier essai — c'est ce que fait ce cours, qui se contente des 20 évènements de la page par défaut.

[2] Extraire l'URL de la page suivante depuis la donnée. Pour les API qui renvoient elles-mêmes le lien de la page suivante dans leur réponse — le style HAL / JSON:API, très répandu. Indiquez le chemin vers la page suivante dans le JSON (par exemple next) ; le traitement suit ce lien de proche en proche jusqu'à ce qu'il soit absent. Les champs nom du paramètre de type limit et nombre d'éléments par page (1000 par défaut) permettent en plus de demander de grandes pages, pour limiter le nombre d'appels.

[3] Paramètres dans l'URL. Pour les API qui ne fournissent aucun lien mais acceptent un couple de paramètres de décalage et de taille — le cas le plus courant, et celui d'OpenAgenda (from et size). Renseignez le nom du paramètre de type offset (offset par défaut, souvent from ou skip) et le nom du paramètre de type limit (size, limit, take…). Par défaut, le décalage est incrémenté du nombre de lignes déjà lues ; si votre API compte en numéros de page et non en nombre d'éléments, cochez Offset en nombre de pages, qui l'incrémente de 1 à chaque appel.

En résumé : la réponse contient un lien vers la suite → méthode [2] ; il faut fabriquer soi-même l'URL de la page suivante → méthode [3] ; tout tient en un appel → méthode [1]. En cas de doute, essayez la source dans un navigateur et regardez ce que contient la réponse.

2.2 Champs à récupérer

Le second onglet décrit la transformation du JSON en tableau. Le chemin des résultats [1] indique où se trouve, dans la réponse, le tableau à parcourir : events, comme repéré plus haut. Une ligne du jeu de données sera produite par élément de ce tableau. Si l'API renvoyait directement un tableau à la racine, ce champ resterait vide.

Chaque entrée de la liste Champs à récupérer associe ensuite un identifiant de colonne — le nom qu'aura la colonne dans le jeu de données — à un chemin de la colonne, évalué dans l'objet de chaque évènement :

Colonne Chemin Ce que ça lit
titre title.fr une propriété imbriquée [2]
lieu location.name idem
ville location.city idem
latitude location.latitude idem
longitude location.longitude idem
mots_cles keywords.fr un tableau de chaînes [3]
liens links[].link une propriété dans un tableau d'objets [4]
Onglet Champs à récupérer
Chemin des résultats et liste des colonnes à extraire.

2.3 Écrire un chemin

Deux notations seulement, mais il faut les distinguer.

Le point descend dans les objets. location.city lit la propriété city de l'objet location. Le .fr de title.fr n'est pas décoratif : sans lui, le traitement chercherait une valeur directement sous title, où il n'y a qu'un objet par langue, et la colonne resterait vide.

Les crochets traversent un tableau d'objets. links[].link signifie : pour chaque élément du tableau links, prends sa propriété link. Les valeurs obtenues ne créent pas de lignes supplémentaires : elles sont concaténées dans une seule cellule.

C'est là qu'intervient le champ Séparateur pour les tableaux, en bas de l'onglet (; par défaut) : c'est le caractère qui joint ces valeurs multiples. Il n'a de sens que pour les chemins qui ramènent plusieurs valeurs — ceux qui utilisent [], et ceux qui pointent directement un tableau de chaînes. Choisissez un caractère qui n'apparaît pas dans les données elles-mêmes.

Deux pièges, vérifiés à l'exécution :

  • un tableau de chaînes se lit sans crochets. Pour les mots-clés, le chemin est keywords.fr, pas keywords.fr[] — le tableau est déjà la valeur finale, il n'y a rien à traverser. Avec les crochets, la colonne ressort vide ;
  • les crochets ne se posent que sur un vrai tableau. Écrire keywords[].fr alors que keywords est un objet fait échouer l'exécution.

En cas de doute, comparez le chemin à la réponse JSON de la section 1.2 : [] se place exactement là où vous voyez un [ suivi de { dans le JSON.

2.4 Données en profondeur d'un tableau

La concaténation convient aux mots-clés ou aux liens, mais pas aux séances : un évènement qui se tient les 9 et 10 juillet devrait produire deux lignes, chacune avec sa date, pour être exploitable dans un calendrier ou une recherche par date. C'est le rôle de la carte Données en profondeur d'un tableau, en bas de l'onglet.

Elle prend un chemin [1] vers un tableau imbriqué — ici timings — puis rouvre, à l'intérieur, une liste de champs à récupérer [2] dont les chemins sont évalués relativement à chaque élément de ce tableau : begin et end, et non timings.begin.

La carte Données en profondeur d'un tableau
Chemin du tableau imbriqué, colonnes relatives, récursivité et séparateur.

Ce que cela produit, mesuré sur une exécution réelle : le traitement émet une ligne par élément du tableau imbriqué, et non une ligne par élément du tableau de résultats. Les colonnes du niveau parent (titre, lieu, ville, mots-clés…) sont recopiées à l'identique sur chacune de ces lignes, et les colonnes du bloc imbriqué s'ajoutent à côté. Le résultat reste un seul tableau plat : 20 évènements totalisant 28 séances ont donné 28 lignes et 9 colonnes. Un évènement sans séance ni tableau timings produit malgré tout sa ligne, colonnes imbriquées vides.

La carte est récursive [3] : à l'intérieur d'un bloc imbriqué, un nouveau bloc Données en profondeur d'un tableau est proposé, sans limite de profondeur. On peut ainsi aplatir un JSON à plusieurs niveaux de tableaux — en gardant en tête que le nombre de lignes se multiplie à chaque niveau.

⚠️ Choisissez donc bien le tableau à déplier : le dépliage définit la granularité d'une ligne du jeu de données. Ici, une ligne n'est plus un évènement mais une séance d'évènement — ce que reflète le titre donné au jeu produit. Si vous vouliez au contraire un enregistrement par évènement, laissez la carte vide et lisez la première date via un chemin simple (firstTiming.begin).

3. Résultat

L'exécution produit un jeu de données de 28 enregistrements [1] et 9 colonnes [2] à partir des 20 évènements de la page. Les deux petites icônes devant mots_cles et liens signalent des colonnes multivaluées : déclarez le séparateur sur ces colonnes dans l'onglet Schéma pour que la plateforme les traite comme des listes plutôt que comme du texte.

Le jeu de données produit
28 enregistrements, 9 colonnes.

Dans les données, l'effet du dépliage est visible directement : Tour de France [1] et Le Belem fait escale à Bordeaux [2] occupent chacun deux lignes, identiques sauf pour debut et fin. Les mots-clés [3] s'affichent en valeurs distinctes grâce au séparateur.

Une ligne par séance dans le jeu produit
Les évènements à plusieurs séances occupent plusieurs lignes.

Si la plateforme ne reconnaît pas automatiquement les colonnes latitude et longitude comme des coordonnées géographiques, associez-les au concept correspondant depuis l'onglet Schéma du jeu de données : l'onglet Carte affiche alors chaque évènement à sa position.

Carte des évènements
Les évènements de l'agenda, positionnés sur la métropole bordelaise.

Si vous avez des remarques sur ce cours, n'hésitez pas à nous les communiquer.