## Add Widget to Dashboard

`evaluation_dashboards.widgets.create(strdashboard_id, WidgetCreateParams**kwargs)  -> EvaluationDashboardWidgetWithResult`

**post** `/v5/evaluation-dashboards/{dashboard_id}/widgets`

Create a new widget, append it to the dashboard, and compute its result in one call.

The widget is persisted as its own entity, its ID is appended to the dashboard's
`widget_order`, and — unless it is a `markdown` or `heading` widget — its result is
computed synchronously against the dashboard's evaluation (or evaluation-group) data
before the response returns. Validation is type-specific: `markdown` requires
`config.content`, `bar`/`histogram`/`donut`/`scatter` require exactly one of
`config.x_column` or `config.x_column_group`, `table` configs with conditional
formatting are schema-validated, and all other chart types require a `query`. The
dashboard must exist and not be archived. A computation failure does not fail the
request: the widget is still created and returned with a result whose
`computation_status` is `failed` and an `error_message` set, while `markdown` and
`heading` widgets return a null result.

### Parameters

- `dashboard_id: str`

- `title: str`

  Widget title

- `type: EvaluationWidgetTypeEnum`

  Widget type

  - `"bar"`

  - `"histogram"`

  - `"donut"`

  - `"scatter"`

  - `"metric"`

  - `"table"`

  - `"markdown"`

  - `"heading"`

  - `"timeseries"`

- `config: Optional[Dict[str, object]]`

  Chart-specific display configuration

