Skip to content

Commit 13cddda

Browse files
authored
fix: expose transport property for clients (#645)
Sometimes it's useful to get a reference to the transport for a client object. Closes #640
1 parent 7ff5963 commit 13cddda

File tree

4 files changed

+95
-77
lines changed

4 files changed

+95
-77
lines changed

gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/client.py.j2

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
118118

119119
from_service_account_json = from_service_account_file
120120

121+
@property
122+
def transport(self) -> {{ service.name }}Transport:
123+
"""Return the transport used by the client instance.
124+
125+
Returns:
126+
{{ service.name }}Transport: The transport used by the client instance.
127+
"""
128+
return self._transport
129+
121130

122131
{% for message in service.resource_messages|sort(attribute="resource_type") -%}
123132
@staticmethod
@@ -143,7 +152,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
143152
"""Parse a {{ resource_msg.message_type.resource_type|snake_case }} path into its component segments."""
144153
m = re.match(r"{{ resource_msg.message_type.path_regex_str }}", path)
145154
return m.groupdict() if m else {}
146-
155+
147156
{% endfor %} {# common resources #}
148157

149158
def __init__(self, *,
@@ -179,12 +188,12 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
179188
not provided, the default SSL client certificate will be used if
180189
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
181190
set, no client certificate will be used.
182-
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
183-
The client info used to send a user-agent string along with
184-
API requests. If ``None``, then default info will be used.
185-
Generally, you only need to set this if you're developing
191+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
192+
The client info used to send a user-agent string along with
193+
API requests. If ``None``, then default info will be used.
194+
Generally, you only need to set this if you're developing
186195
your own client library.
187-
196+
188197
Raises:
189198
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
190199
creation failed for any reason.
@@ -193,10 +202,10 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
193202
client_options = client_options_lib.from_dict(client_options)
194203
if client_options is None:
195204
client_options = client_options_lib.ClientOptions()
196-
205+
197206
# Create SSL credentials for mutual TLS if needed.
198207
use_client_cert = bool(util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")))
199-
208+
200209
ssl_credentials = None
201210
is_mtls = False
202211
if use_client_cert:

gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ def test_{{ service.client_name|snake_case }}_from_service_account_file():
6666
with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory:
6767
factory.return_value = creds
6868
client = {{ service.client_name }}.from_service_account_file("dummy/file/path.json")
69-
assert client._transport._credentials == creds
69+
assert client.transport._credentials == creds
7070

7171
client = {{ service.client_name }}.from_service_account_json("dummy/file/path.json")
72-
assert client._transport._credentials == creds
72+
assert client.transport._credentials == creds
7373

74-
{% if service.host %}assert client._transport._host == '{{ service.host }}{% if ":" not in service.host %}:443{% endif %}'{% endif %}
74+
{% if service.host %}assert client.transport._host == '{{ service.host }}{% if ":" not in service.host %}:443{% endif %}'{% endif %}
7575

7676

7777
def test_{{ service.client_name|snake_case }}_get_transport_class():
@@ -170,7 +170,7 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(use_client_cert_env)
170170
else:
171171
expected_ssl_channel_creds = ssl_channel_creds
172172
expected_host = client.DEFAULT_MTLS_ENDPOINT
173-
173+
174174
grpc_transport.assert_called_once_with(
175175
ssl_channel_credentials=expected_ssl_channel_creds,
176176
credentials=None,
@@ -182,9 +182,9 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(use_client_cert_env)
182182
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
183183
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}):
184184
with mock.patch('{{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.{{ service.name }}GrpcTransport.__init__') as grpc_transport:
185-
with mock.patch('google.auth.transport.grpc.SslCredentials.__init__', return_value=None):
185+
with mock.patch('google.auth.transport.grpc.SslCredentials.__init__', return_value=None):
186186
with mock.patch('google.auth.transport.grpc.SslCredentials.is_mtls', new_callable=mock.PropertyMock) as is_mtls_mock:
187-
with mock.patch('google.auth.transport.grpc.SslCredentials.ssl_credentials', new_callable=mock.PropertyMock) as ssl_credentials_mock:
187+
with mock.patch('google.auth.transport.grpc.SslCredentials.ssl_credentials', new_callable=mock.PropertyMock) as ssl_credentials_mock:
188188
if use_client_cert_env == "false":
189189
is_mtls_mock.return_value = False
190190
ssl_credentials_mock.return_value = None
@@ -195,7 +195,7 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(use_client_cert_env)
195195
ssl_credentials_mock.return_value = mock.Mock()
196196
expected_host = client.DEFAULT_MTLS_ENDPOINT
197197
expected_ssl_channel_creds = ssl_credentials_mock.return_value
198-
198+
199199
grpc_transport.return_value = None
200200
client = {{ service.client_name }}()
201201
grpc_transport.assert_called_once_with(
@@ -208,7 +208,7 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(use_client_cert_env)
208208
# Check the case client_cert_source and ADC client cert are not provided.
209209
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}):
210210
with mock.patch('{{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.{{ service.name }}GrpcTransport.__init__') as grpc_transport:
211-
with mock.patch('google.auth.transport.grpc.SslCredentials.__init__', return_value=None):
211+
with mock.patch('google.auth.transport.grpc.SslCredentials.__init__', return_value=None):
212212
with mock.patch('google.auth.transport.grpc.SslCredentials.is_mtls', new_callable=mock.PropertyMock) as is_mtls_mock:
213213
is_mtls_mock.return_value = False
214214
grpc_transport.return_value = None
@@ -251,7 +251,7 @@ def test_{{ method.name|snake_case }}(transport: str = 'grpc', request_type={{ m
251251

252252
# Mock the actual call within the gRPC stub, and fake the request.
253253
with mock.patch.object(
254-
type(client._transport.{{ method.name|snake_case }}),
254+
type(client.transport.{{ method.name|snake_case }}),
255255
'__call__') as call:
256256
# Designate an appropriate return value for the call.
257257
{% if method.void -%}
@@ -331,7 +331,7 @@ def test_{{ method.name|snake_case }}_field_headers():
331331

332332
# Mock the actual call within the gRPC stub, and fake the request.
333333
with mock.patch.object(
334-
type(client._transport.{{ method.name|snake_case }}),
334+
type(client.transport.{{ method.name|snake_case }}),
335335
'__call__') as call:
336336
{% if method.void -%}
337337
call.return_value = None
@@ -367,7 +367,7 @@ def test_{{ method.name|snake_case }}_from_dict():
367367
)
368368
# Mock the actual call within the gRPC stub, and fake the request.
369369
with mock.patch.object(
370-
type(client._transport.{{ method.name|snake_case }}),
370+
type(client.transport.{{ method.name|snake_case }}),
371371
'__call__') as call:
372372
# Designate an appropriate return value for the call.
373373
{% if method.void -%}
@@ -397,7 +397,7 @@ def test_{{ method.name|snake_case }}_flattened():
397397

398398
# Mock the actual call within the gRPC stub, and fake the request.
399399
with mock.patch.object(
400-
type(client._transport.{{ method.name|snake_case }}),
400+
type(client.transport.{{ method.name|snake_case }}),
401401
'__call__') as call:
402402
# Designate an appropriate return value for the call.
403403
{% if method.void -%}
@@ -462,7 +462,7 @@ def test_{{ method.name|snake_case }}_pager():
462462

463463
# Mock the actual call within the gRPC stub, and fake the request.
464464
with mock.patch.object(
465-
type(client._transport.{{ method.name|snake_case }}),
465+
type(client.transport.{{ method.name|snake_case }}),
466466
'__call__') as call:
467467
# Set the response to a series of pages.
468468
call.side_effect = (
@@ -521,7 +521,7 @@ def test_{{ method.name|snake_case }}_pages():
521521

522522
# Mock the actual call within the gRPC stub, and fake the request.
523523
with mock.patch.object(
524-
type(client._transport.{{ method.name|snake_case }}),
524+
type(client.transport.{{ method.name|snake_case }}),
525525
'__call__') as call:
526526
# Set the response to a series of pages.
527527
call.side_effect = (
@@ -580,7 +580,7 @@ def test_transport_instance():
580580
credentials=credentials.AnonymousCredentials(),
581581
)
582582
client = {{ service.client_name }}(transport=transport)
583-
assert client._transport is transport
583+
assert client.transport is transport
584584

585585

586586
def test_transport_grpc_default():
@@ -589,7 +589,7 @@ def test_transport_grpc_default():
589589
credentials=credentials.AnonymousCredentials(),
590590
)
591591
assert isinstance(
592-
client._transport,
592+
client.transport,
593593
transports.{{ service.name }}GrpcTransport,
594594
)
595595

@@ -669,7 +669,7 @@ def test_{{ service.name|snake_case }}_host_no_port():
669669
credentials=credentials.AnonymousCredentials(),
670670
client_options=client_options.ClientOptions(api_endpoint='{{ host }}'),
671671
)
672-
assert client._transport._host == '{{ host }}:443'
672+
assert client.transport._host == '{{ host }}:443'
673673
{% endwith %}
674674

675675

@@ -679,7 +679,7 @@ def test_{{ service.name|snake_case }}_host_with_port():
679679
credentials=credentials.AnonymousCredentials(),
680680
client_options=client_options.ClientOptions(api_endpoint='{{ host }}:8000'),
681681
)
682-
assert client._transport._host == '{{ host }}:8000'
682+
assert client.transport._host == '{{ host }}:8000'
683683
{% endwith %}
684684

685685

@@ -701,7 +701,7 @@ def test_{{ service.name|snake_case }}_grpc_lro_client():
701701
credentials=credentials.AnonymousCredentials(),
702702
transport='grpc',
703703
)
704-
transport = client._transport
704+
transport = client.transport
705705

706706
# Ensure that we have a api-core operations client.
707707
assert isinstance(

gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
124124

125125
from_service_account_json = from_service_account_file
126126

127+
@property
128+
def transport(self) -> {{ service.name }}Transport:
129+
"""Return the transport used by the client instance.
130+
131+
Returns:
132+
{{ service.name }}Transport: The transport used by the client instance.
133+
"""
134+
return self._transport
135+
127136

128137
{% for message in service.resource_messages|sort(attribute="resource_type") -%}
129138
@staticmethod
@@ -150,7 +159,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
150159
"""Parse a {{ resource_msg.message_type.resource_type|snake_case }} path into its component segments."""
151160
m = re.match(r"{{ resource_msg.message_type.path_regex_str }}", path)
152161
return m.groupdict() if m else {}
153-
162+
154163
{% endfor %} {# common resources #}
155164

156165
def __init__(self, *,
@@ -186,12 +195,12 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
186195
not provided, the default SSL client certificate will be used if
187196
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
188197
set, no client certificate will be used.
189-
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
190-
The client info used to send a user-agent string along with
191-
API requests. If ``None``, then default info will be used.
192-
Generally, you only need to set this if you're developing
198+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
199+
The client info used to send a user-agent string along with
200+
API requests. If ``None``, then default info will be used.
201+
Generally, you only need to set this if you're developing
193202
your own client library.
194-
203+
195204
Raises:
196205
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
197206
creation failed for any reason.
@@ -200,10 +209,10 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
200209
client_options = client_options_lib.from_dict(client_options)
201210
if client_options is None:
202211
client_options = client_options_lib.ClientOptions()
203-
212+
204213
# Create SSL credentials for mutual TLS if needed.
205214
use_client_cert = bool(util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")))
206-
215+
207216
ssl_credentials = None
208217
is_mtls = False
209218
if use_client_cert:

0 commit comments

Comments
 (0)