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).
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
"""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}")
|
||||
Reference in New Issue
Block a user