From 291a3b307fa3ba141715a00cf195c4a17a8609ae Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Thu, 15 Oct 2026 15:18:11 +0000 Subject: [PATCH] Regenerate client from commit ee653d2 of spec repo --- .generator/schemas/v2/openapi.yaml | 278 ++++++++++++++++++ examples/v2/feature-flags/GetSavedFilter.py | 18 ++ .../feature-flags/GetSavedFilter_375197246.py | 18 ++ .../v2/api/feature_flags_api.py | 45 +++ .../v2/model/saved_filter_attributes.py | 122 ++++++++ .../v2/model/saved_filter_condition.py | 59 ++++ .../model/saved_filter_condition_operator.py | 80 +++++ .../v2/model/saved_filter_creation_type.py | 38 +++ .../v2/model/saved_filter_data.py | 55 ++++ .../v2/model/saved_filter_data_type.py | 35 +++ .../v2/model/saved_filter_response.py | 40 +++ .../v2/model/saved_filter_targeting_rule.py | 47 +++ src/datadog_api_client/v2/models/__init__.py | 16 + .../test-runner-data/manifest.json | 21 ++ ...t-a-saved-filter-returns-a-saved-list.json | 35 +++ ...ved-filter-returns-not-found-response.json | 35 +++ ...et-a-saved-filter-returns-ok-response.json | 35 +++ .../test-server-data/v2/feature-flags.json | 93 ++++++ tests/v2/features/feature_flags.feature | 52 ++++ tests/v2/features/undo.json | 6 + 20 files changed, 1128 insertions(+) create mode 100644 examples/v2/feature-flags/GetSavedFilter.py create mode 100644 examples/v2/feature-flags/GetSavedFilter_375197246.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_attributes.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_condition.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_condition_operator.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_creation_type.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_data.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_data_type.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_response.py create mode 100644 src/datadog_api_client/v2/model/saved_filter_targeting_rule.py create mode 100644 tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-a-saved-list.json create mode 100644 tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-not-found-response.json create mode 100644 tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-ok-response.json diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index aa57375c89..8f408f146e 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -108555,6 +108555,181 @@ components: required: - data type: object + SavedFilterAttributes: + description: Saved filter details, including the full targeting rules and conditions. + properties: + archived_at: + description: The time the saved filter was archived. Omitted when the filter is not archived. + example: "2026-01-03T12:00:00Z" + format: date-time + type: string + created_at: + description: The time the saved filter was created. + example: "2026-01-01T12:00:00Z" + format: date-time + type: string + created_by: + description: The ID of the user who created the saved filter. + example: "550e8400-e29b-41d4-a716-446655440091" + type: string + creation_type: + $ref: "#/components/schemas/SavedFilterCreationType" + description: + description: A description of the saved filter. Omitted when no description is set. + example: Users selected by email address or organization ID. + type: string + migration_metadata: + description: Optional JSON metadata supplied by migration tools for tracking the source of a saved filter. + example: + provider: launchdarkly + segment_key: early-access-users + name: + description: The name of the saved filter. + example: Early access users + type: string + targeting_rules: + description: Targeting rules combined with OR. Conditions within each rule are combined with AND. Both saved lists and saved rules use this structure. + items: + $ref: "#/components/schemas/SavedFilterTargetingRule" + type: array + updated_at: + description: The time the saved filter was last updated. + example: "2026-01-02T12:00:00Z" + format: date-time + type: string + required: + - name + - creation_type + - targeting_rules + - created_by + - created_at + - updated_at + type: object + SavedFilterCondition: + description: An inline condition in a saved filter targeting rule. + properties: + attribute: + description: The attribute evaluated by the condition. + example: email + type: string + id: + description: The ID of the condition. + example: "550e8400-e29b-41d4-a716-446655440093" + format: uuid + type: string + operator: + $ref: "#/components/schemas/SavedFilterConditionOperator" + value: + description: Values used by the condition operator. + example: + - user@example.com + items: + type: string + type: array + required: + - id + - operator + - attribute + - value + type: object + SavedFilterConditionOperator: + description: The comparison operator used by a saved filter condition. + enum: + - LT + - LTE + - GT + - GTE + - MATCHES + - NOT_MATCHES + - ONE_OF + - NOT_ONE_OF + - IS_NULL + - EQUALS + - SEMVER_EQ + - SEMVER_NEQ + - SEMVER_LT + - SEMVER_LTE + - SEMVER_GT + - SEMVER_GTE + example: ONE_OF + type: string + x-enum-varnames: + - LT + - LTE + - GT + - GTE + - MATCHES + - NOT_MATCHES + - ONE_OF + - NOT_ONE_OF + - IS_NULL + - EQUALS + - SEMVER_EQ + - SEMVER_NEQ + - SEMVER_LT + - SEMVER_LTE + - SEMVER_GT + - SEMVER_GTE + SavedFilterCreationType: + description: How the saved filter was authored. RULES indicates rule-based authoring and LIST indicates list import. Both types return targeting rules and conditions. + enum: + - RULES + - LIST + example: RULES + type: string + x-enum-varnames: + - RULES + - LIST + SavedFilterData: + description: A saved filter resource. + properties: + attributes: + $ref: "#/components/schemas/SavedFilterAttributes" + id: + description: The ID of the saved filter. + example: "550e8400-e29b-41d4-a716-446655440090" + format: uuid + type: string + type: + $ref: "#/components/schemas/SavedFilterDataType" + required: + - id + - type + - attributes + type: object + SavedFilterDataType: + description: The saved filter resource type. + enum: + - saved-filters + example: saved-filters + type: string + x-enum-varnames: + - SAVED_FILTERS + SavedFilterResponse: + description: Response containing a saved filter and its targeting rules. + properties: + data: + $ref: "#/components/schemas/SavedFilterData" + required: + - data + type: object + SavedFilterTargetingRule: + description: A targeting rule in a saved filter. A rule matches when all its conditions match. + properties: + conditions: + description: Conditions combined with AND within this targeting rule. + items: + $ref: "#/components/schemas/SavedFilterCondition" + type: array + id: + description: The ID of the targeting rule. + example: "550e8400-e29b-41d4-a716-446655440092" + format: uuid + type: string + required: + - id + - conditions + type: object ScaRequest: description: The top-level request object for submitting a Software Composition Analysis (SCA) scan result. properties: @@ -171735,6 +171910,109 @@ paths: operator: AND permissions: - feature_flag_config_write + /api/v2/feature-flags/saved-filters/{saved_filter_id}: + get: + description: |- + Returns a saved filter by ID, including its full targeting rules, conditions, and values. + Supports both saved lists and saved rules. Targeting rules are combined with OR, + and conditions within each rule are combined with AND. + Returns the stored filter definition rather than evaluating it against users or organizations. + Archived filters can be retrieved. Filters that are deleted or belong to another organization return a not found error. + operationId: GetSavedFilter + parameters: + - description: The ID of the saved filter. + example: "550e8400-e29b-41d4-a716-446655440090" + in: path + name: saved_filter_id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + examples: + default: + summary: A saved rule matching an email address OR an organization ID + value: + data: + attributes: + created_at: "2026-01-01T12:00:00Z" + created_by: "550e8400-e29b-41d4-a716-446655440091" + creation_type: RULES + description: Users selected by email address or organization ID. + name: Early access users + targeting_rules: + - conditions: + - attribute: email + id: "550e8400-e29b-41d4-a716-446655440093" + operator: ONE_OF + value: ["user@example.com"] + id: "550e8400-e29b-41d4-a716-446655440092" + - conditions: + - attribute: org_id + id: "550e8400-e29b-41d4-a716-446655440095" + operator: ONE_OF + value: ["12345", "67890"] + id: "550e8400-e29b-41d4-a716-446655440094" + updated_at: "2026-01-02T12:00:00Z" + id: "550e8400-e29b-41d4-a716-446655440090" + type: saved-filters + saved_list: + summary: A saved list containing user IDs + value: + data: + attributes: + created_at: "2026-01-01T12:00:00Z" + created_by: "550e8400-e29b-41d4-a716-446655440091" + creation_type: LIST + name: Early access user list + targeting_rules: + - conditions: + - attribute: user_id + id: "550e8400-e29b-41d4-a716-446655440098" + operator: ONE_OF + value: ["user-123", "user-456"] + id: "550e8400-e29b-41d4-a716-446655440097" + updated_at: "2026-01-02T12:00:00Z" + id: "550e8400-e29b-41d4-a716-446655440096" + type: saved-filters + schema: + $ref: "#/components/schemas/SavedFilterResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - feature_flag_config_read + summary: Get a saved filter + tags: + - Feature Flags + x-permission: + operator: AND + permissions: + - feature_flag_config_read /api/v2/feature-flags/{feature_flag_id}: get: description: |- diff --git a/examples/v2/feature-flags/GetSavedFilter.py b/examples/v2/feature-flags/GetSavedFilter.py new file mode 100644 index 0000000000..7d9ee42bf8 --- /dev/null +++ b/examples/v2/feature-flags/GetSavedFilter.py @@ -0,0 +1,18 @@ +""" +Get a saved filter returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.feature_flags_api import FeatureFlagsApi +from uuid import UUID + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +with ApiClient(configuration) as api_client: + api_instance = FeatureFlagsApi(api_client) + response = api_instance.get_saved_filter( + saved_filter_id=UUID("8c051ac8-df7a-496e-b5c0-de691a411100"), + ) + + print(response) diff --git a/examples/v2/feature-flags/GetSavedFilter_375197246.py b/examples/v2/feature-flags/GetSavedFilter_375197246.py new file mode 100644 index 0000000000..39787e352c --- /dev/null +++ b/examples/v2/feature-flags/GetSavedFilter_375197246.py @@ -0,0 +1,18 @@ +""" +Get a saved filter returns a saved list +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.feature_flags_api import FeatureFlagsApi +from uuid import UUID + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +with ApiClient(configuration) as api_client: + api_instance = FeatureFlagsApi(api_client) + response = api_instance.get_saved_filter( + saved_filter_id=UUID("fb44ff15-fe17-4bab-afe8-9a8eb0cf586c"), + ) + + print(response) diff --git a/src/datadog_api_client/v2/api/feature_flags_api.py b/src/datadog_api_client/v2/api/feature_flags_api.py index 6badda60b4..9c199b319d 100644 --- a/src/datadog_api_client/v2/api/feature_flags_api.py +++ b/src/datadog_api_client/v2/api/feature_flags_api.py @@ -24,6 +24,7 @@ from datadog_api_client.v2.model.create_environment_request import CreateEnvironmentRequest from datadog_api_client.v2.model.update_environment_request import UpdateEnvironmentRequest from datadog_api_client.v2.model.allocation_exposure_schedule_response import AllocationExposureScheduleResponse +from datadog_api_client.v2.model.saved_filter_response import SavedFilterResponse from datadog_api_client.v2.model.update_feature_flag_request import UpdateFeatureFlagRequest from datadog_api_client.v2.model.allocation_response import AllocationResponse from datadog_api_client.v2.model.create_allocations_request import CreateAllocationsRequest @@ -321,6 +322,29 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._get_saved_filter_endpoint = _Endpoint( + settings={ + "response_type": (SavedFilterResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/feature-flags/saved-filters/{saved_filter_id}", + "operation_id": "get_saved_filter", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "saved_filter_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "saved_filter_id", + "location": "path", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._list_feature_flags_endpoint = _Endpoint( settings={ "response_type": (ListFeatureFlagsResponse,), @@ -946,6 +970,27 @@ def get_feature_flags_environment( return self._get_feature_flags_environment_endpoint.call_with_http_info(**kwargs) + def get_saved_filter( + self, + saved_filter_id: UUID, + ) -> SavedFilterResponse: + """Get a saved filter. + + Returns a saved filter by ID, including its full targeting rules, conditions, and values. + Supports both saved lists and saved rules. Targeting rules are combined with OR, + and conditions within each rule are combined with AND. + Returns the stored filter definition rather than evaluating it against users or organizations. + Archived filters can be retrieved. Filters that are deleted or belong to another organization return a not found error. + + :param saved_filter_id: The ID of the saved filter. + :type saved_filter_id: UUID + :rtype: SavedFilterResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["saved_filter_id"] = saved_filter_id + + return self._get_saved_filter_endpoint.call_with_http_info(**kwargs) + def list_feature_flags( self, *, diff --git a/src/datadog_api_client/v2/model/saved_filter_attributes.py b/src/datadog_api_client/v2/model/saved_filter_attributes.py new file mode 100644 index 0000000000..92faf09e5c --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_attributes.py @@ -0,0 +1,122 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import Any, List, Union, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + date, + datetime, + none_type, + unset, + UnsetType, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.saved_filter_creation_type import SavedFilterCreationType + from datadog_api_client.v2.model.saved_filter_targeting_rule import SavedFilterTargetingRule + + +class SavedFilterAttributes(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.saved_filter_creation_type import SavedFilterCreationType + from datadog_api_client.v2.model.saved_filter_targeting_rule import SavedFilterTargetingRule + + return { + "archived_at": (datetime,), + "created_at": (datetime,), + "created_by": (str,), + "creation_type": (SavedFilterCreationType,), + "description": (str,), + "migration_metadata": ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + UUID, + none_type, + ), + "name": (str,), + "targeting_rules": ([SavedFilterTargetingRule],), + "updated_at": (datetime,), + } + + attribute_map = { + "archived_at": "archived_at", + "created_at": "created_at", + "created_by": "created_by", + "creation_type": "creation_type", + "description": "description", + "migration_metadata": "migration_metadata", + "name": "name", + "targeting_rules": "targeting_rules", + "updated_at": "updated_at", + } + + def __init__( + self_, + created_at: datetime, + created_by: str, + creation_type: SavedFilterCreationType, + name: str, + targeting_rules: List[SavedFilterTargetingRule], + updated_at: datetime, + archived_at: Union[datetime, UnsetType] = unset, + description: Union[str, UnsetType] = unset, + migration_metadata: Union[Any, UnsetType] = unset, + **kwargs, + ): + """ + Saved filter details, including the full targeting rules and conditions. + + :param archived_at: The time the saved filter was archived. Omitted when the filter is not archived. + :type archived_at: datetime, optional + + :param created_at: The time the saved filter was created. + :type created_at: datetime + + :param created_by: The ID of the user who created the saved filter. + :type created_by: str + + :param creation_type: How the saved filter was authored. RULES indicates rule-based authoring and LIST indicates list import. Both types return targeting rules and conditions. + :type creation_type: SavedFilterCreationType + + :param description: A description of the saved filter. Omitted when no description is set. + :type description: str, optional + + :param migration_metadata: Optional JSON metadata supplied by migration tools for tracking the source of a saved filter. + :type migration_metadata: bool, date, datetime, dict, float, int, list, str, UUID, none_type, optional + + :param name: The name of the saved filter. + :type name: str + + :param targeting_rules: Targeting rules combined with OR. Conditions within each rule are combined with AND. Both saved lists and saved rules use this structure. + :type targeting_rules: [SavedFilterTargetingRule] + + :param updated_at: The time the saved filter was last updated. + :type updated_at: datetime + """ + if archived_at is not unset: + kwargs["archived_at"] = archived_at + if description is not unset: + kwargs["description"] = description + if migration_metadata is not unset: + kwargs["migration_metadata"] = migration_metadata + super().__init__(kwargs) + + self_.created_at = created_at + self_.created_by = created_by + self_.creation_type = creation_type + self_.name = name + self_.targeting_rules = targeting_rules + self_.updated_at = updated_at diff --git a/src/datadog_api_client/v2/model/saved_filter_condition.py b/src/datadog_api_client/v2/model/saved_filter_condition.py new file mode 100644 index 0000000000..9c34bb345c --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_condition.py @@ -0,0 +1,59 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import List, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.saved_filter_condition_operator import SavedFilterConditionOperator + + +class SavedFilterCondition(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.saved_filter_condition_operator import SavedFilterConditionOperator + + return { + "attribute": (str,), + "id": (UUID,), + "operator": (SavedFilterConditionOperator,), + "value": ([str],), + } + + attribute_map = { + "attribute": "attribute", + "id": "id", + "operator": "operator", + "value": "value", + } + + def __init__(self_, attribute: str, id: UUID, operator: SavedFilterConditionOperator, value: List[str], **kwargs): + """ + An inline condition in a saved filter targeting rule. + + :param attribute: The attribute evaluated by the condition. + :type attribute: str + + :param id: The ID of the condition. + :type id: UUID + + :param operator: The comparison operator used by a saved filter condition. + :type operator: SavedFilterConditionOperator + + :param value: Values used by the condition operator. + :type value: [str] + """ + super().__init__(kwargs) + + self_.attribute = attribute + self_.id = id + self_.operator = operator + self_.value = value diff --git a/src/datadog_api_client/v2/model/saved_filter_condition_operator.py b/src/datadog_api_client/v2/model/saved_filter_condition_operator.py new file mode 100644 index 0000000000..3c39c6c2d1 --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_condition_operator.py @@ -0,0 +1,80 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class SavedFilterConditionOperator(ModelSimple): + """ + The comparison operator used by a saved filter condition. + + :param value: Must be one of ["LT", "LTE", "GT", "GTE", "MATCHES", "NOT_MATCHES", "ONE_OF", "NOT_ONE_OF", "IS_NULL", "EQUALS", "SEMVER_EQ", "SEMVER_NEQ", "SEMVER_LT", "SEMVER_LTE", "SEMVER_GT", "SEMVER_GTE"]. + :type value: str + """ + + allowed_values = { + "LT", + "LTE", + "GT", + "GTE", + "MATCHES", + "NOT_MATCHES", + "ONE_OF", + "NOT_ONE_OF", + "IS_NULL", + "EQUALS", + "SEMVER_EQ", + "SEMVER_NEQ", + "SEMVER_LT", + "SEMVER_LTE", + "SEMVER_GT", + "SEMVER_GTE", + } + LT: ClassVar["SavedFilterConditionOperator"] + LTE: ClassVar["SavedFilterConditionOperator"] + GT: ClassVar["SavedFilterConditionOperator"] + GTE: ClassVar["SavedFilterConditionOperator"] + MATCHES: ClassVar["SavedFilterConditionOperator"] + NOT_MATCHES: ClassVar["SavedFilterConditionOperator"] + ONE_OF: ClassVar["SavedFilterConditionOperator"] + NOT_ONE_OF: ClassVar["SavedFilterConditionOperator"] + IS_NULL: ClassVar["SavedFilterConditionOperator"] + EQUALS: ClassVar["SavedFilterConditionOperator"] + SEMVER_EQ: ClassVar["SavedFilterConditionOperator"] + SEMVER_NEQ: ClassVar["SavedFilterConditionOperator"] + SEMVER_LT: ClassVar["SavedFilterConditionOperator"] + SEMVER_LTE: ClassVar["SavedFilterConditionOperator"] + SEMVER_GT: ClassVar["SavedFilterConditionOperator"] + SEMVER_GTE: ClassVar["SavedFilterConditionOperator"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +SavedFilterConditionOperator.LT = SavedFilterConditionOperator("LT") +SavedFilterConditionOperator.LTE = SavedFilterConditionOperator("LTE") +SavedFilterConditionOperator.GT = SavedFilterConditionOperator("GT") +SavedFilterConditionOperator.GTE = SavedFilterConditionOperator("GTE") +SavedFilterConditionOperator.MATCHES = SavedFilterConditionOperator("MATCHES") +SavedFilterConditionOperator.NOT_MATCHES = SavedFilterConditionOperator("NOT_MATCHES") +SavedFilterConditionOperator.ONE_OF = SavedFilterConditionOperator("ONE_OF") +SavedFilterConditionOperator.NOT_ONE_OF = SavedFilterConditionOperator("NOT_ONE_OF") +SavedFilterConditionOperator.IS_NULL = SavedFilterConditionOperator("IS_NULL") +SavedFilterConditionOperator.EQUALS = SavedFilterConditionOperator("EQUALS") +SavedFilterConditionOperator.SEMVER_EQ = SavedFilterConditionOperator("SEMVER_EQ") +SavedFilterConditionOperator.SEMVER_NEQ = SavedFilterConditionOperator("SEMVER_NEQ") +SavedFilterConditionOperator.SEMVER_LT = SavedFilterConditionOperator("SEMVER_LT") +SavedFilterConditionOperator.SEMVER_LTE = SavedFilterConditionOperator("SEMVER_LTE") +SavedFilterConditionOperator.SEMVER_GT = SavedFilterConditionOperator("SEMVER_GT") +SavedFilterConditionOperator.SEMVER_GTE = SavedFilterConditionOperator("SEMVER_GTE") diff --git a/src/datadog_api_client/v2/model/saved_filter_creation_type.py b/src/datadog_api_client/v2/model/saved_filter_creation_type.py new file mode 100644 index 0000000000..f6981362ac --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_creation_type.py @@ -0,0 +1,38 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class SavedFilterCreationType(ModelSimple): + """ + How the saved filter was authored. RULES indicates rule-based authoring and LIST indicates list import. Both types return targeting rules and conditions. + + :param value: Must be one of ["RULES", "LIST"]. + :type value: str + """ + + allowed_values = { + "RULES", + "LIST", + } + RULES: ClassVar["SavedFilterCreationType"] + LIST: ClassVar["SavedFilterCreationType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +SavedFilterCreationType.RULES = SavedFilterCreationType("RULES") +SavedFilterCreationType.LIST = SavedFilterCreationType("LIST") diff --git a/src/datadog_api_client/v2/model/saved_filter_data.py b/src/datadog_api_client/v2/model/saved_filter_data.py new file mode 100644 index 0000000000..8fd3f40a7e --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_data.py @@ -0,0 +1,55 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.saved_filter_attributes import SavedFilterAttributes + from datadog_api_client.v2.model.saved_filter_data_type import SavedFilterDataType + + +class SavedFilterData(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.saved_filter_attributes import SavedFilterAttributes + from datadog_api_client.v2.model.saved_filter_data_type import SavedFilterDataType + + return { + "attributes": (SavedFilterAttributes,), + "id": (UUID,), + "type": (SavedFilterDataType,), + } + + attribute_map = { + "attributes": "attributes", + "id": "id", + "type": "type", + } + + def __init__(self_, attributes: SavedFilterAttributes, id: UUID, type: SavedFilterDataType, **kwargs): + """ + A saved filter resource. + + :param attributes: Saved filter details, including the full targeting rules and conditions. + :type attributes: SavedFilterAttributes + + :param id: The ID of the saved filter. + :type id: UUID + + :param type: The saved filter resource type. + :type type: SavedFilterDataType + """ + super().__init__(kwargs) + + self_.attributes = attributes + self_.id = id + self_.type = type diff --git a/src/datadog_api_client/v2/model/saved_filter_data_type.py b/src/datadog_api_client/v2/model/saved_filter_data_type.py new file mode 100644 index 0000000000..e30dfcc1f0 --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_data_type.py @@ -0,0 +1,35 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class SavedFilterDataType(ModelSimple): + """ + The saved filter resource type. + + :param value: If omitted defaults to "saved-filters". Must be one of ["saved-filters"]. + :type value: str + """ + + allowed_values = { + "saved-filters", + } + SAVED_FILTERS: ClassVar["SavedFilterDataType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +SavedFilterDataType.SAVED_FILTERS = SavedFilterDataType("saved-filters") diff --git a/src/datadog_api_client/v2/model/saved_filter_response.py b/src/datadog_api_client/v2/model/saved_filter_response.py new file mode 100644 index 0000000000..d8f4c2feed --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_response.py @@ -0,0 +1,40 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.saved_filter_data import SavedFilterData + + +class SavedFilterResponse(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.saved_filter_data import SavedFilterData + + return { + "data": (SavedFilterData,), + } + + attribute_map = { + "data": "data", + } + + def __init__(self_, data: SavedFilterData, **kwargs): + """ + Response containing a saved filter and its targeting rules. + + :param data: A saved filter resource. + :type data: SavedFilterData + """ + super().__init__(kwargs) + + self_.data = data diff --git a/src/datadog_api_client/v2/model/saved_filter_targeting_rule.py b/src/datadog_api_client/v2/model/saved_filter_targeting_rule.py new file mode 100644 index 0000000000..57351fb021 --- /dev/null +++ b/src/datadog_api_client/v2/model/saved_filter_targeting_rule.py @@ -0,0 +1,47 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import List, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.saved_filter_condition import SavedFilterCondition + + +class SavedFilterTargetingRule(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.saved_filter_condition import SavedFilterCondition + + return { + "conditions": ([SavedFilterCondition],), + "id": (UUID,), + } + + attribute_map = { + "conditions": "conditions", + "id": "id", + } + + def __init__(self_, conditions: List[SavedFilterCondition], id: UUID, **kwargs): + """ + A targeting rule in a saved filter. A rule matches when all its conditions match. + + :param conditions: Conditions combined with AND within this targeting rule. + :type conditions: [SavedFilterCondition] + + :param id: The ID of the targeting rule. + :type id: UUID + """ + super().__init__(kwargs) + + self_.conditions = conditions + self_.id = id diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index fa746459af..740a7be6b5 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -9534,6 +9534,14 @@ from datadog_api_client.v2.model.sast_ruleset_data_attributes import SastRulesetDataAttributes from datadog_api_client.v2.model.sast_ruleset_response import SastRulesetResponse from datadog_api_client.v2.model.sast_rulesets_response import SastRulesetsResponse +from datadog_api_client.v2.model.saved_filter_attributes import SavedFilterAttributes +from datadog_api_client.v2.model.saved_filter_condition import SavedFilterCondition +from datadog_api_client.v2.model.saved_filter_condition_operator import SavedFilterConditionOperator +from datadog_api_client.v2.model.saved_filter_creation_type import SavedFilterCreationType +from datadog_api_client.v2.model.saved_filter_data import SavedFilterData +from datadog_api_client.v2.model.saved_filter_data_type import SavedFilterDataType +from datadog_api_client.v2.model.saved_filter_response import SavedFilterResponse +from datadog_api_client.v2.model.saved_filter_targeting_rule import SavedFilterTargetingRule from datadog_api_client.v2.model.sca_request import ScaRequest from datadog_api_client.v2.model.sca_request_data import ScaRequestData from datadog_api_client.v2.model.sca_request_data_attributes import ScaRequestDataAttributes @@ -19129,6 +19137,14 @@ "SastRulesetDataAttributes", "SastRulesetResponse", "SastRulesetsResponse", + "SavedFilterAttributes", + "SavedFilterCondition", + "SavedFilterConditionOperator", + "SavedFilterCreationType", + "SavedFilterData", + "SavedFilterDataType", + "SavedFilterResponse", + "SavedFilterTargetingRule", "ScaRequest", "ScaRequestData", "ScaRequestDataAttributes", diff --git a/tests/generated-test/test-runner-data/manifest.json b/tests/generated-test/test-runner-data/manifest.json index 26a5c0a691..ae6bce3fe3 100644 --- a/tests/generated-test/test-runner-data/manifest.json +++ b/tests/generated-test/test-runner-data/manifest.json @@ -5887,6 +5887,27 @@ "scenario": "Get a feature flag returns \"OK\" response", "version": "v2" }, + { + "feature": "Feature Flags", + "feature_file": "../../v2/features/feature_flags.feature", + "file": "v2/feature-flags/get-a-saved-filter-returns-not-found-response.json", + "scenario": "Get a saved filter returns \"Not Found\" response", + "version": "v2" + }, + { + "feature": "Feature Flags", + "feature_file": "../../v2/features/feature_flags.feature", + "file": "v2/feature-flags/get-a-saved-filter-returns-ok-response.json", + "scenario": "Get a saved filter returns \"OK\" response", + "version": "v2" + }, + { + "feature": "Feature Flags", + "feature_file": "../../v2/features/feature_flags.feature", + "file": "v2/feature-flags/get-a-saved-filter-returns-a-saved-list.json", + "scenario": "Get a saved filter returns a saved list", + "version": "v2" + }, { "feature": "Feature Flags", "feature_file": "../../v2/features/feature_flags.feature", diff --git a/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-a-saved-list.json b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-a-saved-list.json new file mode 100644 index 0000000000..65bd5577fa --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-a-saved-list.json @@ -0,0 +1,35 @@ +{ + "api": "FeatureFlags", + "expected_status": 200, + "feature": "Feature Flags", + "id": "v2/Feature Flags/Get a saved filter returns a saved list", + "operation_id": "GetSavedFilter", + "request": { + "body": null, + "content_type": null, + "method": "GET", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "saved_filter_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "type": "literal", + "value": "fb44ff15-fe17-4bab-afe8-9a8eb0cf586c" + }, + "style": null + } + ], + "path": "/api/v2/feature-flags/saved-filters/{saved_filter_id}" + }, + "scenario": "Get a saved filter returns a saved list", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-not-found-response.json b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-not-found-response.json new file mode 100644 index 0000000000..60bbac6839 --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-not-found-response.json @@ -0,0 +1,35 @@ +{ + "api": "FeatureFlags", + "expected_status": 404, + "feature": "Feature Flags", + "id": "v2/Feature Flags/Get a saved filter returns \"Not Found\" response", + "operation_id": "GetSavedFilter", + "request": { + "body": null, + "content_type": null, + "method": "GET", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "saved_filter_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "type": "literal", + "value": "00000000-0000-0000-0000-000000000000" + }, + "style": null + } + ], + "path": "/api/v2/feature-flags/saved-filters/{saved_filter_id}" + }, + "scenario": "Get a saved filter returns \"Not Found\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-ok-response.json b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-ok-response.json new file mode 100644 index 0000000000..2ac7d61445 --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/feature-flags/get-a-saved-filter-returns-ok-response.json @@ -0,0 +1,35 @@ +{ + "api": "FeatureFlags", + "expected_status": 200, + "feature": "Feature Flags", + "id": "v2/Feature Flags/Get a saved filter returns \"OK\" response", + "operation_id": "GetSavedFilter", + "request": { + "body": null, + "content_type": null, + "method": "GET", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "saved_filter_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "type": "literal", + "value": "8c051ac8-df7a-496e-b5c0-de691a411100" + }, + "style": null + } + ], + "path": "/api/v2/feature-flags/saved-filters/{saved_filter_id}" + }, + "scenario": "Get a saved filter returns \"OK\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-server-data/v2/feature-flags.json b/tests/generated-test/test-server-data/v2/feature-flags.json index 514cb75965..b843e1a2ed 100644 --- a/tests/generated-test/test-server-data/v2/feature-flags.json +++ b/tests/generated-test/test-server-data/v2/feature-flags.json @@ -538,6 +538,99 @@ "scenario": "Get a feature flag returns \"OK\" response", "version": "v2" }, + { + "feature": "Feature Flags", + "frozen_at": "2026-10-14T20:24:21.981Z", + "interactions": [ + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "GET", + "path": "/api/v2/feature-flags/saved-filters/00000000-0000-0000-0000-000000000000", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"saved filter not found: record not found\"}]}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Not Found", + "status": 404 + } + } + ], + "scenario": "Get a saved filter returns \"Not Found\" response", + "version": "v2" + }, + { + "feature": "Feature Flags", + "frozen_at": "2026-10-14T20:24:22.481Z", + "interactions": [ + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "GET", + "path": "/api/v2/feature-flags/saved-filters/8c051ac8-df7a-496e-b5c0-de691a411100", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"8c051ac8-df7a-496e-b5c0-de691a411100\",\"type\":\"saved-filters\",\"attributes\":{\"created_at\":\"2026-10-14T19:57:33Z\",\"created_by\":\"550e8400-e29b-41d4-a716-446655440091\",\"creation_type\":\"RULES\",\"description\":\"Synthetic fixture for OpenAPI tests\",\"name\":\"getSavedFilterTest-Rule\",\"targeting_rules\":[{\"id\":\"204d53d3-9913-485f-af8e-8a8b4b34a4cb\",\"conditions\":[{\"id\":\"e12773d9-27ec-4009-88ab-6654227138c3\",\"operator\":\"ONE_OF\",\"attribute\":\"email\",\"value\":[\"test@example.com\"]}]},{\"id\":\"286b13f5-2b57-42a6-9dd6-555e46332591\",\"conditions\":[{\"id\":\"17367bb6-18cb-4e92-b126-2f1591ab3582\",\"operator\":\"ONE_OF\",\"attribute\":\"org_id\",\"value\":[\"test-org-1\"]}]}],\"updated_at\":\"2026-10-14T19:57:33Z\"}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + } + ], + "scenario": "Get a saved filter returns \"OK\" response", + "version": "v2" + }, + { + "feature": "Feature Flags", + "frozen_at": "2026-10-14T20:24:22.277Z", + "interactions": [ + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "GET", + "path": "/api/v2/feature-flags/saved-filters/fb44ff15-fe17-4bab-afe8-9a8eb0cf586c", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"fb44ff15-fe17-4bab-afe8-9a8eb0cf586c\",\"type\":\"saved-filters\",\"attributes\":{\"created_at\":\"2026-10-14T20:06:17Z\",\"created_by\":\"550e8400-e29b-41d4-a716-446655440091\",\"creation_type\":\"LIST\",\"description\":\"Synthetic fixture for OpenAPI tests\",\"name\":\"getSavedFilterTest-list\",\"targeting_rules\":[{\"id\":\"bb656152-2e92-43bc-a30a-b0bd9187c2ec\",\"conditions\":[{\"id\":\"6b2127a4-a463-4069-baa8-4950f11c6605\",\"operator\":\"ONE_OF\",\"attribute\":\"user_id\",\"value\":[\"test-user-1\",\"test-user-2\"]}]}],\"updated_at\":\"2026-10-14T20:06:17Z\"}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + } + ], + "scenario": "Get a saved filter returns a saved list", + "version": "v2" + }, { "feature": "Feature Flags", "frozen_at": "2026-10-13T16:23:05.377Z", diff --git a/tests/v2/features/feature_flags.feature b/tests/v2/features/feature_flags.feature index 6f67ab23a0..b298d717c2 100644 --- a/tests/v2/features/feature_flags.feature +++ b/tests/v2/features/feature_flags.feature @@ -287,6 +287,58 @@ Feature: Feature Flags And the response "data.attributes.name" has the same value as "feature_flag.data.attributes.name" And the response "data.attributes.value_type" has the same value as "feature_flag.data.attributes.value_type" + @generated @skip @team:ddoghq/feature-flags + Scenario: Get a saved filter returns "Bad Request" response + Given new "GetSavedFilter" request + And request contains "saved_filter_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @team:ddoghq/feature-flags + Scenario: Get a saved filter returns "Not Found" response + Given new "GetSavedFilter" request + And request contains "saved_filter_id" parameter with value "00000000-0000-0000-0000-000000000000" + When the request is sent + Then the response status is 404 Not Found + + @replay-only @team:ddoghq/feature-flags + Scenario: Get a saved filter returns "OK" response + Given new "GetSavedFilter" request + And request contains "saved_filter_id" parameter with value "8c051ac8-df7a-496e-b5c0-de691a411100" + When the request is sent + Then the response status is 200 OK + And the response "data.id" is equal to "8c051ac8-df7a-496e-b5c0-de691a411100" + And the response "data.type" is equal to "saved-filters" + And the response "data.attributes.creation_type" is equal to "RULES" + And the response "data.attributes.name" is equal to "getSavedFilterTest-Rule" + And the response "data.attributes.description" is equal to "Synthetic fixture for OpenAPI tests" + And the response "data.attributes.targeting_rules" has length 2 + And the response "data.attributes.targeting_rules[0].conditions" has length 1 + And the response "data.attributes.targeting_rules[0].conditions[0].attribute" is equal to "email" + And the response "data.attributes.targeting_rules[0].conditions[0].operator" is equal to "ONE_OF" + And the response "data.attributes.targeting_rules[0].conditions[0].value" is equal to ["test@example.com"] + And the response "data.attributes.targeting_rules[1].conditions" has length 1 + And the response "data.attributes.targeting_rules[1].conditions[0].attribute" is equal to "org_id" + And the response "data.attributes.targeting_rules[1].conditions[0].operator" is equal to "ONE_OF" + And the response "data.attributes.targeting_rules[1].conditions[0].value" is equal to ["test-org-1"] + + @replay-only @team:ddoghq/feature-flags + Scenario: Get a saved filter returns a saved list + Given new "GetSavedFilter" request + And request contains "saved_filter_id" parameter with value "fb44ff15-fe17-4bab-afe8-9a8eb0cf586c" + When the request is sent + Then the response status is 200 OK + And the response "data.id" is equal to "fb44ff15-fe17-4bab-afe8-9a8eb0cf586c" + And the response "data.type" is equal to "saved-filters" + And the response "data.attributes.creation_type" is equal to "LIST" + And the response "data.attributes.name" is equal to "getSavedFilterTest-list" + And the response "data.attributes.description" is equal to "Synthetic fixture for OpenAPI tests" + And the response "data.attributes.targeting_rules" has length 1 + And the response "data.attributes.targeting_rules[0].conditions" has length 1 + And the response "data.attributes.targeting_rules[0].conditions[0].attribute" is equal to "user_id" + And the response "data.attributes.targeting_rules[0].conditions[0].operator" is equal to "ONE_OF" + And the response "data.attributes.targeting_rules[0].conditions[0].value" is equal to ["test-user-1", "test-user-2"] + @skip @team:ddoghq/feature-flags Scenario: Get an environment returns "Not Found" response Given new "GetFeatureFlagsEnvironment" request diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index 68ab96be66..aad409ef63 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -3251,6 +3251,12 @@ "type": "idempotent" } }, + "GetSavedFilter": { + "tag": "Feature Flags", + "undo": { + "type": "safe" + } + }, "GetFeatureFlag": { "tag": "Feature Flags", "undo": {