feat(metabase): auto-commit con 17 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 18:40:22 +02:00
parent aec5d82011
commit d110aa40f9
17 changed files with 1946 additions and 2 deletions
@@ -0,0 +1,103 @@
---
name: metabase_dashboard_append_row
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def metabase_dashboard_append_row(client: MetabaseClient, *, dashboard_id: int, tab_id: int, card_ids: list[int], height: int = 4, donor_card_id: int = 0, grid_width: int = 24) -> dict"
description: "Añade N cards como fila horizontal al final de una tab de dashboard. Calcula la primera fila libre con metabase_dashboard_next_row, distribuye las cards con ancho uniforme (grid_width // N), copia parameter_mappings de un dashcard donante si se indica y llama a metabase_update_dashboard_safe. Util para añadir filas de KPIs con los filtros del dashboard ya conectados."
tags: [metabase, dashboard, dashcard, layout, row, append, parameter-mappings, api, python]
uses_functions:
- metabase_dashboard_next_row_py_infra
- metabase_copy_dashcard_mappings_py_infra
- metabase_update_dashboard_safe_py_infra
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
- name: client
desc: "MetabaseClient autenticado con sesion activa"
- name: dashboard_id
desc: "ID del dashboard donde se añaden las cards"
- name: tab_id
desc: "ID de la tab donde se insertan las cards. Usar 0 para dashboards sin tabs o tab raiz"
- name: card_ids
desc: "Lista de IDs de cards a colocar como fila, de izquierda a derecha. No puede estar vacia"
- name: height
desc: "Altura en filas del grid para cada card. Default 4"
- name: donor_card_id
desc: "Si distinto de 0, copia los parameter_mappings de esa card a cada nueva card. Util para replicar los filtros de dashboard ya configurados. Default 0 (sin mappings)"
- name: grid_width
desc: "Anchura total del grid de Metabase. Default 24 (estandar). Cada card recibe grid_width // len(card_ids) columnas"
output: "Dict con el resumen de metabase_update_dashboard_safe: {'added': [negative_ids], 'updated': int, 'removed': int, 'response': dict_respuesta_PUT}"
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/metabase/metabase_dashboard_append_row.py"
---
## Por que existe
Añadir una fila de KPIs a un dashboard de Metabase que ya tiene 18 filtros
requiere: (1) calcular la fila libre, (2) construir cada dashcard con su
``parameter_mappings`` copiado, y (3) enviar el PUT sin activar los gotchas
conocidos (413, 500 FK). Esta funcion compone las tres operaciones atomicas
del registry en un solo paso.
## Ejemplo
```python
from metabase import MetabaseClient, metabase_dashboard_append_row
client = MetabaseClient("https://metabase.example.com", "token...")
# Añadir 4 KPIs al final de la tab 7, copiando filtros de card 42
result = metabase_dashboard_append_row(
client,
dashboard_id=10,
tab_id=7,
card_ids=[101, 102, 103, 104],
height=4,
donor_card_id=42,
)
print(result["added"]) # [-1, -2, -3, -4] IDs temporales asignados
# Añadir 2 cards sin filtros en dashboard sin tabs
result = metabase_dashboard_append_row(
client,
dashboard_id=15,
tab_id=0,
card_ids=[200, 201],
height=6,
)
# Añadir 1 card de ancho completo (24 columnas)
result = metabase_dashboard_append_row(
client,
dashboard_id=10,
tab_id=7,
card_ids=[300],
height=8,
donor_card_id=42,
)
```
## Notas
- Realiza entre 2 y ``1 + 2*len(card_ids)`` requests HTTP: 1 GET para
``next_row`` + (si ``donor_card_id != 0``) 1 GET por card para los
mappings (que comparten el GET del siguiente ``update_safe``) + 1 GET + 1
PUT para ``update_dashboard_safe``. En practica ``metabase_get_dashboard``
se llama 2-3 veces segun si hay donor.
- Si ``grid_width // len(card_ids)`` produce un cociente con resto, las
columnas sobrantes (al lado derecho) quedan vacias en el grid. Para
ajuste preciso, construir los dashcards manualmente y usar
``metabase_update_dashboard_safe`` directamente.
- ``donor_card_id`` debe ser el ``card_id`` de una card que ya existe en el
dashboard (no el ID del dashcard). Lanza ``ValueError`` si no se
encuentra.
- Si ``tab_id != 0``, ``metabase_update_dashboard_safe`` conserva las tabs
del dashboard (evita 500 FK violation).