Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion google/ads/googleads/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ def _get_client_kwargs(cls, config_data: Dict[str, Any]) -> Dict[str, Any]:
"use_cloud_org_for_api_access": config_data.get(
"use_cloud_org_for_api_access"
),
"gaada": config_data.get("gaada"),
}

@classmethod
Expand Down Expand Up @@ -328,6 +329,7 @@ def __init__(
http_proxy: Union[str, None] = None,
use_proto_plus: bool = False,
use_cloud_org_for_api_access: Union[str, None] = None,
gaada: Union[str, None] = None,
):
"""Initializer for the GoogleAdsClient.

Expand All @@ -346,7 +348,8 @@ def __init__(
Google Cloud Organization of your Google Cloud project instead
of developer token to determine your Google Ads API access
levels. Use this flag only if you are enrolled into a limited
pilot that supports this configuration
pilot that supports this configuration.
gaada: a str specifying the Google Ads API Assistant version.
"""
if logging_config:
logging.config.dictConfig(logging_config)
Expand All @@ -363,6 +366,7 @@ def __init__(
use_cloud_org_for_api_access
)
self.enums: _EnumGetter = _EnumGetter(self)
self.gaada: Union[str, None] = gaada

# If given, write the http_proxy channel option for GRPC to use
if http_proxy:
Expand Down Expand Up @@ -442,12 +446,14 @@ def get_service(
self.login_customer_id,
self.linked_customer_id,
self.use_cloud_org_for_api_access,
gaada=self.gaada,
),
AsyncUnaryStreamMetadataInterceptor(
self.developer_token,
self.login_customer_id,
self.linked_customer_id,
self.use_cloud_org_for_api_access,
gaada=self.gaada,
),
AsyncUnaryUnaryLoggingInterceptor(_logger, version, endpoint),
AsyncUnaryStreamLoggingInterceptor(_logger, version, endpoint),
Expand Down Expand Up @@ -484,6 +490,7 @@ def get_service(
self.login_customer_id,
self.linked_customer_id,
self.use_cloud_org_for_api_access,
gaada=self.gaada,
),
LoggingInterceptor(_logger, version, endpoint),
ExceptionInterceptor(
Expand Down
3 changes: 2 additions & 1 deletion google/ads/googleads/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"linked_customer_id",
"http_proxy",
"use_cloud_org_for_api_access",
"use_application_default_credentials"
"use_application_default_credentials",
"gaada",
)
_CONFIG_FILE_PATH_KEY = ("configuration_file_path",)
_OAUTH2_INSTALLED_APP_KEYS = ("client_id", "client_secret", "refresh_token")
Expand Down
38 changes: 24 additions & 14 deletions google/ads/googleads/interceptors/metadata_interceptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(
login_customer_id: Optional[str]= None,
linked_customer_id: Optional[str] = None,
use_cloud_org_for_api_access: Optional[bool] = None,
gaada: Optional[str] = None,
):
"""Initialization method for this class.

Expand All @@ -72,6 +73,7 @@ def __init__(
of developer token to determine your Google Ads API access
levels. Use this flag only if you are enrolled into a limited
pilot that supports this configuration
gaada: a str specifying the Google Ads API Assistant version.
"""
self.developer_token_meta: Tuple[str, str] = (
"developer-token",
Expand All @@ -87,6 +89,7 @@ def __init__(
if linked_customer_id
else None
)
self.gaada: Optional[str] = gaada
self.use_cloud_org_for_api_access: Optional[
bool
] = use_cloud_org_for_api_access
Expand Down Expand Up @@ -152,21 +155,28 @@ def _intercept(
# fixed: https://github.com/googleapis/python-api-core/issues/416
for i, metadatum_tuple in enumerate(metadata):
# Check if the user agent header key is in the current metadatum
if "x-goog-api-client" in metadatum_tuple and _PROTOBUF_VERSION:
# Convert the tuple to a list so it can be modified.
if "x-goog-api-client" in metadatum_tuple:
metadatum: List[str] = list(metadatum_tuple)
# Check that "pb" isn't already included in the user agent.
if "pb" not in metadatum[1]:
# Append the protobuf version key value pair to the end of
# the string.
metadatum[1] += f" pb/{_PROTOBUF_VERSION}{_PB_IMPL_HEADER}"
# Convert the metadatum back to a tuple.
metadatum_tuple: Tuple[str, str] = tuple(metadatum)
# Splice the metadatum back in its original position in
# order to preserve the order of the metadata list.
metadata[i] = metadatum_tuple
# Exit the loop since we already found the user agent.
break

if self.gaada:
metadatum[1] += f" gaada/{self.gaada}"

if _PROTOBUF_VERSION:
# Convert the tuple to a list so it can be modified.
# Check that "pb" isn't already included in the user agent.
if "pb" not in metadatum[1]:
# Append the protobuf version key value pair to the end of
# the string.
metadatum[1] += f" pb/{_PROTOBUF_VERSION}{_PB_IMPL_HEADER}"
# Convert the metadatum back to a tuple.
metadatum_tuple: Tuple[str, str] = tuple(metadatum)

# Splice the metadatum back in its original position in
# order to preserve the order of the metadata list.
metadata[i] = metadatum_tuple
# Exit the loop since we already found the user agent.
break


client_call_details: grpc.ClientCallDetails = self._update_client_call_details_metadata(
client_call_details, metadata
Expand Down
21 changes: 21 additions & 0 deletions tests/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def test_get_client_kwargs_login_customer_id(self):
"linked_customer_id": self.linked_customer_id,
"http_proxy": None,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -147,6 +148,7 @@ def test_get_client_kwargs_login_customer_id_as_None(self):
"linked_customer_id": None,
"http_proxy": None,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -180,6 +182,7 @@ def test_get_client_kwargs_linked_customer_id(self):
"linked_customer_id": self.linked_customer_id,
"http_proxy": None,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -213,6 +216,7 @@ def test_get_client_kwargs_linked_customer_id_as_none(self):
"login_customer_id": None,
"http_proxy": None,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -246,6 +250,7 @@ def test_get_client_kwargs(self):
"linked_customer_id": None,
"http_proxy": self.http_proxy,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -280,6 +285,7 @@ def test_get_client_kwargs_custom_endpoint(self):
"linked_customer_id": None,
"http_proxy": None,
"use_cloud_org_for_api_access": None,
"gaada": None
},
)

Expand Down Expand Up @@ -316,6 +322,7 @@ def test_load_from_env(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_env_versioned(self):
Expand Down Expand Up @@ -351,6 +358,7 @@ def test_load_from_env_versioned(self):
version="v4",
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_dict(self):
Expand Down Expand Up @@ -384,6 +392,7 @@ def test_load_from_dict(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_dict_versioned(self):
Expand Down Expand Up @@ -417,6 +426,7 @@ def test_load_from_dict_versioned(self):
version="v4",
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_string(self):
Expand Down Expand Up @@ -450,6 +460,7 @@ def test_load_from_string(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_string_versioned(self):
Expand Down Expand Up @@ -485,6 +496,7 @@ def test_load_from_string_versioned(self):
version="v4",
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_get_service(self):
Expand Down Expand Up @@ -881,6 +893,7 @@ def test_load_http_proxy_from_env(self):
version=None,
http_proxy=self.http_proxy,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_http_proxy_from_dict(self):
Expand Down Expand Up @@ -915,6 +928,7 @@ def test_load_http_proxy_from_dict(self):
version=None,
http_proxy=self.http_proxy,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_http_proxy_from_string(self):
Expand Down Expand Up @@ -949,6 +963,7 @@ def test_load_http_proxy_from_string(self):
version=None,
http_proxy=self.http_proxy,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_client_info_package_not_found(self):
Expand Down Expand Up @@ -1017,6 +1032,7 @@ def test_load_http_proxy_from_storage(self):
version=None,
http_proxy=self.http_proxy,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_storage(self):
Expand Down Expand Up @@ -1058,6 +1074,7 @@ def test_load_from_storage(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_storage_versioned(self):
Expand Down Expand Up @@ -1099,6 +1116,7 @@ def test_load_from_storage_versioned(self):
version="v4",
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_storage_login_cid_int(self):
Expand Down Expand Up @@ -1142,6 +1160,7 @@ def test_load_from_storage_login_cid_int(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_storage_custom_path(self):
Expand Down Expand Up @@ -1177,6 +1196,7 @@ def test_load_from_storage_custom_path(self):
version=None,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)

def test_load_from_storage_file_not_found(self):
Expand Down Expand Up @@ -1239,4 +1259,5 @@ def test_load_from_storage_service_account_config(self):
version=latest_version,
http_proxy=None,
use_cloud_org_for_api_access=None,
gaada=None
)
40 changes: 40 additions & 0 deletions tests/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,17 @@ def test_load_from_dict_logging(self):
}
self.assertEqual(config.load_from_dict(config_data), config_data)

def test_load_from_dict_gaada(self):
"""Should load "gaada" config from dict."""
config_data = {
**self.default_dict_config,
**{
"gaada": "1.6.0",
},
}
result = config.load_from_dict(config_data)
self.assertEqual(result["gaada"], "1.6.0")

def test_load_from_dict_secondary_service_account_keys(self):
"""Should convert secondary keys to primary keys."""
config_data = {
Expand Down Expand Up @@ -664,6 +675,35 @@ def test_disambiguate_string_bool_raises_value_error(self):
def test_disambiguate_string_bool_raises_type_error(self):
self.assertRaises(TypeError, config.disambiguate_string_bool, {})

def test_load_from_env_gaada(self):
"""Should load ads api assistant flag from environment when specified"""
environ = {
**self.default_env_var_config,
**{
"GOOGLE_ADS_GAADA": "1.6.0",
},
}

with mock.patch("os.environ", environ):
results = config.load_from_env()
self.assertEqual(
results["gaada"],
"1.6.0",
)

def test_load_from_yaml_file_gaada(self):
"""Should load "gaada" config from a yaml."""
self._create_mock_yaml({"gaada": "1.6.0"})

result = config.load_from_yaml_file()
self.assertEqual(result["gaada"], "1.6.0")

def test_load_from_yaml_file_gaada_not_set(self):
"""Should set "gaada" as False when not set."""
self._create_mock_yaml({})
result = config.load_from_yaml_file()
self.assertEqual(result.get("gaada"), None)

def test_load_from_env_use_cloud_org_for_api_access(self):
"""Should load api access flag from environment when specified"""
environ = {
Expand Down