Skip to content

Commit a60a211

Browse files
feat: allow Callables for transport and channel init (#1699)
1 parent 7de4b96 commit a60a211

File tree

32 files changed

+402
-258
lines changed

32 files changed

+402
-258
lines changed

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/async_client.py.j2

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from collections import OrderedDict
77
import functools
88
import re
9-
from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, {% if service.any_server_streaming %}AsyncIterable, Awaitable, {% endif %}{% if service.any_client_streaming %}AsyncIterator, {% endif %}Sequence, Tuple, Type, Union
9+
from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, {% if service.any_server_streaming %}AsyncIterable, Awaitable, {% endif %}{% if service.any_client_streaming %}AsyncIterator, {% endif %}Sequence, Tuple, Type, Union
1010
{% if api.all_method_settings.values()|map(attribute="auto_populated_fields", default=[])|list %}
1111
import uuid
1212
{% endif %}
@@ -173,7 +173,7 @@ class {{ service.async_client_name }}:
173173

174174
def __init__(self, *,
175175
credentials: Optional[ga_credentials.Credentials] = None,
176-
transport: Union[str, {{ service.name }}Transport] = "grpc_asyncio",
176+
transport: Optional[Union[str, {{ service.name }}Transport, Callable[..., {{ service.name }}Transport]]] = "grpc_asyncio",
177177
client_options: Optional[ClientOptions] = None,
178178
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
179179
) -> None:
@@ -185,9 +185,11 @@ class {{ service.async_client_name }}:
185185
credentials identify the application to the service; if none
186186
are specified, the client will attempt to ascertain the
187187
credentials from the environment.
188-
transport (Union[str, ~.{{ service.name }}Transport]): The
189-
transport to use. If set to None, a transport is chosen
190-
automatically.
188+
transport (Optional[Union[str,{{ service.name }}Transport,Callable[..., {{ service.name }}Transport]]]):
189+
The transport to use, or a Callable that constructs and returns a new transport to use.
190+
If a Callable is given, it will be called with the same set of initialization
191+
arguments as used in the {{ service.name }}Transport constructor.
192+
If set to None, a transport is chosen automatically.
191193
{% if 'rest' in opts.transport and not opts.rest_numeric_enums %}
192194
{# TODO (gapic-generator-python/issues/1918): Remove the beta preview comment. #}
193195
NOTE: "rest" transport functionality is currently in a
@@ -196,8 +198,8 @@ class {{ service.async_client_name }}:
196198
{% endif %}
197199
client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
198200
Custom options for the client.
199-
200-
1. The ``api_endpoint`` property can be used to override the
201+
202+
1. The ``api_endpoint`` property can be used to override the
201203
default endpoint provided by the client when ``transport`` is
202204
not explicitly provided. Only if this property is not set and
203205
``transport`` was not explicitly provided, the endpoint is

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import functools
99
{% endif %}
1010
import os
1111
import re
12-
from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, {% if service.any_server_streaming %}Iterable, {% endif %}{% if service.any_client_streaming %}Iterator, {% endif %}Sequence, Tuple, Type, Union, cast
12+
from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, {% if service.any_server_streaming %}Iterable, {% endif %}{% if service.any_client_streaming %}Iterator, {% endif %}Sequence, Tuple, Type, Union, cast
1313
{% if api.all_method_settings.values()|map(attribute="auto_populated_fields", default=[])|list %}
1414
import uuid
1515
{% endif %}
@@ -435,7 +435,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
435435

436436
def __init__(self, *,
437437
credentials: Optional[ga_credentials.Credentials] = None,
438-
transport: Optional[Union[str, {{ service.name }}Transport]] = None,
438+
transport: Optional[Union[str, {{ service.name }}Transport, Callable[..., {{ service.name }}Transport]]] = None,
439439
client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
440440
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
441441
) -> None:
@@ -447,9 +447,11 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
447447
credentials identify the application to the service; if none
448448
are specified, the client will attempt to ascertain the
449449
credentials from the environment.
450-
transport (Union[str, {{ service.name }}Transport]): The
451-
transport to use. If set to None, a transport is chosen
452-
automatically.
450+
transport (Optional[Union[str,{{ service.name }}Transport,Callable[..., {{ service.name }}Transport]]]):
451+
The transport to use, or a Callable that constructs and returns a new transport.
452+
If a Callable is given, it will be called with the same set of initialization
453+
arguments as used in the {{ service.name }}Transport constructor.
454+
If set to None, a transport is chosen automatically.
453455
{% if 'rest' in opts.transport and not opts.rest_numeric_enums %}
454456
{# TODO (gapic-generator-python/issues/1918): Remove the beta preview comment. #}
455457
NOTE: "rest" transport functionality is currently in a
@@ -543,8 +545,13 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
543545
if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"):
544546
credentials = google.auth._default.get_api_key_credentials(api_key_value)
545547

546-
Transport = type(self).get_transport_class(cast(str, transport))
547-
self._transport = Transport(
548+
transport_init: Union[Type[{{ service.name }}Transport], Callable[..., {{ service.name }}Transport]] = (
549+
type(self).get_transport_class(transport)
550+
if isinstance(transport, str) or transport is None
551+
else cast(Callable[..., {{ service.name }}Transport], transport)
552+
)
553+
# initialize with the provided callable or the passed in class
554+
self._transport = transport_init(
548555
credentials=credentials,
549556
credentials_file=self._client_options.credentials_file,
550557
host=self._api_endpoint,

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/grpc.py.j2

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
6262
credentials: Optional[ga_credentials.Credentials] = None,
6363
credentials_file: Optional[str] = None,
6464
scopes: Optional[Sequence[str]] = None,
65-
channel: Optional[grpc.Channel] = None,
65+
channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None,
6666
api_mtls_endpoint: Optional[str] = None,
6767
client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
6868
ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
@@ -82,14 +82,17 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
8282
credentials identify the application to the service; if none
8383
are specified, the client will attempt to ascertain the
8484
credentials from the environment.
85-
This argument is ignored if ``channel`` is provided.
85+
This argument is ignored if a ``channel`` instance is provided.
8686
credentials_file (Optional[str]): A file with credentials that can
8787
be loaded with :func:`google.auth.load_credentials_from_file`.
88-
This argument is ignored if ``channel`` is provided.
88+
This argument is ignored if a ``channel`` instance is provided.
8989
scopes (Optional(Sequence[str])): A list of scopes. This argument is
90-
ignored if ``channel`` is provided.
91-
channel (Optional[grpc.Channel]): A ``Channel`` instance through
92-
which to make calls.
90+
ignored if a ``channel`` instance is provided.
91+
channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]):
92+
A ``Channel`` instance through which to make calls, or a Callable
93+
that constructs and returns one. If set to None, ``self.create_channel``
94+
is used to create the channel. If a Callable is given, it will be called
95+
with the same arguments as used in ``self.create_channel``.
9396
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
9497
If provided, it overrides the ``host`` argument and tries to create
9598
a mutual TLS channel with client SSL credentials from
@@ -99,11 +102,11 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
99102
private key bytes, both in PEM format. It is ignored if
100103
``api_mtls_endpoint`` is None.
101104
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
102-
for the grpc channel. It is ignored if ``channel`` is provided.
105+
for the grpc channel. It is ignored if a ``channel`` instance is provided.
103106
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
104107
A callback to provide client certificate bytes and private key bytes,
105108
both in PEM format. It is used to configure a mutual TLS channel. It is
106-
ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
109+
ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
107110
quota_project_id (Optional[str]): An optional project to use for billing
108111
and quota.
109112
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -132,7 +135,7 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
132135
if client_cert_source:
133136
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
134137

135-
if channel:
138+
if isinstance(channel, grpc.Channel):
136139
# Ignore credentials if a channel was passed.
137140
credentials = False
138141
# If a channel was explicitly provided, set it.
@@ -173,7 +176,9 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
173176
)
174177

175178
if not self._grpc_channel:
176-
self._grpc_channel = type(self).create_channel(
179+
# initialize with the provided callable or the default channel
180+
channel_init = channel or type(self).create_channel
181+
self._grpc_channel = channel_init(
177182
self._host,
178183
# use the credentials which are saved
179184
credentials=self._credentials,

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/grpc_asyncio.py.j2

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
7878
the credentials from the environment.
7979
credentials_file (Optional[str]): A file with credentials that can
8080
be loaded with :func:`google.auth.load_credentials_from_file`.
81-
This argument is ignored if ``channel`` is provided.
8281
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
8382
service. These are only used when credentials are not specified and
8483
are passed to :func:`google.auth.default`.
@@ -106,7 +105,7 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
106105
credentials: Optional[ga_credentials.Credentials] = None,
107106
credentials_file: Optional[str] = None,
108107
scopes: Optional[Sequence[str]] = None,
109-
channel: Optional[aio.Channel] = None,
108+
channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None,
110109
api_mtls_endpoint: Optional[str] = None,
111110
client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
112111
ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
@@ -126,15 +125,18 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
126125
credentials identify the application to the service; if none
127126
are specified, the client will attempt to ascertain the
128127
credentials from the environment.
129-
This argument is ignored if ``channel`` is provided.
128+
This argument is ignored if a ``channel`` instance is provided.
130129
credentials_file (Optional[str]): A file with credentials that can
131130
be loaded with :func:`google.auth.load_credentials_from_file`.
132-
This argument is ignored if ``channel`` is provided.
131+
This argument is ignored if a ``channel`` instance is provided.
133132
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
134133
service. These are only used when credentials are not specified and
135134
are passed to :func:`google.auth.default`.
136-
channel (Optional[aio.Channel]): A ``Channel`` instance through
137-
which to make calls.
135+
channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]):
136+
A ``Channel`` instance through which to make calls, or a Callable
137+
that constructs and returns one. If set to None, ``self.create_channel``
138+
is used to create the channel. If a Callable is given, it will be called
139+
with the same arguments as used in ``self.create_channel``.
138140
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
139141
If provided, it overrides the ``host`` argument and tries to create
140142
a mutual TLS channel with client SSL credentials from
@@ -144,11 +146,11 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
144146
private key bytes, both in PEM format. It is ignored if
145147
``api_mtls_endpoint`` is None.
146148
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
147-
for the grpc channel. It is ignored if ``channel`` is provided.
149+
for the grpc channel. It is ignored if a ``channel`` instance is provided.
148150
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
149151
A callback to provide client certificate bytes and private key bytes,
150152
both in PEM format. It is used to configure a mutual TLS channel. It is
151-
ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
153+
ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
152154
quota_project_id (Optional[str]): An optional project to use for billing
153155
and quota.
154156
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -177,7 +179,7 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
177179
if client_cert_source:
178180
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
179181

180-
if channel:
182+
if isinstance(channel, aio.Channel):
181183
# Ignore credentials if a channel was passed.
182184
credentials = False
183185
# If a channel was explicitly provided, set it.
@@ -217,7 +219,9 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport):
217219
)
218220

