From 714ffabbd02f450d6b200e5af2f8a973cd0a3e95 Mon Sep 17 00:00:00 2001 From: Jan Kadlec Date: Fri, 21 Mar 2025 09:10:47 +0100 Subject: [PATCH] feat: add InlineFilter support to PythonSDK JIRA: F1-1181 risk: low --- gooddata-sdk/gooddata_sdk/__init__.py | 1 + .../gooddata_sdk/compute/model/filter.py | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/gooddata-sdk/gooddata_sdk/__init__.py b/gooddata-sdk/gooddata_sdk/__init__.py index 014062e9f..a902a5557 100644 --- a/gooddata-sdk/gooddata_sdk/__init__.py +++ b/gooddata-sdk/gooddata_sdk/__init__.py @@ -231,6 +231,7 @@ AllTimeFilter, AttributeFilter, Filter, + InlineFilter, MetricValueFilter, NegativeAttributeFilter, PositiveAttributeFilter, diff --git a/gooddata-sdk/gooddata_sdk/compute/model/filter.py b/gooddata-sdk/gooddata_sdk/compute/model/filter.py index edc40f4bc..3abe6d3d5 100644 --- a/gooddata-sdk/gooddata_sdk/compute/model/filter.py +++ b/gooddata-sdk/gooddata_sdk/compute/model/filter.py @@ -5,6 +5,8 @@ from importlib.util import find_spec from typing import Optional, Union +from gooddata_api_client.model.inline_filter_definition_inline import InlineFilterDefinitionInline + if find_spec("icu") is not None: from icu import Locale, SimpleDateFormat # type: ignore[import-not-found] @@ -503,3 +505,38 @@ def description(self, labels: dict[str, str], format_locale: Optional[str] = Non return ( f"{self.operator.capitalize()} {self.value}{dimensionality_str} {labels.get(metric_ids[0], metric_ids[0])}" ) + + +class InlineFilter(Filter): + """Filter using a custom MAQL expression. + + Automatically decides, whether to create or update. + + Args: + maql (str): The MAQL expression string that defines the filter condition. + + Example: + ```python + from gooddata_sdk import InlineFilter + from gooddata_pandas import GoodPandas + + gp = GoodPandas.create_from_profile() + factory = gp.data_frames("demo") + + filter_by = InlineFilter('{label/region} = "West"') + + factory.not_indexed(columns=dict(order_amount="metric/order_amount"), filter_by=filter_by) + ``` + """ + + def __init__(self, maql: str): + super().__init__() + + self.maql = maql + + def is_noop(self) -> bool: + return False + + def as_api_model(self) -> afm_models.InlineFilterDefinition: + body = InlineFilterDefinitionInline(self.maql) + return afm_models.InlineFilterDefinition(body, _check_type=False)