dashui
DashUI — shared ipywidgets component library for the Dashlibs suite. Import from here in any dash-* package instead of duplicating widget code.
1""" 2DashUI — shared ipywidgets component library for the Dashlibs suite. 3Import from here in any dash-* package instead of duplicating widget code. 4""" 5from dashui.components import ( 6 SourceSelector, 7 action_button, 8 card, 9 header, 10 html, 11 output_panel, 12 running_list, 13 section, 14 source_selector, 15 status_line, 16) 17from dashui.schema import list_columns, list_columns_safe 18from dashui.theme import accent 19 20__version__ = "0.1.2" 21__all__ = [ 22 "SourceSelector", 23 "action_button", 24 "card", 25 "header", 26 "html", 27 "output_panel", 28 "running_list", 29 "section", 30 "source_selector", 31 "status_line", 32 "list_columns", 33 "list_columns_safe", 34 "accent", 35]
54@dataclass 55class SourceSelector: 56 """ 57 The UC Table / DataFrame variable / SQL Query picker used by every 58 Dashlibs UI that reads from Databricks. 59 60 Usage:: 61 src = source_selector() 62 ui = card([src.toggle, src.box, ...]) 63 kind, value = src.value() 64 """ 65 toggle: object 66 box: object 67 table_input: object 68 df_input: object 69 sql_input: object 70 71 def value(self) -> tuple[str, str]: 72 """Returns (kind, value) where kind is 'table' | 'dataframe' | 'sql'.""" 73 if self.toggle.value == "UC Table": 74 return "table", self.table_input.value.strip() 75 if self.toggle.value == "DataFrame variable": 76 return "dataframe", self.df_input.value.strip() 77 return "sql", self.sql_input.value.strip() 78 79 def resolve_df(self): 80 """Resolve the selected source to a Spark DataFrame (for direct use in core classes).""" 81 kind, value = self.value() 82 if kind == "dataframe": 83 import IPython 84 shell = IPython.get_ipython() 85 df = shell.user_ns.get(value) if shell else None 86 if df is None: 87 raise ValueError(f"Variable '{value}' not found") 88 return df 89 from pyspark.sql import SparkSession 90 spark = SparkSession.getActiveSession() 91 if kind == "table": 92 return spark.table(value) 93 return spark.sql(value)
The UC Table / DataFrame variable / SQL Query picker used by every Dashlibs UI that reads from Databricks.
Usage:: src = source_selector() ui = card([src.toggle, src.box, ...]) kind, value = src.value()
71 def value(self) -> tuple[str, str]: 72 """Returns (kind, value) where kind is 'table' | 'dataframe' | 'sql'.""" 73 if self.toggle.value == "UC Table": 74 return "table", self.table_input.value.strip() 75 if self.toggle.value == "DataFrame variable": 76 return "dataframe", self.df_input.value.strip() 77 return "sql", self.sql_input.value.strip()
Returns (kind, value) where kind is 'table' | 'dataframe' | 'sql'.
79 def resolve_df(self): 80 """Resolve the selected source to a Spark DataFrame (for direct use in core classes).""" 81 kind, value = self.value() 82 if kind == "dataframe": 83 import IPython 84 shell = IPython.get_ipython() 85 df = shell.user_ns.get(value) if shell else None 86 if df is None: 87 raise ValueError(f"Variable '{value}' not found") 88 return df 89 from pyspark.sql import SparkSession 90 spark = SparkSession.getActiveSession() 91 if kind == "table": 92 return spark.table(value) 93 return spark.sql(value)
Resolve the selected source to a Spark DataFrame (for direct use in core classes).
46def card(children, padding: str = "16px"): 47 """Bordered VBox wrapper used as the outer container for every launch() UI.""" 48 w = _require_widgets() 49 return w.VBox(list(children), layout=w.Layout( 50 padding=padding, border=f"1px solid {BORDER}", border_radius="8px", 51 ))
Bordered VBox wrapper used as the outer container for every launch() UI.
25def header(title: str, library: str = "default", emoji: str = "", subtitle: str = ""): 26 """Top banner used at the start of every launch() UI.""" 27 color = accent(library) 28 sub = f"<div style='font-size:12px;color:{MUTED};margin-top:2px'>{subtitle}</div>" if subtitle else "" 29 return html( 30 f"<h2 style='color:{color};margin-bottom:0'>{emoji} {title}</h2>{sub}" 31 )
Top banner used at the start of every launch() UI.
122def output_panel(): 123 """Standard scrollable output area for run/profile results and errors.""" 124 w = _require_widgets() 125 return w.Output()
Standard scrollable output area for run/profile results and errors.
128def running_list(formatter): 129 """ 130 A live-updating numbered list display, the pattern used for 'added entities' 131 / 'added relationships' style accumulators. 132 133 Usage:: 134 items = [] 135 out, render = running_list(lambda i, item: f"{i}. {item['name']}") 136 items.append({"name": "Customer"}) 137 render(items) 138 """ 139 w = _require_widgets() 140 out = w.Output() 141 142 def render(items: list): 143 with out: 144 out.clear_output() 145 for i, item in enumerate(items, 1): 146 print(formatter(i, item)) 147 148 return out, render
A live-updating numbered list display, the pattern used for 'added entities' / 'added relationships' style accumulators.
Usage:: items = [] out, render = running_list(lambda i, item: f"{i}. {item['name']}") items.append({"name": "Customer"}) render(items)
34def section(title: str): 35 """Step/section divider, e.g. '<b>Step 1: Source data</b>'.""" 36 return html(f"<hr><b>{title}</b>")
Step/section divider, e.g. 'Step 1: Source data'.
96def source_selector(label: str = "Source:") -> SourceSelector: 97 w = _require_widgets() 98 toggle = w.ToggleButtons(options=["UC Table", "DataFrame variable", "SQL Query"], description=label) 99 table_input = w.Text(placeholder="catalog.schema.table", description="Table:") 100 df_input = w.Text(placeholder="df", description="Variable:") 101 sql_input = w.Textarea(placeholder="SELECT * FROM ...", description="SQL:", rows=3) 102 box = w.VBox([table_input]) 103 104 def on_change(change): 105 if change["new"] == "UC Table": 106 box.children = [table_input] 107 elif change["new"] == "DataFrame variable": 108 box.children = [df_input] 109 else: 110 box.children = [sql_input] 111 112 toggle.observe(on_change, names="value") 113 return SourceSelector(toggle, box, table_input, df_input, sql_input)
39def status_line(text: str, kind: str = "info"): 40 """One-line colored status message: kind in success|error|warning|info.""" 41 color = {"success": SUCCESS, "error": DANGER, "warning": "#F57C00", "info": NEUTRAL}.get(kind, NEUTRAL) 42 prefix = {"success": "✅", "error": "❌", "warning": "⚠️", "info": "ℹ️"}.get(kind, "") 43 return html(f"<span style='color:{color}'>{prefix} {text}</span>")
One-line colored status message: kind in success|error|warning|info.
6def list_columns(table: str) -> list[str]: 7 """Return column names for a UC table, without loading any data.""" 8 from pyspark.sql import SparkSession 9 spark = SparkSession.getActiveSession() 10 return [f.name for f in spark.table(table).schema.fields]
Return column names for a UC table, without loading any data.
13def list_columns_safe(table: str) -> list[str]: 14 """Like list_columns, but returns [] instead of raising — for UI dropdowns.""" 15 try: 16 return list_columns(table) 17 except Exception: 18 return []
Like list_columns, but returns [] instead of raising — for UI dropdowns.
23def accent(library: str) -> str: 24 """Look up the accent color for a Dashlibs package name (e.g. 'dashsynthetic').""" 25 return ACCENTS.get(library, ACCENTS["default"])
Look up the accent color for a Dashlibs package name (e.g. 'dashsynthetic').