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]
@dataclass
class SourceSelector:
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()

SourceSelector( toggle: object, box: object, table_input: object, df_input: object, sql_input: object)
toggle: object
box: object
table_input: object
df_input: object
sql_input: object
def value(self) -> tuple[str, str]:
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'.

def resolve_df(self):
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).

def action_button(text: str, style: str = 'primary', emoji: str = ''):
116def action_button(text: str, style: str = "primary", emoji: str = ""):
117    w = _require_widgets()
118    label = f"{emoji} {text}".strip()
119    return w.Button(description=label, button_style=style, layout=w.Layout(height="36px"))
def card(children, padding: str = '16px'):
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.

def html(text: str):
20def html(text: str):
21    w = _require_widgets()
22    return w.HTML(text)
def output_panel():
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.

def running_list(formatter):
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)

def section(title: str):
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'.

def source_selector(label: str = 'Source:') -> SourceSelector:
 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)
def status_line(text: str, kind: str = 'info'):
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.

def list_columns(table: str) -> list[str]:
 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.

def list_columns_safe(table: str) -> list[str]:
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.

def accent(library: str) -> str:
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').