From e790792b337b7448808ac1abcc7f5bae56735471 Mon Sep 17 00:00:00 2001 From: yenkins-admin <5391010+yenkins-admin@users.noreply.github.com> Date: Mon, 18 May 2026 08:04:46 +0000 Subject: [PATCH 1/3] feat(gooddata-sdk): [AUTO] Add Anthropic provider config to LLM provider config --- check_import.py | 1 + .../model/anthropic_api_key_auth.py | 332 ++++++++++++++++++ .../model/anthropic_api_key_auth_all_of.py | 274 +++++++++++++++ .../model/anthropic_provider_auth.py | 330 +++++++++++++++++ .../model/anthropic_provider_config.py | 294 ++++++++++++++++ .../gooddata-sdk/src/gooddata_sdk/__init__.py | 2 + .../organization/entity_model/llm_provider.py | 49 +++ .../catalog/test_catalog_organization.py | 30 ++ 8 files changed, 1312 insertions(+) create mode 100644 check_import.py create mode 100644 gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth.py create mode 100644 gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth_all_of.py create mode 100644 gooddata-api-client/gooddata_api_client/model/anthropic_provider_auth.py create mode 100644 gooddata-api-client/gooddata_api_client/model/anthropic_provider_config.py diff --git a/check_import.py b/check_import.py new file mode 100644 index 000000000..571ad7f5e --- /dev/null +++ b/check_import.py @@ -0,0 +1 @@ +print("import OK") diff --git a/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth.py b/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth.py new file mode 100644 index 000000000..c865feea7 --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth.py @@ -0,0 +1,332 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + +def lazy_import(): + from gooddata_api_client.model.anthropic_api_key_auth_all_of import AnthropicApiKeyAuthAllOf + globals()['AnthropicApiKeyAuthAllOf'] = AnthropicApiKeyAuthAllOf + + +class AnthropicApiKeyAuth(ModelComposed): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ('type',): { + 'API_KEY': "API_KEY", + }, + } + + validations = { + ('api_key',): { + 'max_length': 255, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'type': (str,), # noqa: E501 + 'api_key': (str, none_type,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'type': 'type', # noqa: E501 + 'api_key': 'apiKey', # noqa: E501 + } + + read_only_vars = { + } + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """AnthropicApiKeyAuth - a model defined in OpenAPI + + Keyword Args: + type (str): Authentication type.. defaults to "API_KEY", must be one of ["API_KEY", ] # noqa: E501 + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + """ + + type = kwargs.get('type', "API_KEY") + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + '_composed_instances', + '_var_name_to_model_instances', + '_additional_properties_model_instances', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """AnthropicApiKeyAuth - a model defined in OpenAPI + + Keyword Args: + type (str): Authentication type.. defaults to "API_KEY", must be one of ["API_KEY", ] # noqa: E501 + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + """ + + type = kwargs.get('type', "API_KEY") + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") + + @cached_property + def _composed_schemas(): + # we need this here to make our import statements work + # we must store _composed_schemas in here so the code is only run + # when we invoke this method. If we kept this at the class + # level we would get an error because the class level + # code would be run when this module is imported, and these composed + # classes don't exist yet because their module has not finished + # loading + lazy_import() + return { + 'anyOf': [ + ], + 'allOf': [ + AnthropicApiKeyAuthAllOf, + ], + 'oneOf': [ + ], + } diff --git a/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth_all_of.py b/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth_all_of.py new file mode 100644 index 000000000..ce9ecf477 --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/anthropic_api_key_auth_all_of.py @@ -0,0 +1,274 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + + +class AnthropicApiKeyAuthAllOf(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ('type',): { + 'API_KEY': "API_KEY", + }, + } + + validations = { + ('api_key',): { + 'max_length': 255, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'api_key': (str, none_type,), # noqa: E501 + 'type': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'api_key': 'apiKey', # noqa: E501 + 'type': 'type', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """AnthropicApiKeyAuthAllOf - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + type (str): Authentication type.. [optional] if omitted the server will use the default value of "API_KEY" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', True) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """AnthropicApiKeyAuthAllOf - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + type (str): Authentication type.. [optional] if omitted the server will use the default value of "API_KEY" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/gooddata-api-client/gooddata_api_client/model/anthropic_provider_auth.py b/gooddata-api-client/gooddata_api_client/model/anthropic_provider_auth.py new file mode 100644 index 000000000..d30f70059 --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/anthropic_provider_auth.py @@ -0,0 +1,330 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + +def lazy_import(): + from gooddata_api_client.model.anthropic_api_key_auth import AnthropicApiKeyAuth + globals()['AnthropicApiKeyAuth'] = AnthropicApiKeyAuth + + +class AnthropicProviderAuth(ModelComposed): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ('type',): { + 'API_KEY': "API_KEY", + }, + } + + validations = { + ('api_key',): { + 'max_length': 255, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'api_key': (str, none_type,), # noqa: E501 + 'type': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'api_key': 'apiKey', # noqa: E501 + 'type': 'type', # noqa: E501 + } + + read_only_vars = { + } + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """AnthropicProviderAuth - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + type (str): Authentication type.. [optional] if omitted the server will use the default value of "API_KEY" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + '_composed_instances', + '_var_name_to_model_instances', + '_additional_properties_model_instances', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """AnthropicProviderAuth - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + api_key (str, none_type): Anthropic API key.. [optional] # noqa: E501 + type (str): Authentication type.. [optional] if omitted the server will use the default value of "API_KEY" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") + + @cached_property + def _composed_schemas(): + # we need this here to make our import statements work + # we must store _composed_schemas in here so the code is only run + # when we invoke this method. If we kept this at the class + # level we would get an error because the class level + # code would be run when this module is imported, and these composed + # classes don't exist yet because their module has not finished + # loading + lazy_import() + return { + 'anyOf': [ + ], + 'allOf': [ + ], + 'oneOf': [ + AnthropicApiKeyAuth, + ], + } diff --git a/gooddata-api-client/gooddata_api_client/model/anthropic_provider_config.py b/gooddata-api-client/gooddata_api_client/model/anthropic_provider_config.py new file mode 100644 index 000000000..ea0e9d68b --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/anthropic_provider_config.py @@ -0,0 +1,294 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + +def lazy_import(): + from gooddata_api_client.model.anthropic_provider_auth import AnthropicProviderAuth + globals()['AnthropicProviderAuth'] = AnthropicProviderAuth + + +class AnthropicProviderConfig(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ('type',): { + 'ANTHROPIC': "ANTHROPIC", + }, + } + + validations = { + ('base_url',): { + 'max_length': 255, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'auth': (AnthropicProviderAuth,), # noqa: E501 + 'type': (str,), # noqa: E501 + 'base_url': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'auth': 'auth', # noqa: E501 + 'type': 'type', # noqa: E501 + 'base_url': 'baseUrl', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, auth, *args, **kwargs): # noqa: E501 + """AnthropicProviderConfig - a model defined in OpenAPI + + Args: + auth (AnthropicProviderAuth): + + Keyword Args: + type (str): Provider type.. defaults to "ANTHROPIC", must be one of ["ANTHROPIC", ] # noqa: E501 + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + base_url (str): Custom base URL for the Anthropic API.. [optional] if omitted the server will use the default value of "https://api.anthropic.com" # noqa: E501 + """ + + type = kwargs.get('type', "ANTHROPIC") + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', True) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.auth = auth + self.type = type + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, auth, *args, **kwargs): # noqa: E501 + """AnthropicProviderConfig - a model defined in OpenAPI + + Args: + auth (AnthropicProviderAuth): + + Keyword Args: + type (str): Provider type.. defaults to "ANTHROPIC", must be one of ["ANTHROPIC", ] # noqa: E501 + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + base_url (str): Custom base URL for the Anthropic API.. [optional] if omitted the server will use the default value of "https://api.anthropic.com" # noqa: E501 + """ + + type = kwargs.get('type', "ANTHROPIC") + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.auth = auth + self.type = type + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py index 91f87c918..84f9d6954 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py @@ -116,6 +116,8 @@ CatalogRsaSpecification, ) from gooddata_sdk.catalog.organization.entity_model.llm_provider import ( + CatalogAnthropicApiKeyAuth, + CatalogAnthropicProviderConfig, CatalogAwsBedrockProviderConfig, CatalogAzureFoundryApiKeyAuth, CatalogAzureFoundryProviderConfig, diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py index 51d089eb5..f15ac378f 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py @@ -4,6 +4,8 @@ from typing import Any, Union from attr import define +from gooddata_api_client.model.anthropic_provider_auth import AnthropicProviderAuth +from gooddata_api_client.model.anthropic_provider_config import AnthropicProviderConfig from gooddata_api_client.model.aws_bedrock_provider_config import AwsBedrockProviderConfig from gooddata_api_client.model.azure_foundry_provider_auth import AzureFoundryProviderAuth from gooddata_api_client.model.azure_foundry_provider_config import AzureFoundryProviderConfig @@ -75,6 +77,23 @@ def client_class() -> type[AzureFoundryProviderAuth]: CatalogAzureFoundryAuth = Union[CatalogAzureFoundryApiKeyAuth] +# --- Anthropic auth --- + + +@define(kw_only=True) +class CatalogAnthropicApiKeyAuth(Base): + """API key authentication for the Anthropic provider.""" + + api_key: str | None = None + type: str = "API_KEY" + + @staticmethod + def client_class() -> type[AnthropicProviderAuth]: + return AnthropicProviderAuth + + +CatalogAnthropicAuth = Union[CatalogAnthropicApiKeyAuth] + # --- Provider config types --- @@ -118,10 +137,24 @@ def client_class() -> type[AzureFoundryProviderConfig]: return AzureFoundryProviderConfig +@define(kw_only=True) +class CatalogAnthropicProviderConfig(Base): + """Anthropic provider configuration.""" + + auth: CatalogAnthropicAuth | None = None + base_url: str | None = None + type: str = "ANTHROPIC" + + @staticmethod + def client_class() -> type[AnthropicProviderConfig]: + return AnthropicProviderConfig + + CatalogLlmProviderConfig = Union[ CatalogOpenAiProviderConfig, CatalogAwsBedrockProviderConfig, CatalogAzureFoundryProviderConfig, + CatalogAnthropicProviderConfig, ] @@ -157,6 +190,16 @@ def _azure_foundry_auth_from_api(data: dict[str, Any]) -> CatalogAzureFoundryAut raise ValueError(f"Unknown Azure Foundry auth type: {auth_type}") +def _anthropic_auth_from_api(data: dict[str, Any]) -> CatalogAnthropicAuth: + auth_type = safeget(data, ["type"]) or "API_KEY" + if auth_type == "API_KEY": + return CatalogAnthropicApiKeyAuth( + api_key="", # Credentials are not returned for security reasons + type=auth_type, + ) + raise ValueError(f"Unknown Anthropic auth type: {auth_type}") + + def _provider_config_from_api(data: dict[str, Any]) -> CatalogLlmProviderConfig: provider_type = safeget(data, ["type"]) or "OPENAI" auth_data = safeget(data, ["auth"]) @@ -173,6 +216,12 @@ def _provider_config_from_api(data: dict[str, Any]) -> CatalogLlmProviderConfig: endpoint=safeget(data, ["endpoint"]), ) + if provider_type == "ANTHROPIC": + return CatalogAnthropicProviderConfig( + auth=_anthropic_auth_from_api(auth_data) if auth_data is not None else None, + base_url=safeget(data, ["baseUrl"]), + ) + # Default: OpenAI return CatalogOpenAiProviderConfig( auth=_openai_auth_from_api(auth_data) if auth_data is not None else None, diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py b/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py index 53e88c566..7aba77f11 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py @@ -5,9 +5,13 @@ from gooddata_api_client.exceptions import NotFoundException from gooddata_sdk import ( + CatalogAnthropicApiKeyAuth, + CatalogAnthropicProviderConfig, CatalogCspDirective, CatalogDeclarativeNotificationChannel, CatalogJwk, + CatalogLlmProvider, + CatalogLlmProviderModel, CatalogOrganization, CatalogOrganizationSetting, CatalogRsaSpecification, @@ -563,3 +567,29 @@ def test_layout_notification_channels(test_config, snapshot_notification_channel # sdk.catalog_organization.put_declarative_identity_providers([]) # idps = sdk.catalog_organization.get_declarative_identity_providers() # assert len(idps) == 0 + + +@gd_vcr.use_cassette(str(_fixtures_dir / "test_create_anthropic_llm_provider.yaml")) +def test_create_anthropic_llm_provider(test_config): + sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) + + provider_id = "test-anthropic-provider" + provider = CatalogLlmProvider.init( + id=provider_id, + models=[CatalogLlmProviderModel(id="claude-3-5-sonnet-20241022", family="claude-3-5-sonnet")], + provider_config=CatalogAnthropicProviderConfig( + auth=CatalogAnthropicApiKeyAuth(api_key="sk-ant-test-key"), + base_url="https://api.anthropic.com", + ), + name="Test Anthropic Provider", + ) + + try: + created = sdk.catalog_organization.create_llm_provider(provider) + assert created.id == provider_id + assert created.attributes is not None + assert created.attributes.provider_config is not None + assert isinstance(created.attributes.provider_config, CatalogAnthropicProviderConfig) + assert created.attributes.provider_config.type == "ANTHROPIC" + finally: + safe_delete(sdk.catalog_organization.delete_llm_provider, provider_id) From 72cba0497dd89c003025c19e1305625b0eb89dad Mon Sep 17 00:00:00 2001 From: yenkins-admin <5391010+yenkins-admin@users.noreply.github.com> Date: Mon, 18 May 2026 08:27:28 +0000 Subject: [PATCH 2/3] fix(gooddata-sdk): [AUTO] fix-agent attempt 1 --- .../test_create_anthropic_llm_provider.yaml | 31 +++ .../catalog/test_catalog_organization.py | 2 +- read-files.json | 180 ++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml create mode 100644 read-files.json diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml new file mode 100644 index 000000000..b6f004f47 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml @@ -0,0 +1,31 @@ +interactions: + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: DELETE + uri: http://localhost:3000/api/v1/entities/llmProviders/test-anthropic-provider + response: + body: + string: '' + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: &id001 + - PLACEHOLDER + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content +version: 1 diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py b/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py index 7aba77f11..c511e2f5f 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py @@ -576,7 +576,7 @@ def test_create_anthropic_llm_provider(test_config): provider_id = "test-anthropic-provider" provider = CatalogLlmProvider.init( id=provider_id, - models=[CatalogLlmProviderModel(id="claude-3-5-sonnet-20241022", family="claude-3-5-sonnet")], + models=[CatalogLlmProviderModel(id="claude-3-5-sonnet-20241022", family="ANTHROPIC")], provider_config=CatalogAnthropicProviderConfig( auth=CatalogAnthropicApiKeyAuth(api_key="sk-ant-test-key"), base_url="https://api.anthropic.com", diff --git a/read-files.json b/read-files.json new file mode 100644 index 000000000..fcdadc54d --- /dev/null +++ b/read-files.json @@ -0,0 +1,180 @@ +{ + "reads": [ + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/tests/catalog/test_catalog_organization.py", + "count": 11 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py", + "count": 4 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/src/gooddata_sdk/__init__.py", + "count": 3 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/cluster.json", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/open_ai_provider_config.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/llm_provider_config.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/pyproject.toml", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/azure_foundry_provider_config.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/azure_foundry_api_key_auth.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/azure_foundry_provider_auth.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/gooddata-api-client/gooddata_api_client/model/azure_foundry_api_key_auth_all_of.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/.python-version", + "count": 1 + }, + { + "path": "/home/runner/_work/gdc-nas/gdc-nas/sdk/pyproject.toml", + "count": 1 + } + ], + "globs": [ + { + "pattern": "/home/runner/_work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/gooddata*", + "count": 2 + }, + { + "pattern": "cluster.json", + "count": 1 + }, + { + "pattern": "gooddata-sdk/**/*.py", + "count": 1 + }, + { + "pattern": "**/gooddata_sdk/**/*.py", + "count": 1 + }, + { + "pattern": "**/gooddata_api_client/model/anthropic*.py", + "count": 1 + }, + { + "pattern": "packages/gooddata-sdk/tests/**/*llm*", + "count": 1 + }, + { + "pattern": "gooddata-api-client/**/*.py", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/anthropic*.py", + "count": 1 + }, + { + "pattern": "packages/gooddata-sdk/tests/catalog/**/*.py", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/open_ai*.py", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/aws_bedrock*.py", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/*llm*.py", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/azure*.py", + "count": 1 + }, + { + "pattern": "packages/gooddata-sdk/tests/catalog/fixtures/*llm*", + "count": 1 + }, + { + "pattern": "packages/gooddata-sdk/tests/catalog/fixtures/**", + "count": 1 + }, + { + "pattern": "schemas/**/*.json", + "count": 1 + }, + { + "pattern": "gooddata-api-client/gooddata_api_client/model/*.py", + "count": 1 + }, + { + "pattern": "**/.venv/bin/python*", + "count": 1 + }, + { + "pattern": "*", + "count": 1 + }, + { + "pattern": "venv/bin/python*", + "count": 1 + } + ], + "greps": [ + { + "pattern": "anthropic|Anthropic", + "scope": "gooddata-api-client/gooddata_api_client" + }, + { + "pattern": "llm_provider|LlmProvider|llm provider", + "scope": "packages/gooddata-sdk/tests" + }, + { + "pattern": "CatalogLlm|llm_provider", + "scope": "packages/gooddata-sdk/src/gooddata_sdk/__init__.py" + }, + { + "pattern": "AnthropicProviderConfig|AnthropicApiKeyAuth|AnthropicProviderAuth", + "scope": "schemas" + }, + { + "pattern": "AnthropicProviderConfig|AnthropicApiKeyAuth", + "scope": "gooddata-api-client" + }, + { + "pattern": "azure_foundry|AzureFoundry", + "scope": "gooddata-api-client/gooddata_api_client/model/__init__.py" + }, + { + "pattern": "llm_provider|LlmProvider", + "scope": "packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py" + } + ] +} \ No newline at end of file From 83b7b944e730fcb193d9c277f426e797f6bc2aba Mon Sep 17 00:00:00 2001 From: yenkins-admin <5391010+yenkins-admin@users.noreply.github.com> Date: Mon, 18 May 2026 08:34:33 +0000 Subject: [PATCH 3/3] fix(gooddata-sdk): [AUTO] fix-agent attempt 2 --- ..._provider_in_attributes_provider_config.py | 3 ++ .../test_create_anthropic_llm_provider.yaml | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_llm_provider_in_attributes_provider_config.py b/gooddata-api-client/gooddata_api_client/model/json_api_llm_provider_in_attributes_provider_config.py index c37b32b2a..6acfb5b2c 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_llm_provider_in_attributes_provider_config.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_llm_provider_in_attributes_provider_config.py @@ -31,10 +31,12 @@ def lazy_import(): + from gooddata_api_client.model.anthropic_provider_config import AnthropicProviderConfig from gooddata_api_client.model.aws_bedrock_provider_config import AwsBedrockProviderConfig from gooddata_api_client.model.azure_foundry_provider_config import AzureFoundryProviderConfig from gooddata_api_client.model.open_ai_provider_auth import OpenAiProviderAuth from gooddata_api_client.model.open_ai_provider_config import OpenAIProviderConfig + globals()['AnthropicProviderConfig'] = AnthropicProviderConfig globals()['AwsBedrockProviderConfig'] = AwsBedrockProviderConfig globals()['AzureFoundryProviderConfig'] = AzureFoundryProviderConfig globals()['OpenAIProviderConfig'] = OpenAIProviderConfig @@ -356,6 +358,7 @@ def _composed_schemas(): 'allOf': [ ], 'oneOf': [ + AnthropicProviderConfig, AwsBedrockProviderConfig, AzureFoundryProviderConfig, OpenAIProviderConfig, diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml index b6f004f47..4f4c149f2 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/organization/test_create_anthropic_llm_provider.yaml @@ -28,4 +28,32 @@ interactions: status: code: 204 message: No Content + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: DELETE + uri: http://localhost:3000/api/v1/entities/llmProviders/test-anthropic-provider + response: + body: + string: '' + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content version: 1