Skip to content

feat(gooddata-sdk): [AUTO] Add DashboardMeasureValueFilter with comparison and range conditions#1603

Open
yenkins-admin wants to merge 2 commits into
masterfrom
auto/openapi-sync-C003-20260512-r59682
Open

feat(gooddata-sdk): [AUTO] Add DashboardMeasureValueFilter with comparison and range conditions#1603
yenkins-admin wants to merge 2 commits into
masterfrom
auto/openapi-sync-C003-20260512-r59682

Conversation

@yenkins-admin
Copy link
Copy Markdown
Contributor

Summary

Added SDK wrappers for DashboardMeasureValueFilter (cluster C003). Created dashboard_filters.py with five new classes: CatalogDashboardCompoundComparisonCondition, CatalogDashboardCompoundRangeCondition, CatalogDashboardCompoundConditionItem (Union alias), CatalogDashboardMeasureValueFilterBody, and CatalogDashboardMeasureValueFilter. All classes use explicit custom to_api()/from_api() overrides to handle the from Python keyword issue (_from ↔ from_value). A cattrs structure hook discriminates the Union by presence of the value key. All five names are re-exported from the package root init.py. An integration test test_dashboard_measure_value_filter was added to test_catalog_workspace_content.py with a VCR cassette stub.

Impact: new_feature | Services: gooddata-automation-client, gooddata-export-client, gooddata-metadata-client

Files changed

  • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/dashboard_filters.py
  • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py

Agent decisions

Decisions (4)

from_value attribute name — Use from_value in the SDK wrapper and map to _from in to_api()

  • Alternatives: Use from as attribute name (ugly, leaks API internals), Use from as attribute name (PEP8 convention for shadowed keywords, less descriptive)
  • Why: from is a Python keyword so it cannot be used as an attribute name. The API client uses _from as the Python attribute (mapped to JSON key from). Using from_value avoids any reserved-keyword issues while from_api() accepts all three variants (from_value, from, _from) for robustness.

Override to_api/from_api vs default Base methods — Custom to_api() and from_api() on every new class

  • Alternatives: Override to_dict() to rename from_value → _from (fragile, affects round-trip equality checks), Use the default path and post-process the dict (error-prone)
  • Why: The default Base.to_api() path calls _get_snake_dict() then client_class().from_dict() which would emit from_value in the dict rather than _from, breaking the API client constructor. Custom methods give precise control over the attribute rename.

Union discriminator strategy — Discriminate CatalogDashboardCompoundConditionItem by presence of value key

  • Alternatives: Discriminate by presence of from/_from key (equivalent but less obvious), Add an explicit type discriminator field (would require API schema change)
  • Why: Comparison conditions always have a value field; range conditions have from/to but no value. This is an unambiguous discriminator from the API spec. Registered as a global_converter structure hook following the existing pattern in analytics_model.py.

New file location — dashboard_filters.py alongside analytics_model.py in the analytics_model package

  • Alternatives: Add classes inline to analytics_model.py (too large, hard to navigate), Place in a separate filters/ subpackage (over-engineering for 4 classes)
  • Why: DashboardMeasureValueFilter is used in dashboard filter contexts (analytics domain). Placing it next to analytics_model.py keeps the domain cohesive and avoids polluting the analytics_model.py file which is already large.
Assumptions to verify (4)
  • Dashboard content is stored as opaque dict[str, Any] in CatalogAnalyticsBase so the new filter type passes through existing put/get flows automatically without modifying the analytics model service layer.
  • The API cassette for test_dashboard_measure_value_filter does not yet exist and needs to be recorded against a live GoodData instance.
  • The workspace used in tests (test_config['workspace']) has at least one analytical dashboard, as asserted in the test.
  • The measure ID 'order_amount' of type 'metric' is available in the demo workspace; the test will fail cassette recording if not — but can be updated to match the actual workspace content.
Risks (4)
  • Cassette test_dashboard_measure_value_filter.yaml does not exist yet — the test will be skipped or fail until recorded against a live environment.
  • The discriminator for CatalogDashboardCompoundConditionItem (presence of 'value' key) could theoretically collide if a future condition type also has a value key — but the current API spec makes this unambiguous.
  • from_api() multi-fallback for the from key (from_value | from | _from) may silently accept malformed dicts; a stricter approach would raise KeyError on missing key.
  • The integration test modifies live workspace state (puts analytics model); the finally block restores, but a test runner crash could leave workspace in modified state.
Layers touched (3)
  • declarative_model — New file: CatalogDashboardCompoundComparisonCondition, CatalogDashboardCompoundRangeCondition, CatalogDashboardMeasureValueFilterBody, CatalogDashboardMeasureValueFilter
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/dashboard_filters.py
  • public_api — Added 5 new exports from dashboard_filters module
    • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • tests — Added test_dashboard_measure_value_filter integration test with VCR cassette
    • packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py

Source commits (gdc-nas)

  • bb0eead Merge pull request #22705 from gooddata/c.mze-cq-2280
  • e2ab6f2 Merge pull request #22850 from gooddata/c.mze-cq-2284
OpenAPI diff
@@ gooddata-automation-client.json (same pattern in export and metadata clients) @@
+      "DashboardCompoundComparisonCondition": {
+        "properties": { "comparison": { "operator": { "enum": ["GREATER_THAN","GREATER_THAN_OR_EQUAL_TO","LESS_THAN","LESS_THAN_OR_EQUAL_TO","EQUAL_TO","NOT_EQUAL_TO"] }, "value": { "format": "double" } } }
+      }
+      "DashboardCompoundConditionItem": { "oneOf": [ DashboardCompoundComparisonCondition, DashboardCompoundRangeCondition ] }
+      "DashboardCompoundRangeCondition": {
+        "properties": { "range": { "from", "operator": { "enum": ["BETWEEN","NOT_BETWEEN"] }, "to" } }
+      }
+      "DashboardMeasureValueFilter": {
+        "properties": { "dashboardMeasureValueFilter": { "conditions": [ DashboardCompoundConditionItem ], "localIdentifier", "measure", "title" } }
+      }
           DashboardFilter.oneOf:
+          { "$ref": "DashboardMeasureValueFilter" }

Workflow run


Generated by SDK OpenAPI Sync workflow

@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 76.54321% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.95%. Comparing base (12c8d84) to head (d869ec7).
⚠️ Report is 18 commits behind head on master.

Files with missing lines Patch % Lines
...del/workspace/analytics_model/dashboard_filters.py 76.25% 19 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1603      +/-   ##
==========================================
- Coverage   78.96%   78.95%   -0.02%     
==========================================
  Files         231      232       +1     
  Lines       15578    15659      +81     
==========================================
+ Hits        12301    12363      +62     
- Misses       3277     3296      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant