get_dashboard_info.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. """Operator to assemble dashboard metadata from DuckDB for downstream prompts."""
  2. from __future__ import annotations
  3. import json
  4. from typing import Any, Dict, List
  5. from app.data_access import DuckDBClient
  6. from app.endpoints.schema import CardFilter, CardInfo, DashboardInfo
  7. def _build_filters(filter_rows: List[Dict[str, Any]]) -> Dict[str, List[CardFilter]]:
  8. filters_by_card: Dict[str, List[CardFilter]] = {}
  9. for row in filter_rows:
  10. options_raw = row.get("options") or "[]"
  11. try:
  12. options = json.loads(options_raw)
  13. except Exception:
  14. options = []
  15. card_filter = CardFilter(
  16. card_id=row["card_id"],
  17. filter_id=row["filter_id"],
  18. type=row.get("filter_type", "F"),
  19. where_clause=row.get("where_clause", ""),
  20. default_value=row.get("default_value"),
  21. options=options,
  22. )
  23. filters_by_card.setdefault(row["card_id"], []).append(card_filter)
  24. return filters_by_card
  25. def get_dashboard_info(input_args: Dict[str, Any]) -> DashboardInfo:
  26. """Retrieve dashboard info + card definitions + filters for given ids."""
  27. dashboard_id = input_args.get("dashboard_id")
  28. card_ids = input_args.get("card_ids") or []
  29. bbk_id = input_args.get("bbk")
  30. if not dashboard_id:
  31. raise ValueError("dashboard_id is required in input_args")
  32. client = DuckDBClient()
  33. mapping_rows = client.fetch_dashboard_cards(dashboard_id, card_ids, bbk_id)
  34. if not mapping_rows:
  35. raise ValueError(f"Dashboard {dashboard_id} not found or no cards match")
  36. target_card_ids = [row["card_id"] for row in mapping_rows]
  37. card_defs = {row["card_id"]: row for row in client.fetch_card_definition(target_card_ids)}
  38. filter_rows = client.fetch_card_filters(target_card_ids)
  39. filters_by_card = _build_filters(filter_rows)
  40. dashboard_meta = client.fetch_dashboard_info(dashboard_id) or {
  41. "dashboard_id": dashboard_id,
  42. "dashboard_name": mapping_rows[0].get("dashboard_name", ""),
  43. "dashboard_desc": "",
  44. "folder_path": "",
  45. }
  46. cards: List[CardInfo] = []
  47. for row in mapping_rows:
  48. card_id = row["card_id"]
  49. card_def = card_defs.get(card_id, {})
  50. cards.append(
  51. CardInfo(
  52. card_id=card_id,
  53. card_name=card_def.get("card_name", row.get("card_name", "")),
  54. card_desc=card_def.get("card_desc", ""),
  55. dataset_id=row.get("dataset_id", ""),
  56. sql_select=card_def.get("sql_select", ""),
  57. sql_where={},
  58. sql_groupby=card_def.get("sql_groupby", ""),
  59. filters=filters_by_card.get(card_id, []),
  60. )
  61. )
  62. return DashboardInfo(
  63. dashboard_id=dashboard_meta.get("dashboard_id", dashboard_id),
  64. dashboard_name=dashboard_meta.get("dashboard_name", ""),
  65. dashboard_desc=dashboard_meta.get("dashboard_desc", ""),
  66. folder_path=dashboard_meta.get("folder_path", ""),
  67. cards=cards,
  68. )