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 :
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 :
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 :
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
Aucun commentaire pour le moment.