Skip to content

kpi_builder

kpi_builder

Builder API for constructing Domo KPI card definitions from scratch.

This is the WRITE-side counterpart to :mod:kpi_definition (the READ/parse side). It mirrors the Magic ETL "action" registry pattern (DomoDataflow/action/base.py): a registry keyed by a friendly chart-type name, a @register_card_type decorator, a polymorphic base builder, and concrete per-chart-type subclasses.

Each builder accepts high-level parameters (dataset, title, measure, dimension, ...) and produces a fully-typed :class:KpiDefinition. Calling .to_dict() on that result yields the create/definition envelope.

Usage::

from crew_dcs.classes.DomoCard.kpi_builder import build_kpi_card_definition

envelope = build_kpi_card_definition(
    "bar",
    dataset_id="61c4e63d-0627-41f7-b138-74968ebd7634",
    title="Access by Object Type",
    dimension_column="Object_Type",
    measure_column="Event_ID",
    aggregation="COUNT",
)
# envelope == {"definition": {...}, "columns": []}
inner_definition = envelope["definition"]

Note on dataset_id: the create/definition envelope produced here does NOT embed the dataset id (Domo binds the dataset elsewhere on create — see the module __doc__ and the returned builder's dataset_id attribute). The id is retained on the builder so a caller/route can bind it at POST time.

BarCardBuilder dataclass

BarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Vertical bar chart (dimension + measure).

ComboCardBuilder dataclass

ComboCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Combo chart: bar + line on the same card (dimension + measure + series).

Useful for showing amounts as bars and a ratio/trend as a line on the same chart (e.g. Revenue as bars + Margin % as a line).

Set big_number_column to add a summary number above the chart.

DonutCardBuilder dataclass

DonutCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Donut chart (dimension + measure).

Useful for revenue mix, cost structure visualization.

FunnelCardBuilder dataclass

FunnelCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Funnel chart (dimension + measure). EXPERIMENTAL: badge_funnel is unverified against a live instance.

Useful as a P&L waterfall alternative: Revenue -> COGS -> Gross Profit -> Operating Expenses -> Net Income. Each stage is a dimension value.

GaugeCardBuilder dataclass

GaugeCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Filled-gauge chart (single measure, no dimension).

Useful for liquidity ratios (Current Ratio, Debt-to-Equity) and other single-value KPIs that benefit from a visual range indicator. Uses badge_filledgauge (a chartType confirmed present on live instances); badge_compgauge is the comparative-gauge alternative.

GroupedBarCardBuilder dataclass

GroupedBarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Vertical grouped/multi bar chart (dimension + measure + series).

HeatmapCardBuilder dataclass

HeatmapCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Heatmap chart (dimension + measure + series).

Useful for period-over-period comparison (e.g. monthly revenue by account type across years).

HorizontalBarCardBuilder dataclass

HorizontalBarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Horizontal bar chart (dimension + measure).

Useful for P&L line items where account names are long and read better on the y-axis.

HorizontalGroupedBarCardBuilder dataclass

HorizontalGroupedBarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Horizontal grouped/multi bar chart (dimension + measure + series). EXPERIMENTAL: badge_horiz_multibar is unverified; the confirmed grouped-bar type is the vertical badge_vert_multibar (grouped_bar).

Useful for Actual vs Budget comparisons by account category.

HorizontalStackedBarCardBuilder dataclass

HorizontalStackedBarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Horizontal stacked bar chart (dimension + measure + series).

Useful for balance sheet composition (Assets/Liabilities/Equity stacked by account type).

KpiCardBuilder dataclass

KpiCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Base builder for a Domo KPI card definition.

Subclasses register themselves with :func:register_card_type, which sets the friendly_name and chart_type class attributes. Behavioural flags (requires_dimension, supports_series, is_single_value) control how the main subscription is assembled.

Attributes:

Name Type Description
dataset_id str

Source dataset id. Retained for the caller to bind at POST time; NOT embedded in the emitted definition.

title str

Card title.

measure_column str | None

The VALUE column (aggregated numeric measure).

aggregation str

Aggregation applied to measure_column (e.g. "SUM").

dimension_column str | None

The ITEM / primary groupBy column.

series_column str | None

Optional SERIES / secondary grouping column.

filters list[Any]

Optional filters (raw dicts or :class:Filter instances).

order_by list[Any]

Optional sorts (raw dicts or :class:SortColumn instances).

overrides dict[str, Any]

Chart overrides (e.g. title_x, title_y, footer).

description str | None

Optional card description.

allow_table_drill bool

Whether table drill is allowed (default True).

build

build() -> KpiDefinition

Assemble and return a fully-typed :class:KpiDefinition.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
def build(self) -> KpiDefinition:
    """Assemble and return a fully-typed :class:`KpiDefinition`."""
    self._validate()

    # Build the beast-mode measure (if any) before assembling columns so the
    # VALUE mapping can reference it by formula id.
    formulas: list[Formula] = []
    self._formula_id = None
    if self.measure_beastmode:
        ref = self.measure_beastmode
        fobj = build_persisted_formula(
            legacy_id=ref["legacy_id"],
            template_id=ref["template_id"],
            name=ref.get("name", ""),
            expression=ref["expression"],
            data_type=ref.get("data_type", "DECIMAL"),
        )
        self._formula_id = fobj.id
        formulas.append(fobj)
    elif self.measure_formula:
        fobj = build_formula(
            name=self.measure_formula["name"],
            expression=self.measure_formula["formula"],
            data_type=self.measure_formula.get("data_type", "DECIMAL"),
        )
        self._formula_id = fobj.id
        formulas.append(fobj)

    main_extras: dict[str, Any] = {}
    if self.date_grain:
        main_extras["dateGrain"] = self.date_grain

    main = Subscription(
        name="main",
        columns=self.build_columns(),
        filters=self._coerce_filters(),
        order_by=self._coerce_order_by(),
        group_by=self.build_group_by(),
        fiscal=False,
        projection=False,
        distinct=False,
        extras=main_extras,
    )

    subscriptions: dict[str, Subscription] = {"main": main}

    # Optional big_number subscription (combo cards: summary number above chart)
    if self.big_number_column or self.big_number_formula_id:
        bn_col: ColumnMapping
        if self.big_number_formula_id:
            bn_col = ColumnMapping(
                formula_id=self.big_number_formula_id,
                mapping="VALUE",
            )
        else:
            bn_col = ColumnMapping(
                column=self.big_number_column,
                aggregation=self.big_number_aggregation,
                mapping="VALUE",
            )
        big_number = Subscription(
            name="big_number",
            columns=[bn_col],
            filters=self._coerce_filters(),
            order_by=[],
            group_by=[],
            fiscal=False,
            projection=False,
            distinct=False,
        )
        subscriptions["big_number"] = big_number

    charts = {
        "main": {
            "component": "main",
            "chartType": self.chart_type,
            "overrides": dict(self.overrides),
            "goal": None,
        }
    }

    return KpiDefinition(
        subscriptions=subscriptions,
        formulas=formulas,
        charts=charts,
        segments={"active": [], "definitions": []},
        conditional_formats=[],
        annotations=[],
        slicers=[],
        title=self.title,
        description=self.description,
        chart_version="12",
        allow_table_drill=self.allow_table_drill,
        input_table=False,
    )

build_columns

build_columns() -> list[ColumnMapping]

Build the main subscription column mappings.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
316
317
318
319
320
321
322
323
324
325
326
327
def build_columns(self) -> list[ColumnMapping]:
    """Build the ``main`` subscription column mappings."""
    if self.is_single_value:
        return [self._measure_mapping("VALUE")]

    columns = [
        ColumnMapping(column=self.dimension_column, mapping="ITEM"),
        self._measure_mapping("VALUE"),
    ]
    if self.supports_series and self.series_column:
        columns.append(ColumnMapping(column=self.series_column, mapping="SERIES"))
    return columns

build_group_by

build_group_by() -> list[GroupByColumn]

Build the main subscription groupBy columns.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
329
330
331
332
333
334
335
336
def build_group_by(self) -> list[GroupByColumn]:
    """Build the ``main`` subscription groupBy columns."""
    if self.is_single_value or not self.dimension_column:
        return []
    groups = [GroupByColumn(column=self.dimension_column)]
    if self.supports_series and self.series_column:
        groups.append(GroupByColumn(column=self.series_column))
    return groups

to_dict

to_dict() -> dict[str, Any]

Build the card and return the full create/definition envelope.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
459
460
461
def to_dict(self) -> dict[str, Any]:
    """Build the card and return the full create/definition envelope."""
    return self.build().to_dict()

LineCardBuilder dataclass

LineCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Line/line-bar combo chart (dimension + measure, optional series).

Useful for trend over time (Revenue, Expenses, Net Income).

ParetoCardBuilder dataclass

ParetoCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Pareto chart (dimension + measure). EXPERIMENTAL: badge_pareto is unverified against a live instance.

Shows the 80/20 rule — useful for identifying which accounts or cost categories drive the majority of revenue or expense.

PieCardBuilder dataclass

PieCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Pie chart (dimension + measure).

Useful for asset allocation, expense distribution, revenue mix.

SingleValueCardBuilder dataclass

SingleValueCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Single big-number card (no dimension).

StackedBarCardBuilder dataclass

StackedBarCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Vertical stacked bar chart (dimension + measure + series).

TableCardBuilder dataclass

TableCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Basic table card.

A table lists one or more VALUE columns and does not require a dimension / groupBy. The base build_columns emits an ITEM + VALUE pair; for a table we emit the measure as a plain VALUE column with no groupBy.

TreemapCardBuilder dataclass

TreemapCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Treemap chart (dimension + measure + series). EXPERIMENTAL: badge_treemap is unverified; badge_sunburst is the confirmed hierarchical alternative.

Useful for hierarchical financial data — shows account hierarchy as nested rectangles sized by amount.

TrendlineCardBuilder dataclass

TrendlineCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Trend line chart (dimension + measure). EXPERIMENTAL: badge_trendline is unverified; confirmed line-ish alternatives are badge_rttrendline, badge_two_trendline and badge_symbolline.

Useful for showing financial trends over time (revenue growth, cost trends, margin trajectory).

WaterfallCardBuilder dataclass

WaterfallCardBuilder(
    dataset_id: str = "",
    title: str = "",
    measure_column: str | None = None,
    aggregation: str = "SUM",
    measure_formula: dict[str, Any] | None = None,
    measure_beastmode: dict[str, Any] | None = None,
    dimension_column: str | None = None,
    series_column: str | None = None,
    filters: list[Any] = list(),
    order_by: list[Any] = list(),
    overrides: dict[str, Any] = dict(),
    description: str | None = None,
    allow_table_drill: bool = True,
    date_grain: dict[str, Any] | None = None,
    big_number_column: str | None = None,
    big_number_aggregation: str = "SUM",
    big_number_formula_id: str | None = None,
)

Bases: KpiCardBuilder

Waterfall-style chart using vertical bar (dimension + measure).

Domo does not expose a dedicated badge_waterfall chartType via the Content API. This builder uses badge_vert_bar as the closest substitute — the card can be switched to waterfall display in the Domo UI after creation. Each dimension value becomes a step in the P&L bridge (Revenue -> COGS -> Gross Profit -> Net Income).

build_formula

build_formula(
    name: str, expression: str, data_type: str = "DECIMAL"
) -> Formula

Build a card-level beast mode :class:Formula from a name + expression.

This produces a formula embedded in a single card's definition (a calculation_<uuid> reference). It is not persisted on the dataset and is not reusable across cards — use it for one-off, card-specific calculations.

For a reusable, governed metric that many cards reference (and that appears in Domo's beast-mode catalog), create a dataset-level beast mode instead via :meth:crew_dcs.classes.DomoBeastMode.DomoBeastMode.create.

The expression is Domo Beast Mode SQL with dataset columns wrapped in backticks, e.g. "SUM(`SalesAmount`) - SUM(`TotalProductCost`)". columnPositions are derived from the backticked tokens.

Parameters:

Name Type Description Default
name str

Display name of the beast mode.

required
expression str

Beast Mode SQL (columns in backticks).

required
data_type str

Output data type (e.g. "DECIMAL", "LONG").

'DECIMAL'
Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def build_formula(name: str, expression: str, data_type: str = "DECIMAL") -> Formula:
    """Build a **card-level** beast mode :class:`Formula` from a name + expression.

    This produces a formula embedded in a *single card's* definition (a
    ``calculation_<uuid>`` reference). It is not persisted on the dataset and is
    not reusable across cards — use it for one-off, card-specific calculations.

    For a **reusable, governed** metric that many cards reference (and that
    appears in Domo's beast-mode catalog), create a *dataset-level* beast mode
    instead via :meth:`crew_dcs.classes.DomoBeastMode.DomoBeastMode.create`.

    The ``expression`` is Domo Beast Mode SQL with dataset columns wrapped in
    backticks, e.g. ``"SUM(`SalesAmount`) - SUM(`TotalProductCost`)"``.
    ``columnPositions`` are derived from the backticked tokens.

    Args:
        name: Display name of the beast mode.
        expression: Beast Mode SQL (columns in backticks).
        data_type: Output data type (e.g. ``"DECIMAL"``, ``"LONG"``).
    """
    positions = [
        ColumnRef(column_name=m.group(0), column_position=m.start())
        for m in _BACKTICK_COL.finditer(expression)
    ]
    return Formula(
        id=f"calculation_{uuid.uuid4()}",
        name=name,
        formula=expression,
        status="VALID",
        data_type=data_type,
        column_positions=positions,
        variable=False,
        persisted_on_data_source=False,
        is_aggregatable=False,
    )

build_kpi_card_definition

build_kpi_card_definition(
    chart_type: str, **kwargs: Any
) -> dict[str, Any]

Build a card definition envelope for a friendly chart type.

Parameters:

Name Type Description Default
chart_type str

Friendly chart-type name (see :func:get_registered_card_types).

required
**kwargs Any

Passed through to the :class:KpiCardBuilder subclass (dataset_id, title, measure_column, aggregation, dimension_column, series_column, filters, order_by, overrides, description, ...).

{}

Returns:

Type Description
dict[str, Any]

The full envelope {"definition": {...}, "columns": [...]}. The

dict[str, Any]

ready-to-send inner definition is available at result["definition"].

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
def build_kpi_card_definition(chart_type: str, **kwargs: Any) -> dict[str, Any]:
    """Build a card definition envelope for a friendly chart type.

    Args:
        chart_type: Friendly chart-type name (see :func:`get_registered_card_types`).
        **kwargs: Passed through to the :class:`KpiCardBuilder` subclass
            (``dataset_id``, ``title``, ``measure_column``, ``aggregation``,
            ``dimension_column``, ``series_column``, ``filters``, ``order_by``,
            ``overrides``, ``description``, ...).

    Returns:
        The full envelope ``{"definition": {...}, "columns": [...]}``.  The
        ready-to-send inner definition is available at ``result["definition"]``.
    """
    builder_cls = get_card_builder_class(chart_type)
    builder = builder_cls(**kwargs)
    return builder.to_dict()

build_persisted_formula

build_persisted_formula(
    legacy_id: str,
    template_id: int,
    name: str,
    expression: str,
    data_type: str = "DECIMAL",
) -> Formula

Build a reference to an existing dataset-level beast mode.

Unlike :func:build_formula (which mints a fresh card-only formula), this references a beast mode already persisted on the dataset: it reuses the beast mode's legacy_id (calculation_<uuid>) as the formula id, sets persistedOnDataSource=True and the templateId linking back to the dataset template. Referencing by legacy_id (not display name) is what keeps cards working when a beast mode is renamed.

Parameters:

Name Type Description Default
legacy_id str

The beast mode's legacyId (calculation_<uuid>).

required
template_id int

The dataset template id (integer) of the beast mode.

required
name str

Display name (informational; the link is via legacy_id/template_id).

required
expression str

The beast mode's SQL expression (Domo stores a copy on the card).

required
data_type str

Result data type.

'DECIMAL'
Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def build_persisted_formula(
    legacy_id: str,
    template_id: int,
    name: str,
    expression: str,
    data_type: str = "DECIMAL",
) -> Formula:
    """Build a reference to an existing **dataset-level** beast mode.

    Unlike :func:`build_formula` (which mints a fresh card-only formula), this
    references a beast mode already persisted on the dataset: it reuses the beast
    mode's ``legacy_id`` (``calculation_<uuid>``) as the formula id, sets
    ``persistedOnDataSource=True`` and the ``templateId`` linking back to the
    dataset template. Referencing by ``legacy_id`` (not display name) is what
    keeps cards working when a beast mode is renamed.

    Args:
        legacy_id: The beast mode's ``legacyId`` (``calculation_<uuid>``).
        template_id: The dataset template id (integer) of the beast mode.
        name: Display name (informational; the link is via legacy_id/template_id).
        expression: The beast mode's SQL expression (Domo stores a copy on the card).
        data_type: Result data type.
    """
    positions = [
        ColumnRef(column_name=m.group(0), column_position=m.start())
        for m in _BACKTICK_COL.finditer(expression)
    ]
    return Formula(
        id=legacy_id,
        name=name,
        formula=expression,
        status="VALID",
        data_type=data_type,
        column_positions=positions,
        variable=False,
        persisted_on_data_source=True,
        template_id=template_id,
        is_aggregatable=False,
    )

card_type_map

card_type_map() -> dict[str, str]

Return the friendly-name -> Domo-chartType mapping.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
225
226
227
def card_type_map() -> dict[str, str]:
    """Return the friendly-name -> Domo-chartType mapping."""
    return dict(_CARD_CHART_TYPE_MAP)

get_card_builder_class

get_card_builder_class(
    friendly_name: str,
) -> type[KpiCardBuilder]

Return the builder class registered for a friendly chart-type name.

Raises:

Type Description
ValueError

If the friendly name is not registered.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
192
193
194
195
196
197
198
199
200
201
202
203
204
def get_card_builder_class(friendly_name: str) -> type[KpiCardBuilder]:
    """Return the builder class registered for a friendly chart-type name.

    Raises:
        ValueError: If the friendly name is not registered.
    """
    cls = _CARD_BUILDER_REGISTRY.get(friendly_name)
    if cls is None:
        known = ", ".join(sorted(_CARD_BUILDER_REGISTRY))
        raise ValueError(
            f"Unknown card chart type '{friendly_name}'. Registered: {known}"
        )
    return cls

get_experimental_card_types

get_experimental_card_types() -> list[str]

Return friendly names whose Domo chartType is unverified (experimental).

These builders emit a chartType string that has not been confirmed against a real card on a live instance; creating them may fail or render empty.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
212
213
214
215
216
217
218
219
220
221
222
def get_experimental_card_types() -> list[str]:
    """Return friendly names whose Domo chartType is unverified (experimental).

    These builders emit a chartType string that has not been confirmed against
    a real card on a live instance; creating them may fail or render empty.
    """
    return sorted(
        name
        for name, cls in _CARD_BUILDER_REGISTRY.items()
        if getattr(cls, "experimental", False)
    )

get_registered_card_types

get_registered_card_types() -> list[str]

Return all registered friendly chart-type names.

Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
207
208
209
def get_registered_card_types() -> list[str]:
    """Return all registered friendly chart-type names."""
    return sorted(_CARD_BUILDER_REGISTRY)

register_card_type

register_card_type(friendly_name: str, chart_type: str)

Decorator registering a :class:KpiCardBuilder subclass.

Parameters:

Name Type Description Default
friendly_name str

Human-friendly key (e.g. "bar", "single_value").

required
chart_type str

Domo chartType string (e.g. "badge_vert_bar").

required
Source code in src/crew_dcs/classes/DomoCard/kpi_builder.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
def register_card_type(friendly_name: str, chart_type: str):
    """Decorator registering a :class:`KpiCardBuilder` subclass.

    Args:
        friendly_name: Human-friendly key (e.g. ``"bar"``, ``"single_value"``).
        chart_type: Domo ``chartType`` string (e.g. ``"badge_vert_bar"``).
    """

    def decorator(cls: type[KpiCardBuilder]) -> type[KpiCardBuilder]:
        cls.friendly_name = friendly_name
        cls.chart_type = chart_type
        _CARD_BUILDER_REGISTRY[friendly_name] = cls
        _CARD_CHART_TYPE_MAP[friendly_name] = chart_type
        return cls

    return decorator