16
16
#
17
17
18
18
from collections import OrderedDict
19
+ from distutils import util
19
20
import os
20
21
import re
21
- from typing import Callable , Dict , Sequence , Tuple , Type , Union
22
+ from typing import Callable , Dict , Optional , Sequence , Tuple , Type , Union
22
23
import pkg_resources
23
24
24
- import google .api_core . client_options as ClientOptions # type: ignore
25
+ from google .api_core import client_options as client_options_lib # type: ignore
25
26
from google .api_core import exceptions # type: ignore
26
27
from google .api_core import gapic_v1 # type: ignore
27
28
from google .api_core import retry as retries # type: ignore
28
29
from google .auth import credentials # type: ignore
29
30
from google .auth .transport import mtls # type: ignore
31
+ from google .auth .transport .grpc import SslCredentials # type: ignore
30
32
from google .auth .exceptions import MutualTLSChannelError # type: ignore
31
33
from google .oauth2 import service_account # type: ignore
32
34
@@ -130,6 +132,15 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
130
132
131
133
from_service_account_json = from_service_account_file
132
134
135
+ @property
136
+ def transport (self ) -> ErrorGroupServiceTransport :
137
+ """Return the transport used by the client instance.
138
+
139
+ Returns:
140
+ ErrorGroupServiceTransport: The transport used by the client instance.
141
+ """
142
+ return self ._transport
143
+
133
144
@staticmethod
134
145
def error_group_path (project : str , group : str ,) -> str :
135
146
"""Return a fully-qualified error_group string."""
@@ -141,12 +152,71 @@ def parse_error_group_path(path: str) -> Dict[str, str]:
141
152
m = re .match (r"^projects/(?P<project>.+?)/groups/(?P<group>.+?)$" , path )
142
153
return m .groupdict () if m else {}
143
154
155
+ @staticmethod
156
+ def common_billing_account_path (billing_account : str ,) -> str :
157
+ """Return a fully-qualified billing_account string."""
158
+ return "billingAccounts/{billing_account}" .format (
159
+ billing_account = billing_account ,
160
+ )
161
+
162
+ @staticmethod
163
+ def parse_common_billing_account_path (path : str ) -> Dict [str , str ]:
164
+ """Parse a billing_account path into its component segments."""
165
+ m = re .match (r"^billingAccounts/(?P<billing_account>.+?)$" , path )
166
+ return m .groupdict () if m else {}
167
+
168
+ @staticmethod
169
+ def common_folder_path (folder : str ,) -> str :
170
+ """Return a fully-qualified folder string."""
171
+ return "folders/{folder}" .format (folder = folder ,)
172
+
173
+ @staticmethod
174
+ def parse_common_folder_path (path : str ) -> Dict [str , str ]:
175
+ """Parse a folder path into its component segments."""
176
+ m = re .match (r"^folders/(?P<folder>.+?)$" , path )
177
+ return m .groupdict () if m else {}
178
+
179
+ @staticmethod
180
+ def common_organization_path (organization : str ,) -> str :
181
+ """Return a fully-qualified organization string."""
182
+ return "organizations/{organization}" .format (organization = organization ,)
183
+
184
+ @staticmethod
185
+ def parse_common_organization_path (path : str ) -> Dict [str , str ]:
186
+ """Parse a organization path into its component segments."""
187
+ m = re .match (r"^organizations/(?P<organization>.+?)$" , path )
188
+ return m .groupdict () if m else {}
189
+
190
+ @staticmethod
191
+ def common_project_path (project : str ,) -> str :
192
+ """Return a fully-qualified project string."""
193
+ return "projects/{project}" .format (project = project ,)
194
+
195
+ @staticmethod
196
+ def parse_common_project_path (path : str ) -> Dict [str , str ]:
197
+ """Parse a project path into its component segments."""
198
+ m = re .match (r"^projects/(?P<project>.+?)$" , path )
199
+ return m .groupdict () if m else {}
200
+
201
+ @staticmethod
202
+ def common_location_path (project : str , location : str ,) -> str :
203
+ """Return a fully-qualified location string."""
204
+ return "projects/{project}/locations/{location}" .format (
205
+ project = project , location = location ,
206
+ )
207
+
208
+ @staticmethod
209
+ def parse_common_location_path (path : str ) -> Dict [str , str ]:
210
+ """Parse a location path into its component segments."""
211
+ m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
212
+ return m .groupdict () if m else {}
213
+
144
214
def __init__ (
145
215
self ,
146
216
* ,
147
- credentials : credentials .Credentials = None ,
148
- transport : Union [str , ErrorGroupServiceTransport ] = None ,
149
- client_options : ClientOptions = None ,
217
+ credentials : Optional [ credentials .Credentials ] = None ,
218
+ transport : Union [str , ErrorGroupServiceTransport , None ] = None ,
219
+ client_options : Optional [ client_options_lib . ClientOptions ] = None ,
150
220
client_info : gapic_v1 .client_info .ClientInfo = DEFAULT_CLIENT_INFO ,
151
221
) -> None :
152
222
"""Instantiate the error group service client.
@@ -160,53 +230,74 @@ def __init__(
160
230
transport (Union[str, ~.ErrorGroupServiceTransport]): The
161
231
transport to use. If set to None, a transport is chosen
162
232
automatically.
163
- client_options (ClientOptions): Custom options for the client. It
164
- won't take effect if a ``transport`` instance is provided.
233
+ client_options (client_options_lib. ClientOptions): Custom options for the
234
+ client. It won't take effect if a ``transport`` instance is provided.
165
235
(1) The ``api_endpoint`` property can be used to override the
166
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
236
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
167
237
environment variable can also be used to override the endpoint:
168
238
"always" (always use the default mTLS endpoint), "never" (always
169
- use the default regular endpoint, this is the default value for
170
- the environment variable) and "auto" (auto switch to the default
171
- mTLS endpoint if client SSL credentials is present). However,
172
- the ``api_endpoint`` property takes precedence if provided.
173
- (2) The ``client_cert_source`` property is used to provide client
174
- SSL credentials for mutual TLS transport. If not provided, the
175
- default SSL credentials will be used if present.
176
- client_info (google.api_core.gapic_v1.client_info.ClientInfo):
177
- The client info used to send a user-agent string along with
178
- API requests. If ``None``, then default info will be used.
179
- Generally, you only need to set this if you're developing
239
+ use the default regular endpoint) and "auto" (auto switch to the
240
+ default mTLS endpoint if client certificate is present, this is
241
+ the default value). However, the ``api_endpoint`` property takes
242
+ precedence if provided.
243
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
244
+ is "true", then the ``client_cert_source`` property can be used
245
+ to provide client certificate for mutual TLS transport. If
246
+ not provided, the default SSL client certificate will be used if
247
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
248
+ set, no client certificate will be used.
249
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
250
+ The client info used to send a user-agent string along with
251
+ API requests. If ``None``, then default info will be used.
252
+ Generally, you only need to set this if you're developing
180
253
your own client library.
181
254
182
255
Raises:
183
256
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
184
257
creation failed for any reason.
185
258
"""
186
259
if isinstance (client_options , dict ):
187
- client_options = ClientOptions .from_dict (client_options )
260
+ client_options = client_options_lib .from_dict (client_options )
188
261
if client_options is None :
189
- client_options = ClientOptions .ClientOptions ()
262
+ client_options = client_options_lib .ClientOptions ()
263
+
264
+ # Create SSL credentials for mutual TLS if needed.
265
+ use_client_cert = bool (
266
+ util .strtobool (os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ))
267
+ )
190
268
191
- if client_options .api_endpoint is None :
192
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS" , "never" )
269
+ ssl_credentials = None
270
+ is_mtls = False
271
+ if use_client_cert :
272
+ if client_options .client_cert_source :
273
+ import grpc # type: ignore
274
+
275
+ cert , key = client_options .client_cert_source ()
276
+ ssl_credentials = grpc .ssl_channel_credentials (
277
+ certificate_chain = cert , private_key = key
278
+ )
279
+ is_mtls = True
280
+ else :
281
+ creds = SslCredentials ()
282
+ is_mtls = creds .is_mtls
283
+ ssl_credentials = creds .ssl_credentials if is_mtls else None
284
+
285
+ # Figure out which api endpoint to use.
286
+ if client_options .api_endpoint is not None :
287
+ api_endpoint = client_options .api_endpoint
288
+ else :
289
+ use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
193
290
if use_mtls_env == "never" :
194
- client_options . api_endpoint = self .DEFAULT_ENDPOINT
291
+ api_endpoint = self .DEFAULT_ENDPOINT
195
292
elif use_mtls_env == "always" :
196
- client_options . api_endpoint = self .DEFAULT_MTLS_ENDPOINT
293
+ api_endpoint = self .DEFAULT_MTLS_ENDPOINT
197
294
elif use_mtls_env == "auto" :
198
- has_client_cert_source = (
199
- client_options .client_cert_source is not None
200
- or mtls .has_default_client_cert_source ()
201
- )
202
- client_options .api_endpoint = (
203
- self .DEFAULT_MTLS_ENDPOINT
204
- if has_client_cert_source
205
- else self .DEFAULT_ENDPOINT
295
+ api_endpoint = (
296
+ self .DEFAULT_MTLS_ENDPOINT if is_mtls else self .DEFAULT_ENDPOINT
206
297
)
207
298
else :
208
299
raise MutualTLSChannelError (
209
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
300
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
210
301
)
211
302
212
303
# Save or instantiate the transport.
@@ -230,10 +321,9 @@ def __init__(
230
321
self ._transport = Transport (
231
322
credentials = credentials ,
232
323
credentials_file = client_options .credentials_file ,
233
- host = client_options . api_endpoint ,
324
+ host = api_endpoint ,
234
325
scopes = client_options .scopes ,
235
- api_mtls_endpoint = client_options .api_endpoint ,
236
- client_cert_source = client_options .client_cert_source ,
326
+ ssl_channel_credentials = ssl_credentials ,
237
327
quota_project_id = client_options .quota_project_id ,
238
328
client_info = client_info ,
239
329
)
0 commit comments