Automatización de Dashboards de Redash: Enviando Gráficos a Mattermost
Un script de Python resuelve la tarea de entregar automáticamente gráficos desde Redash a Mattermost. Obtiene datos mediante API, recrea visualizaciones en matplotlib, las combina en un solo dashboard y lo envía a un canal. Ideal para equipos donde los datos se actualizan con retraso y la revisión manual de dashboards es ineficiente.
El pipeline se ejecuta en un cron job: verifica la actualidad de los datos, construye gráficos con anotaciones y publica el informe final antes de que comience la jornada laboral.
Obtención de Datos desde la API de Redash
Redash proporciona una API para ejecutar consultas por query_id con parámetros. La función principal:
import requests
BASE_URL = 'https://tu-instancia-redash'
HEADERS = {'Authorization': 'Key TU_CLAVE_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 el resultado no está listo, la API devuelve un job — implementa polling para esperar a su finalización. Para dashboards, analiza los parámetros de la 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()
}
Convierte fechas dinámicas como 'últimos 7 días' manualmente:
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')
}
Construcción y Anotación de Gráficos
Las visualizaciones se construyen en matplotlib, imitando los estilos de Redash: colores, tipos de línea, tamaños. Un ejemplo básico de gráfico de líneas:
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('Dinámica de la métrica')
return fig
El paso clave son las anotaciones para legibilidad en imágenes estáticas. Añade el último valor, el cambio semanal, la desviación del plan:
ax.annotate(
f"valor: {last_value}",
xy=(last_date, last_value),
xytext=(10, 10),
textcoords='offset points'
)
Esto permite que las métricas se entiendan sin interactividad.
Combinación de Gráficos en un Dashboard
Múltiples gráficos (por métricas, categorías) se fusionan en una imagen usando PIL para una mejor experiencia de usuario:
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)
Añade encabezados de sección por departamento o tema para facilitar la navegación.
Verificaciones y Protección contra Duplicados
El script verifica la fecha objetivo en los datos:
if df['date'].max() != target_date:
raise Exception('Los datos aún no están actualizados')
Protección contra envíos duplicados mediante un archivo de estado:
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)
Envío a Mattermost
Usa mattermostdriver para subir el archivo y publicar:
from mattermostdriver import Driver
mm = Driver({
'url': 'tu-mattermost',
'token': 'TOKEN_DEL_BOT',
})
mm.login()
mm.posts.create_post({
'channel_id': channel_id,
'message': 'Informe listo',
'file_ids': [file_id],
})
Puntos Clave
- La automatización reduce el esfuerzo manual: los gráficos llegan al mensajero automáticamente tras las actualizaciones de datos.
- Las anotaciones en los gráficos garantizan información completa sin interacciones de hover.
- La combinación en un solo dashboard mejora la UX en el chat.
- Las verificaciones de actualidad y duplicados aseguran la fiabilidad del pipeline.
- Fácil de escalar: añade nuevos query_ids y parámetros.
— Editorial Team
Aún no hay comentarios.