219221
if not self._grpc_channel:
220-
self._grpc_channel = type(self).create_channel(
222+
# initialize with the provided callable or the default channel
223+
channel_init = channel or type(self).create_channel
224+
self._grpc_channel = channel_init(
221225
self._host,
222226
# use the credentials which are saved
223227
credentials=self._credentials,

packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/services/asset_service/async_client.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from collections import OrderedDict
1717
import functools
1818
import re
19-
from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union
19+
from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union
2020

2121
from google.cloud.asset_v1 import gapic_version as package_version
2222

@@ -183,7 +183,7 @@ def universe_domain(self) -> str:
183183

184184
def __init__(self, *,
185185
credentials: Optional[ga_credentials.Credentials] = None,
186-
transport: Union[str, AssetServiceTransport] = "grpc_asyncio",
186+
transport: Optional[Union[str, AssetServiceTransport, Callable[..., AssetServiceTransport]]] = "grpc_asyncio",
187187
client_options: Optional[ClientOptions] = None,
188188
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
189189
) -> None:
@@ -195,9 +195,11 @@ def __init__(self, *,
195195
credentials identify the application to the service; if none
196196
are specified, the client will attempt to ascertain the
197197
credentials from the environment.
198-
transport (Union[str, ~.AssetServiceTransport]): The
199-
transport to use. If set to None, a transport is chosen
200-
automatically.
198+
transport (Optional[Union[str,AssetServiceTransport,Callable[..., AssetServiceTransport]]]):
199+
The transport to use, or a Callable that constructs and returns a new transport to use.
200+
If a Callable is given, it will be called with the same set of initialization
201+
arguments as used in the AssetServiceTransport constructor.
202+
If set to None, a transport is chosen automatically.
201203
NOTE: "rest" transport functionality is currently in a
202204
beta state (preview). We welcome your feedback via an
203205
issue in this library's source repository.

0 commit comments

Comments
 (0)