Skip to content

Commit ac60411

Browse files
committed
fix(gooddata-sdk): keep isHiddenFromKda on declarative metrics
CatalogDeclarativeMetric did not declare is_hidden_from_kda. The generated DeclarativeMetric gained the field when the API client was regenerated, but the SDK attrs class was not updated, and cattrs drops keys a class does not declare. So loading a metric layout from disk or the server lost the flag silently, and every SDK put sent the metric without it: a git deploy could never set it, and a load-then-put wiped a flag set in the UI. Declare the field on the metric class only; the other analytics classes share CatalogAnalyticsBase but their generated models have no such field. An unset field stays None and is not sent, so existing layouts and cassettes are unchanged. A round-trip test covers true, false and an absent key through disk and to_api(). jira: GDAI-2630 risk: low
1 parent 9e9ffae commit ac60411

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

‎packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ def client_class() -> type[DeclarativeFilterContext]:
331331

332332
@define(kw_only=True)
333333
class CatalogDeclarativeMetric(CatalogAnalyticsBase):
334+
is_hidden_from_kda: bool | None = None
335+
334336
@staticmethod
335337
def client_class() -> type[DeclarativeMetric]:
336338
return DeclarativeMetric
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# (C) 2026 GoodData Corporation
2+
"""Unit test: a metric's ``isHiddenFromKda`` survives the declarative round trip."""
3+
4+
from __future__ import annotations
5+
6+
from pathlib import Path
7+
8+
import pytest
9+
from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model import (
10+
CatalogDeclarativeAnalyticsLayer,
11+
)
12+
13+
_METRIC = {"id": "bmk_w_fraud_charged_back", "title": "BMK", "content": {"format": "#,##0", "maql": "SELECT 1"}}
14+
15+
16+
@pytest.mark.parametrize(
17+
("extra", "expected"),
18+
[
19+
({"isHiddenFromKda": True}, True),
20+
({"isHiddenFromKda": False}, False),
21+
({}, None),
22+
],
23+
ids=["hidden", "explicit-visible", "absent"],
24+
)
25+
def test_declarative_metric_is_hidden_from_kda_survives_round_trip(
26+
tmp_path: Path, extra: dict, expected: bool | None
27+
) -> None:
28+
layer = CatalogDeclarativeAnalyticsLayer.from_dict({"metrics": [{**_METRIC, **extra}]})
29+
30+
layer.store_to_disk(tmp_path)
31+
reloaded = CatalogDeclarativeAnalyticsLayer.load_from_disk(tmp_path)
32+
33+
assert reloaded.metrics[0].is_hidden_from_kda is expected
34+
assert reloaded.to_api().to_dict(camel_case=True)["metrics"][0] == {**_METRIC, **extra}

0 commit comments

Comments
 (0)