#!/usr/bin/env python3 """Configure dashboard 1019 filters as multi-select dropdowns. PKs no tienen has_field_values=list, asi que Metabase no auto-lista. Solucion: crear 3 cards "lookup" (id, name) y usarlas como values_source de cada parametro. Producto (2.7M rows) -> dropdown search (no card-source, busqueda en vivo). """ import json import subprocess import httpx API_KEY = subprocess.check_output(["pass", "show", "metabase/aurgi-api-key"], text=True).strip().splitlines()[0] BASE = "https://reports.autingo.es" COLLECTION_ID = 559 DASHBOARD_ID = 1019 client = httpx.Client(base_url=BASE, headers={"x-api-key": API_KEY}, timeout=180) # Lookup cards: id, name (orden alfabetico) LOOKUPS = { "centers": """ SELECT `psql_dcpublic.centers`.id AS id, `psql_dcpublic.centers`.name AS name FROM `psql_dcpublic.centers` WHERE `psql_dcpublic.centers`.id NOT IN (159, 162) ORDER BY name """, "cc_users": """ SELECT DISTINCT `psql_dcpublic.tpv_authorization_tpvuser`.id AS id, `psql_dcpublic.tpv_authorization_tpvuser`.name AS name FROM `psql_dcpublic.tpv_authorization_tpvuser` JOIN `psql_dcpublic.tpv_authorization_tpvuser_centers` ON `psql_dcpublic.tpv_authorization_tpvuser`.id = `psql_dcpublic.tpv_authorization_tpvuser_centers`.tpvuser_id WHERE `psql_dcpublic.tpv_authorization_tpvuser_centers`.dccenter_id IN (159, 162) AND `psql_dcpublic.tpv_authorization_tpvuser`.is_active ORDER BY name """, "companies": """ SELECT `psql_dcpublic.companies`.id AS id, `psql_dcpublic.companies`.name AS name FROM `psql_dcpublic.companies` ORDER BY name """, } def make_lookup_card(slug: str, sql: str) -> int: name = f"_lookup_{slug}" body = { "name": name, "description": f"Lookup table for dashboard filter dropdown ({slug})", "type": "question", "display": "table", "visualization_settings": {}, "dataset_query": { "type": "native", "database": 6, "native": {"query": sql.strip(), "template-tags": {}}, }, "collection_id": COLLECTION_ID, "result_metadata": None, } r = client.post("/api/card", json=body) r.raise_for_status() cid = r.json()["id"] print(f" lookup card {slug:12} -> {cid}") # Run query to populate result_metadata client.post(f"/api/card/{cid}/query") return cid print("creating lookup cards...") lookup_ids = {slug: make_lookup_card(slug, sql) for slug, sql in LOOKUPS.items()} # Re-read each card to pick up result_metadata field-ids (needed for value_field/label_field by name) def field_ref(card_id, col_name): """Reference column inside a native source card. Metabase accepts: ['field', '', {'base-type': '...'}] """ c = client.get(f"/api/card/{card_id}").json() for f in c.get("result_metadata", []) or []: if f["name"] == col_name: base = f.get("base_type", "type/Integer" if col_name == "id" else "type/Text") return ["field", col_name, {"base-type": base}] # fallback return ["field", col_name, {"base-type": "type/Integer" if col_name == "id" else "type/Text"}] print("\nupdating dashboard parameters...") new_params = [ {"id": "p_date", "name": "Fecha presupuesto", "slug": "fecha", "sectionId": "date", "type": "date/range"}, {"id": "p_centro", "name": "Centro", "slug": "centro", "sectionId": "id", "type": "id", "values_query_type": "list", "values_source_type": "card", "values_source_config": { "card_id": lookup_ids["centers"], "value_field": field_ref(lookup_ids["centers"], "id"), "label_field": field_ref(lookup_ids["centers"], "name"), }, "isMultiSelect": True}, {"id": "p_agente", "name": "Agente CC", "slug": "agente", "sectionId": "id", "type": "id", "values_query_type": "list", "values_source_type": "card", "values_source_config": { "card_id": lookup_ids["cc_users"], "value_field": field_ref(lookup_ids["cc_users"], "id"), "label_field": field_ref(lookup_ids["cc_users"], "name"), }, "isMultiSelect": True}, {"id": "p_compania", "name": "Compañía", "slug": "compania", "sectionId": "id", "type": "id", "values_query_type": "list", "values_source_type": "card", "values_source_config": { "card_id": lookup_ids["companies"], "value_field": field_ref(lookup_ids["companies"], "id"), "label_field": field_ref(lookup_ids["companies"], "name"), }, "isMultiSelect": True}, {"id": "p_producto", "name": "Producto", "slug": "producto", "sectionId": "id", "type": "id", "values_query_type": "search", "values_source_type": None, "values_source_config": {}, "isMultiSelect": True}, ] r = client.put(f"/api/dashboard/{DASHBOARD_ID}", json={"parameters": new_params}) r.raise_for_status() print("dashboard updated") print(f" URL: {BASE}/dashboard/{DASHBOARD_ID}") client.close()