Objectif
Ce tutoriel décrit, étape par étape, le fonctionnement du script kameleoon_to_confluence.py. À partir d’un ID d’expérience Kameleoon, d’un site Confluence et d’un ID d’espace Confluence, le script récupère les métadonnées de l’expérience et ses résultats statistiques, identifie la variation gagnante, et upserte une ligne pour cette expérience dans un tableau sur une page Confluence. Réexécuter le script pour la même expérience met à jour sa ligne existante au lieu d’en créer un doublon. Les étapes 1–5 réutilisent le même flux de requête et d’interrogation que le tutoriel d’export vers Airtable. Seule la destination change.Alternative : exporter avec un assistant IA au lieu du script
L’exécution du script nécessite un environnement Python, quatre identifiants stockés, et une réexécution manuelle pour chaque expérience à exporter. Si vous utilisez déjà un assistant IA compatible MCP tel que Claude, vous pouvez effectuer le même export depuis une conversation, en le connectant aux serveurs MCP (Model Context Protocol) distants de Kameleoon et d’Atlassian, soit via un outil de codage, soit directement dans l’application Claude. Suivez notre guide pour exporter les résultats à l’aide de Claude.Prérequis
-
Identifiants API Kameleoon. L’Automation API nécessite un access token. Le script en obtient un de manière programmatique à partir d’un
client_idet d’unclient_secretgrâce au grantclient_credentials. Consultez Obtenir un access token. - Un token API Confluence, associé à l’adresse e-mail du compte auquel il appartient. Créez un token sur id.atlassian.com/manage-profile/security/api-tokens. Le script envoie les deux en authentification HTTP Basic à chaque requête Confluence.
- L’ID numérique d’espace Confluence pour l’espace qui héberge la page. Contrairement à un ID de base de données Notion ou un ID de base Airtable, l’ID numérique d’un espace n’apparaît pas dans son URL (cette URL montre la clé d’espace à la place), et n’apparaît nulle part dans l’interface web Confluence non plus. Demandez à un assistant IA connecté via MCP de le rechercher pour vous, ou récupérez-le vous-même via l’endpoint REST de Confluence Get spaces.
-
Python 3.9+ avec la bibliothèque
requests(pip install requests).
188308), avec deux variations en plus de l’originale : variation 828220 et variation 828221.
1. S’authentifier auprès de l’Automation API
Endpoint : obtenez un access token en envoyant une requête POST à l’endpoint de token.
Exemple :
access_token retourné en tant que token Bearer pour chaque requête suivante à l’Automation API. Les access tokens restent valides 2 heures par défaut.
2. Récupérer l’expérience
Endpoint : récupérez les métadonnées de l’expérience en envoyant une requête GET à l’endpoint Get an experiment.
Exemple :
name, status, dateStarted, dateEnded, et description pour la ligne Confluence, et mainGoalId pour limiter la requête de résultats à l’étape suivante.
L’API retourne
mainGoalId par défaut ; vous n’avez donc pas besoin d’un paramètre optionalFields pour le lire. L’Automation API ne publie pas d’énumération fixe pour le champ status, mais les autres champs de type statut de l’API utilisent systématiquement des tokens en majuscules (par exemple, STOPPED, ACTIVE, DRAFT). L’étape 6 mappe le champ status sur cette hypothèse. Confirmez les tokens exacts que votre compte retourne avec une requête réelle avant de vous fier à ce mapping.3. Demander les résultats de l’expérience
Endpoint : déclenchez la génération du rapport de résultats en envoyant une requête POST à l’endpoint Request experiment’s results.
Exemple :
dataCode, que l’étape 4 utilise pour interroger le résultat.
Ce script nécessite
bayesian: true et définit sequentialTesting: false. bayesian et sequentialTesting sont des méthodes alternatives de calcul de la significativité, et ce tutoriel rapporte la probabilité de succès bayésienne. Avec Bayesian activé, la valeur reliability du rapport porte la probabilité de succès bayésienne (la probabilité qu’une variation batte la référence), que le script mappe sur la colonne Probability. Confirmez cette valeur par rapport au même rapport dans l’application Kameleoon si votre compte utilise une méthode statistique par défaut différente.4. Interroger les résultats
Endpoint : récupérez le rapport en envoyant des requêtes GET à l’endpoint Poll results jusqu’à ce qu’il soit prêt.
Le
status de la réponse est WAITING pendant que Kameleoon calcule le rapport, READY quand les données sont disponibles, ou ERROR / TIMEOUT en cas d’échec. Quand le statut est ERROR ou TIMEOUT, la réponse inclut un errorDescription de premier niveau. Le script interroge à intervalle fixe jusqu’à ce que le statut soit READY.
Exemple :
5. Sélectionner la variation la plus performante
Les résultats contiennent une entrée par variation sousvariationData, ainsi que la ligne _reference pour la page originale. Pour chaque variation, les métriques de l’objectif demandé se trouvent sous breakdownData._reference.generalData.goalsData[goalId].
Le script ignore l’entrée _reference, lit l’improvementRate et la reliability (la probabilité de succès bayésienne) de chaque variation, et sélectionne comme meilleure performance la variation ayant le taux d’amélioration le plus élevé. La colonne Result mappée à l’étape suivante indique si cette variation a réellement gagné : si elle a atteint une probabilité de succès suffisamment élevée avec un uplift positif.
Exemple :
828220 affiche une amélioration de +211,48 % contre -43,33 % pour la variation 828221. La variation 828220 a donc le taux d’amélioration le plus élevé et, avec une probabilité supérieure à 95 % et un uplift positif, est la véritable gagnante.
6. Mapper les données aux colonnes Confluence
Le script transforme les métadonnées de l’expérience et les métriques de la variation la plus performante en une ligne pour le tableau Confluence, utilisant les mêmes huit colonnes que les exports Notion et Airtable.
Exemple :
L’Automation API ne publie pas d’énumération fixe pour le champ
status de l’expérience, et les tokens peuvent évoluer. map_status effectue une correspondance sans distinction de casse et retourne None pour un statut non reconnu, ce qui laisse la cellule Status vide au lieu d’écrire une valeur incorrecte. Confirmez les tokens que votre compte retourne avec un simple GET /experiments/{experimentId} et étendez STATUS_MAP si nécessaire.7. Analyser le tableau Experiments existant
Confluence n’a pas d’objet base de données ou tableau propre. Au lieu de cela, le script maintient une page dédiée avec un seul tableau HTML, une ligne par expérience, et traite la colonne Experiment Name de la même manière que Notion traite une propriété title ou Airtable traite un champ de fusion : comme la clé sur laquelle il upsertez. Le script construit ce tableau avec une dispositionfull-width plutôt que la disposition par défaut plus étroite de Confluence, puisque huit colonnes d’en-têtes modérément longs s’enroulent au milieu du mot à la largeur de page par défaut.
Le format de stockage de Confluence (le balisage de type HTML dans lequel le corps d’une page est stocké) enveloppe le texte de chaque cellule dans une balise <p>, et l’en-tête d’une page nouvellement créée est du simple <tr><th>...</th></tr> sans <thead> environnant. L’analyseur ci-dessous, construit sur la classe standard html.parser.HTMLParser de Python, traite à la fois le cas d’en-tête nu et le cas <thead>-enveloppé, et traite une cellule vide de la même manière que Confluence la rend, soit comme un <p></p> vide soit comme un <p /> auto-fermant. Il s’arrête aussi au premier </table>, donc un second tableau ailleurs sur la page (un que vous avez ajouté à la main, par exemple) ne fusionne jamais dans le résultat analysé, et ferme toute ligne ou cellule qu’une édition malformée a laissée ouverte, qu’la balise suivante ouvre une nouvelle ligne ou que le tableau lui-même se termine, donc une balise non fermée égarée ne peut pas silencieusement supprimer une ligne.
Exemple :
reorder_row se protège contre un tableau dont les colonnes ont été manuellement réorganisées dans Confluence, par exemple par une personne faisant glisser une colonne dans l’éditeur. Sans cela, une recherche par position comparer le Experiment Name de la nouvelle ligne contre quelle que colonne siège maintenant à cette position sur le tableau existant, correspondant silencieusement à la mauvaise ligne ou à aucune. Il réaligne seulement une véritable réorganisation, où l’en-tête a toujours les mêmes huit libellés dans un ordre différent. Si le texte d’une cellule d’en-tête a lui-même été modifié, par exemple en retitrant Notes en Comments, les libellés ne correspondent plus du tout à HEADER, donc la fonction remonte à l’ordre de colonnes existant et imprime un avertissement plutôt que de deviner, plutôt que de silencieusement effacer les données de cette colonne sur chaque ligne.8. Trouver, créer ou mettre à jour la page Confluence
Trouver : cherchez la page par titre dans l’espace en utilisant les paramètres de requêtetitle et space-id sur l’endpoint Get pages. Passer body-format=storage retourne le contenu actuel du tableau dans le même appel.
Confluence n’a pas d’endpoint de mise à jour par ligne ou par champ. Mettre à jour une page remplace son corps entier, donc le script lit toujours le tableau actuel, upsertez une ligne en mémoire, et réécrit le tableau entier. Cette remise en place entière du corps diffère de l’export Airtable, qui patchs un seul enregistrement, et de l’export Notion, qui patchs les propriétés d’une seule page.
Contrairement aux API Notion et Airtable, Confluence exige que l’appelant incrémente
version.number à chaque mise à jour, au numéro de version actuel plus un. Envoyer le numéro actuel à nouveau, ou omettre version, cause l’échec de la requête. Un assistant IA connecté via MCP utilisant les outils d’Atlassian gère cela automatiquement ; un appel REST direct, comme dans ce script, ne le fait pas.9. Exécuter le script
Transmettez l’ID de l’expérience, le site Confluence et l’ID d’espace en arguments :--page-title pour cibler une page nommée autrement que le défaut Experiments.
Script complet
Le script complet ci-dessous correspond fonction par fonction à kameleoon_to_confluence.py. Copiez-le directement, ou téléchargez le fichier depuis ce lien.Notes de personnalisation
- Le mapping de statut se trouve dans la constante
STATUS_MAP, indexée sur les tokens de statut en majuscules retournés par l’API. Ajustez les valeurs cibles si vos colonnes Status diffèrent deRunning/Implementing/Completed/Defunct, et confirmez les tokens que votre compte retourne avec une requêteGET /experiments/{experimentId}réelle avant de vous fier au mapping. - Probability provient de la probabilité de succès bayésienne mesurée, ce qui nécessite
bayesian: truesur la requête de résultats. Si vous voulez une estimation pré-expérience à la place, supprimez la ligneProbabilitydebuild_row. - La sélection de l’objectif utilise le
mainGoalIdde l’expérience. Pour établir un rapport sur un objectif différent, transmettez son ID àrequest_resultset àpick_best_variation. - Clé d’upsert. La correspondance sur Experiment Name est exacte, donc des différences de casse ou d’espacement créent une nouvelle ligne au lieu de mettre à jour celle existante. Gardez des noms d’expérience uniques sur la page. Le flux recherche-puis-écriture n’est pas atomique, donc évitez d’exécuter deux exports pour la même expérience simultanément, et évitez de renommer une expérience entre les exécutions sauf si vous voulez aussi une nouvelle ligne pour cela.
- Mises à jour de page entière. Chaque mise à jour réécrit le tableau entier, puisque Confluence n’a pas de mise à jour par ligne. Si vous maintenez la page à la main entre les exécutions du script, gardez vos modifications à l’intérieur du tableau que le script construit. Le script ne préserve pas actuellement le contenu en dehors de ce tableau.
- Conflits de version. Le script lit toujours le numéro de version actuel de la page immédiatement avant l’écriture, donc une édition manuelle effectuée entre la lecture et l’écriture cause l’échec du
PUTsuivant avec un conflit de version. Réexécutez le script si cela se produit. - Limites de débit. L’Automation API autorise jusqu’à 50 requêtes par 10 secondes et 1 000 par heure, mais Kameleoon recommande de rester sous 12 appels par minute par compte. Confluence Cloud applique ses propres limites de débit, qui varient selon le plan ; consultez la documentation des limites de débit d’Atlassian pour les valeurs actuelles. Si vous traitez de nombreuses expériences par lot, mettez les tokens en cache, limitez le débit des requêtes, et envisagez la Data API pour les besoins à fort volume.