Retour à l'accueil

Bot Redash dans Mattermost : automatisation des graphiques

Script automatise l'envoi de graphiques depuis Redash vers Mattermost : récupère les données via API, crée des visualisations en matplotlib avec annotations, combine en tableau de bord avec PIL et publie dans le canal. Inclut des vérifications de fraîcheur des données et protection contre les doublons. Adapté aux rapports BI quotidiens d'équipe.

Automatisez Redash : graphiques dans Mattermost quotidiennement
Advertisement 728x90

Automatisation des tableaux de bord Redash : Envoi de graphiques vers Mattermost

Un script Python résout la tâche de diffusion automatique de graphiques de Redash vers Mattermost. Il récupère les données via l'API, recrée les visualisations avec matplotlib, les combine en un tableau de bord unique et l'envoie dans un canal. Idéal pour les équipes où les données sont mises à jour avec un délai et où la consultation manuelle des tableaux de bord est inefficace.

Le pipeline s'exécute via une tâche cron : il vérifie la fraîcheur des données, construit des graphiques avec annotations et publie le rapport final avant le début de la journée de travail.

Récupération des données depuis l'API Redash

Redash fournit une API pour exécuter des requêtes par query_id avec paramètres. La fonction principale :

Google AdInline article slot
import requests

BASE_URL = 'https://votre-instance-redash'
HEADERS = {'Authorization': 'Key VOTRE_CLE_API'}

def fetch_query(query_id, params):
    response = requests.post(
        f'{BASE_URL}/api/queries/{query_id}/results',
        headers=HEADERS,
        json={'parameters': params, 'max_age': 0},
    )
    return response.json()

Si le résultat n'est pas prêt, l'API retourne un job — implémentez un polling pour attendre la fin. Pour les tableaux de bord, analysez les paramètres de l'URL :

from urllib.parse import parse_qs, urlparse

def parse_dashboard_url(url):
    parsed = urlparse(url)
    params = parse_qs(parsed.query)
    return {
        key: value[0]
        for key, value in params.items()
    }

Convertissez les dates dynamiques comme '7 derniers jours' manuellement :

from datetime import datetime, timedelta

def last_7_days():
    today = datetime.utcnow()
    return {
        'start': (today - timedelta(days=7)).strftime('%Y-%m-%d'),
        'end': today.strftime('%Y-%m-%d')
    }

Construction et annotation des graphiques

Les visualisations sont construites avec matplotlib, en imitant les styles Redash : couleurs, types de lignes, tailles. Un exemple de graphique linéaire basique :

Google AdInline article slot
import matplotlib.pyplot as plt

def build_chart(df):
    fig, ax = plt.subplots(figsize=(6, 4))

    ax.plot(df['date'], df['value'], linewidth=2)
    ax.plot(df['date'], df['plan'], linewidth=2)

    ax.set_title('Dynamique de la métrique')

    return fig

L'étape clé est l'annotation pour la lisibilité dans les images statiques. Ajoutez la dernière valeur, la variation hebdomadaire, l'écart par rapport au plan :

ax.annotate(
    f"valeur : {last_value}",
    xy=(last_date, last_value),
    xytext=(10, 10),
    textcoords='offset points'
)

Cela permet de comprendre les métriques sans interactivité.

Combinaison des graphiques en un tableau de bord

Plusieurs graphiques (par métriques, catégories) sont fusionnés en une seule image avec PIL pour une meilleure expérience utilisateur :

Google AdInline article slot
from PIL import Image

def merge_images(images, output_path):
    base = Image.new('RGB', (1200, 800), 'white')

    for img, pos in images:
        base.paste(img, pos)

    base.save(output_path)

Ajoutez des en-têtes de section par département ou thème pour la navigation.

Vérifications et protection contre les doublons

Le script vérifie la date cible dans les données :

if df['date'].max() != target_date:
    raise Exception('Données pas encore mises à jour')

Protection contre les envois en double via un fichier d'état :

from pathlib import Path

STATE_FILE = Path('last_sent.txt')

def was_sent(date):
    return STATE_FILE.exists() and STATE_FILE.read_text() == str(date)

Envoi vers Mattermost

Utilisez mattermostdriver pour télécharger le fichier et publier :

from mattermostdriver import Driver

mm = Driver({
    'url': 'votre-mattermost',
    'token': 'TOKEN_BOT',
})

mm.login()

mm.posts.create_post({
    'channel_id': channel_id,
    'message': 'Rapport prêt',
    'file_ids': [file_id],
})

Points clés

  • L'automatisation réduit l'effort manuel : les graphiques arrivent dans le messager automatiquement après les mises à jour des données.
  • Les annotations sur les graphiques assurent une information complète sans interactions de survol.
  • La combinaison en un seul tableau de bord améliore l'UX dans le chat.
  • Les vérifications de fraîcheur et de doublons garantissent la fiabilité du pipeline.
  • Facile à étendre : ajoutez de nouveaux query_id et paramètres.

— Editorial Team

Advertisement 728x90

Lire ensuite