Files
fn_registry/python/functions/metabase/dashboards.py
egutierrez be5a7b582e feat: funciones Python para API Metabase
Añade módulo Python con funciones para la API de Metabase en dominio infra.
Incluye cliente HTTP, auth, y CRUD de cards, dashboards y users.
Proyecto gestionado con uv (pyproject.toml).
2026-03-28 20:32:28 +01:00

144 lines
4.7 KiB
Python

"""CRUD de dashboards de Metabase."""
from .client import MetabaseClient
def metabase_list_dashboards(
client: MetabaseClient,
filter: str = "",
) -> list[dict]:
"""Lista dashboards de Metabase con filtro opcional.
Endpoint: GET /api/dashboard. Retorna dashboards resumidos (sin dashcards).
Args:
client: Cliente autenticado.
filter: "all", "mine" o "archived". Vacio = todas.
Returns:
Lista de dicts con: id, name, description, collection_id,
creator_id, archived, created_at.
Example:
>>> dashboards = metabase_list_dashboards(client, filter="mine")
>>> for d in dashboards:
... print(d["id"], d["name"])
"""
params = {}
if filter:
params["f"] = filter
return client.request("GET", "/api/dashboard", params=params)
def metabase_get_dashboard(client: MetabaseClient, dashboard_id: int) -> dict:
"""Obtiene un dashboard completo incluyendo sus cards.
Endpoint: GET /api/dashboard/:id.
Args:
client: Cliente autenticado.
dashboard_id: ID del dashboard.
Returns:
Dict con: id, name, description, dashcards (lista de cards posicionadas),
parameters (filtros), tabs, collection_id, archived.
Cada dashcard tiene: id, card_id, card (objeto completo), size_x, size_y,
col, row, dashboard_tab_id, parameter_mappings, visualization_settings.
Example:
>>> dash = metabase_get_dashboard(client, 1)
>>> for dc in dash["dashcards"]:
... print(f"Card {dc['card_id']} at ({dc['col']}, {dc['row']})")
"""
return client.request("GET", f"/api/dashboard/{dashboard_id}")
def metabase_create_dashboard(
client: MetabaseClient,
name: str,
description: str = "",
collection_id: int = 0,
) -> dict:
"""Crea un nuevo dashboard vacio en Metabase.
Endpoint: POST /api/dashboard.
Para agregar cards usar metabase_update_dashboard con dashcards.
Args:
client: Cliente autenticado.
name: Nombre del dashboard.
description: Descripcion opcional.
collection_id: Coleccion destino. 0 = root.
Returns:
Dict con el dashboard creado.
Example:
>>> dash = metabase_create_dashboard(client, "Sales Overview", "KPIs de ventas")
>>> # Agregar cards:
>>> metabase_update_dashboard(client, dash["id"], dashcards=[
... {"id": -1, "card_id": 42, "size_x": 6, "size_y": 4, "col": 0, "row": 0},
... ])
"""
body: dict = {"name": name}
if description:
body["description"] = description
if collection_id > 0:
body["collection_id"] = collection_id
return client.request("POST", "/api/dashboard", json=body)
def metabase_update_dashboard(client: MetabaseClient, dashboard_id: int, **fields) -> dict:
"""Actualiza un dashboard incluyendo metadata, cards y tabs.
Endpoint: PUT /api/dashboard/:id.
El campo dashcards representa el ESTADO COMPLETO DESEADO del dashboard:
- Agregar card: incluirla con ID negativo (-1, -2, etc.)
- Actualizar card existente: incluirla con su ID positivo
- Eliminar card: omitirla del array
Args:
client: Cliente autenticado.
dashboard_id: ID del dashboard.
**fields: Campos a actualizar. Validos:
name (str), description (str), archived (bool),
dashcards (list[dict]), tabs (list[dict]),
parameters (list[dict]), collection_id (int).
Returns:
Dict con el dashboard actualizado.
Example:
>>> # Cambiar nombre
>>> metabase_update_dashboard(client, 1, name="Updated Name")
>>>
>>> # Agregar card (primero obtener existentes)
>>> dash = metabase_get_dashboard(client, 1)
>>> cards = list(dash["dashcards"])
>>> cards.append({"id": -1, "card_id": 55, "size_x": 6, "size_y": 4, "col": 0, "row": 0})
>>> metabase_update_dashboard(client, 1, dashcards=cards)
>>>
>>> # Archivar (soft-delete)
>>> metabase_update_dashboard(client, 1, archived=True)
"""
return client.request("PUT", f"/api/dashboard/{dashboard_id}", json=fields)
def metabase_delete_dashboard(client: MetabaseClient, dashboard_id: int) -> None:
"""Elimina permanentemente un dashboard.
Endpoint: DELETE /api/dashboard/:id. IRREVERSIBLE.
Para soft-delete preferir: metabase_update_dashboard(client, id, archived=True)
Args:
client: Cliente autenticado.
dashboard_id: ID del dashboard a eliminar.
Example:
>>> metabase_delete_dashboard(client, 1)
>>> # Preferir: metabase_update_dashboard(client, 1, archived=True)
"""
client.request("DELETE", f"/api/dashboard/{dashboard_id}")