Skip to content

Commit

Permalink
feat: add api key support (#969)
Browse files Browse the repository at this point in the history
* feat: add api key support

* chore: update integration tests
  • Loading branch information
arithmetic1728 authored Jan 19, 2022
1 parent 9b66c72 commit 7c72739
Show file tree
Hide file tree
Showing 14 changed files with 403 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,16 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, {{ service.name }}Transport):
# transport is a {{ service.name }}Transport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -324,6 +328,11 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,27 @@ def test_credentials_transport_error():
client_options={"credentials_file": "credentials.json"},
transport=transport,
)

# It is an error to provide an api_key and a transport instance.
transport = transports.{{ service.name }}{{ opts.transport[0].capitalize() }}Transport(
credentials=ga_credentials.AnonymousCredentials(),
)
options = client_options.ClientOptions()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = {{ service.client_name }}(
client_options=options,
transport=transport,
)

# It is an error to provide an api_key and a credential.
options = mock.Mock()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = {{ service.client_name }}(
client_options=options,
credentials=ga_credentials.AnonymousCredentials()
)

# It is an error to provide scopes and a transport instance.
transport = transports.{{ service.name }}{{ opts.transport[0].capitalize() }}Transport(
Expand Down Expand Up @@ -2897,4 +2918,34 @@ def test_client_ctx():
pass
close.assert_called()

@pytest.mark.parametrize("client_class,transport_class", [
{% if 'grpc' in opts.transport %}
({{ service.client_name }}, transports.{{ service.grpc_transport_name }}),
({{ service.async_client_name }}, transports.{{ service.grpc_asyncio_transport_name }}),
{% elif 'rest' in opts.transport %}
({{ service.client_name }}, transports.{{ service.rest_transport_name }}),
{% endif %}
])
def test_api_key_credentials(client_class, transport_class):
with mock.patch.object(
google.auth._default, "get_api_key_credentials", create=True
) as get_api_key_credentials:
mock_cred = mock.Mock()
get_api_key_credentials.return_value = mock_cred
options = client_options.ClientOptions()
options.api_key = "api_key"
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class(client_options=options)
patched.assert_called_once_with(
credentials=mock_cred,
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
always_use_jwt_access=True,
)

{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,16 @@ def __init__(self, *,

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, AssetServiceTransport):
# transport is a AssetServiceTransport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -364,6 +368,11 @@ def __init__(self, *,
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3547,6 +3547,27 @@ def test_credentials_transport_error():
transport=transport,
)

# It is an error to provide an api_key and a transport instance.
transport = transports.AssetServiceGrpcTransport(
credentials=ga_credentials.AnonymousCredentials(),
)
options = client_options.ClientOptions()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = AssetServiceClient(
client_options=options,
transport=transport,
)

# It is an error to provide an api_key and a credential.
options = mock.Mock()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = AssetServiceClient(
client_options=options,
credentials=ga_credentials.AnonymousCredentials()
)

# It is an error to provide scopes and a transport instance.
transport = transports.AssetServiceGrpcTransport(
credentials=ga_credentials.AnonymousCredentials(),
Expand Down Expand Up @@ -4129,3 +4150,29 @@ def test_client_ctx():
with client:
pass
close.assert_called()

@pytest.mark.parametrize("client_class,transport_class", [
(AssetServiceClient, transports.AssetServiceGrpcTransport),
(AssetServiceAsyncClient, transports.AssetServiceGrpcAsyncIOTransport),
])
def test_api_key_credentials(client_class, transport_class):
with mock.patch.object(
google.auth._default, "get_api_key_credentials", create=True
) as get_api_key_credentials:
mock_cred = mock.Mock()
get_api_key_credentials.return_value = mock_cred
options = client_options.ClientOptions()
options.api_key = "api_key"
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class(client_options=options)
patched.assert_called_once_with(
credentials=mock_cred,
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
always_use_jwt_access=True,
)
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,16 @@ def __init__(self, *,

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, IAMCredentialsTransport):
# transport is a IAMCredentialsTransport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -360,6 +364,11 @@ def __init__(self, *,
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1491,6 +1491,27 @@ def test_credentials_transport_error():
transport=transport,
)

# It is an error to provide an api_key and a transport instance.
transport = transports.IAMCredentialsGrpcTransport(
credentials=ga_credentials.AnonymousCredentials(),
)
options = client_options.ClientOptions()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = IAMCredentialsClient(
client_options=options,
transport=transport,
)

# It is an error to provide an api_key and a credential.
options = mock.Mock()
options.api_key = "api_key"
with pytest.raises(ValueError):
client = IAMCredentialsClient(
client_options=options,
credentials=ga_credentials.AnonymousCredentials()
)

# It is an error to provide scopes and a transport instance.
transport = transports.IAMCredentialsGrpcTransport(
credentials=ga_credentials.AnonymousCredentials(),
Expand Down Expand Up @@ -2011,3 +2032,29 @@ def test_client_ctx():
with client:
pass
close.assert_called()

@pytest.mark.parametrize("client_class,transport_class", [
(IAMCredentialsClient, transports.IAMCredentialsGrpcTransport),
(IAMCredentialsAsyncClient, transports.IAMCredentialsGrpcAsyncIOTransport),
])
def test_api_key_credentials(client_class, transport_class):
with mock.patch.object(
google.auth._default, "get_api_key_credentials", create=True
) as get_api_key_credentials:
mock_cred = mock.Mock()
get_api_key_credentials.return_value = mock_cred
options = client_options.ClientOptions()
options.api_key = "api_key"
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class(client_options=options)
patched.assert_called_once_with(
credentials=mock_cred,
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
always_use_jwt_access=True,
)
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,16 @@ def __init__(self, *,

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, ConfigServiceV2Transport):
# transport is a ConfigServiceV2Transport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -395,6 +399,11 @@ def __init__(self, *,
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,16 @@ def __init__(self, *,

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, LoggingServiceV2Transport):
# transport is a LoggingServiceV2Transport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -351,6 +355,11 @@ def __init__(self, *,
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,16 @@ def __init__(self, *,

api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options)

api_key_value = getattr(client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError("client_options.api_key and credentials are mutually exclusive")

# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
if isinstance(transport, MetricsServiceV2Transport):
# transport is a MetricsServiceV2Transport instance.
if credentials or client_options.credentials_file:
if credentials or client_options.credentials_file or api_key_value:
raise ValueError("When providing a transport instance, "
"provide its credentials directly.")
if client_options.scopes:
Expand All @@ -352,6 +356,11 @@ def __init__(self, *,
)
self._transport = transport
else:
import google.auth._default # type: ignore

if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
credentials = google.auth._default.get_api_key_credentials(api_key_value)

Transport = type(self).get_transport_class(transport)
self._transport = Transport(
credentials=credentials,
Expand Down
Loading

0 comments on commit 7c72739

Please sign in to comment.