- `query: Optional[Query]`

  Structured query AST for metric computation (SeriesQuery or MetricQuery)

  - `class SeriesQuery: …`

    Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

    Used for widget types: table, bar, histogram, donut, scatter.
    Returns: {"type": "series", "data": [...]}

    Example SQL equivalent:
    SELECT category, AVG(score) as avg_score, COUNT(*) as count
    FROM evaluation_items
    WHERE score > 0.5 AND category = 'test'
    GROUP BY category
    ORDER BY avg_score DESC
    LIMIT 100

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `class ExpressionColumn: …`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `column: str`

            Column name from evaluation_items.data

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["COLUMN"]]`

            - `"COLUMN"`

        - `class ExpressionAggregation: …`

          Aggregation function to apply

          Examples:
          {"type": "AGGREGATION", "function": "AVG", "column": "score"}
          {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
          {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

          - `column: str`

            Column to aggregate, or '*' for COUNT(*)

          - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

            Supported aggregation functions

            - `"COUNT"`

            - `"SUM"`

            - `"AVG"`

            - `"MIN"`

            - `"MAX"`

            - `"STDDEV"`

            - `"VARIANCE"`

            - `"PERCENTILE"`

            - `"COUNT_DISTINCT"`

            - `"PERCENTAGE"`

          - `evaluation_ids: Optional[List[str]]`

            Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

          - `params: Optional[Dict[str, object]]`

            Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["AGGREGATION"]]`

            - `"AGGREGATION"`

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

      - `conditions: List[Condition]`

        - `column: str`

          Column name to filter on

        - `operator: Literal["=", "!=", ">", 9 more]`

          Comparison operator

          - `"="`

          - `"!="`

          - `">"`

          - `"<"`

          - `">="`

          - `"<="`

          - `"IN"`

          - `"NOT IN"`

          - `"LIKE"`

          - `"NOT LIKE"`

          - `"IS NULL"`

          - `"IS NOT NULL"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `value: Optional[Union[str, float, bool, 2 more]]`

          Value to compare against. Not required for IS NULL / IS NOT NULL operators.

          - `str`

          - `float`

          - `bool`

          - `List[object]`

      - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

        Logical operators connecting conditions. Length must be len(conditions) - 1

        - `"AND"`

        - `"OR"`

    - `group_by: Optional[List[str]]`

      Columns to group by

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

    - `limit: Optional[int]`

      Max rows to return

    - `order_by: Optional[List[OrderBy]]`

      Sort order

      - `column: str`

        Column name to sort by

      - `direction: Optional[Literal["ASC", "DESC"]]`

        Sort direction

        - `"ASC"`

        - `"DESC"`

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

  - `class MetricQuery: …`

    Query that returns a single metric value (used for metric widgets).

    Used for widget type: metric.
    Enforces exactly 1 aggregation in select.
    Returns: {"type": "metric", "data": ...}

    Example SQL equivalent:
    SELECT AVG(score) as average_score
    FROM evaluation_items

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Returns

- `class EvaluationDashboardWidgetWithResult: …`

  Response model for widget creation - includes widget and computed result

  - `id: str`

    Unique identifier of the widget

  - `account_id: str`

    Account that owns this widget

  - `created_at: datetime`

    When the widget was created

  - `title: str`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: Optional[Dict[str, object]]`

    Display configuration

  - `object: Optional[Literal["evaluation_widget"]]`

    - `"evaluation_widget"`

  - `query: Optional[Query]`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `class SeriesQuery: …`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `class ExpressionColumn: …`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: str`

              Column name from evaluation_items.data

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["COLUMN"]]`

              - `"COLUMN"`

          - `class ExpressionAggregation: …`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: str`

              Column to aggregate, or '*' for COUNT(*)

            - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: Optional[List[str]]`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: Optional[Dict[str, object]]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["AGGREGATION"]]`

              - `"AGGREGATION"`

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

        - `conditions: List[Condition]`

          - `column: str`

            Column name to filter on

          - `operator: Literal["=", "!=", ">", 9 more]`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `value: Optional[Union[str, float, bool, 2 more]]`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `str`

            - `float`

            - `bool`

            - `List[object]`

        - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `group_by: Optional[List[str]]`

        Columns to group by

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: Optional[int]`

        Max rows to return

      - `order_by: Optional[List[OrderBy]]`

        Sort order

        - `column: str`

          Column name to sort by

        - `direction: Optional[Literal["ASC", "DESC"]]`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

    - `class MetricQuery: …`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: Optional[EvaluationDashboardWidgetResultResponse]`

    Computed result for this widget

    - `id: str`

      Unique identifier of the widget result

    - `computation_status: str`

      Status: pending, completed, or failed

    - `widget_id: str`

      Widget ID this result belongs to

    - `computed_at: Optional[datetime]`

      When computation completed

    - `computed_result: Optional[Dict[str, object]]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: Optional[str]`

      Error message if computation failed

### Example

```python
import os
from scale_gp_beta import SGPClient

client = SGPClient(
    api_key=os.environ.get("SGP_API_KEY"),  # This is the default and can be omitted
)
evaluation_dashboard_widget_with_result = client.evaluation_dashboards.widgets.create(
    dashboard_id="dashboard_id",
    title="x",
    type="bar",
)
print(evaluation_dashboard_widget_with_result.id)
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "title": "title",
  "type": "bar",
  "config": {
    "foo": "bar"
  },
  "object": "evaluation_widget",
  "query": {
    "select": [
      {
        "expression": {
          "column": "column",
          "source": "source",
          "type": "COLUMN"
        },
        "alias": "alias"
      }
    ],
    "evaluation_ids": [
      "string"
    ],
    "filter": {
      "conditions": [
        {
          "column": "column",
          "operator": "=",
          "source": "source",
          "value": "string"
        }
      ],
      "logicalOperators": [
        "AND"
      ]
    },
    "groupBy": [
      "string"
    ],
    "latest_only": true,
    "limit": 1,
    "orderBy": [
      {
        "column": "column",
        "direction": "ASC",
        "source": "source"
      }
    ]
  },
  "result": {
    "id": "id",
    "computation_status": "computation_status",
    "widget_id": "widget_id",
    "computed_at": "2019-12-27T18:11:19.117Z",
    "computed_result": {
      "foo": "bar"
    },
    "error_message": "error_message"
  }
}
```
