@@ -215,6 +215,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
215
215
m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
216
216
return m .groupdict () if m else {}
217
217
218
+ @classmethod
219
+ def get_mtls_endpoint_and_cert_source (
220
+ cls , client_options : Optional [client_options_lib .ClientOptions ] = None
221
+ ):
222
+ """Return the API endpoint and client cert source for mutual TLS.
223
+
224
+ The client cert source is determined in the following order:
225
+ (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
226
+ client cert source is None.
227
+ (2) if `client_options.client_cert_source` is provided, use the provided one; if the
228
+ default client cert source exists, use the default one; otherwise the client cert
229
+ source is None.
230
+
231
+ The API endpoint is determined in the following order:
232
+ (1) if `client_options.api_endpoint` if provided, use the provided one.
233
+ (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
234
+ default mTLS endpoint; if the environment variabel is "never", use the default API
235
+ endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
236
+ use the default API endpoint.
237
+
238
+ More details can be found at https://google.aip.dev/auth/4114.
239
+
240
+ Args:
241
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
242
+ client. Only the `api_endpoint` and `client_cert_source` properties may be used
243
+ in this method.
244
+
245
+ Returns:
246
+ Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
247
+ client cert source to use.
248
+
249
+ Raises:
250
+ google.auth.exceptions.MutualTLSChannelError: If any errors happen.
251
+ """
252
+ if client_options is None :
253
+ client_options = client_options_lib .ClientOptions ()
254
+ use_client_cert = os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
255
+ use_mtls_endpoint = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
256
+ if use_client_cert not in ("true" , "false" ):
257
+ raise ValueError (
258
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
259
+ )
260
+ if use_mtls_endpoint not in ("auto" , "never" , "always" ):
261
+ raise MutualTLSChannelError (
262
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
263
+ )
264
+
265
+ # Figure out the client cert source to use.
266
+ client_cert_source = None
267
+ if use_client_cert == "true" :
268
+ if client_options .client_cert_source :
269
+ client_cert_source = client_options .client_cert_source
270
+ elif mtls .has_default_client_cert_source ():
271
+ client_cert_source = mtls .default_client_cert_source ()
272
+
273
+ # Figure out which api endpoint to use.
274
+ if client_options .api_endpoint is not None :
275
+ api_endpoint = client_options .api_endpoint
276
+ elif use_mtls_endpoint == "always" or (
277
+ use_mtls_endpoint == "auto" and client_cert_source
278
+ ):
279
+ api_endpoint = cls .DEFAULT_MTLS_ENDPOINT
280
+ else :
281
+ api_endpoint = cls .DEFAULT_ENDPOINT
282
+
283
+ return api_endpoint , client_cert_source
284
+
218
285
def __init__ (
219
286
self ,
220
287
* ,
@@ -265,57 +332,22 @@ def __init__(
265
332
if client_options is None :
266
333
client_options = client_options_lib .ClientOptions ()
267
334
268
- # Create SSL credentials for mutual TLS if needed.
269
- if os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not in (
270
- "true" ,
271
- "false" ,
272
- ):
273
- raise ValueError (
274
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
275
- )
276
- use_client_cert = (
277
- os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) == "true"
335
+ api_endpoint , client_cert_source_func = self .get_mtls_endpoint_and_cert_source (
336
+ client_options
278
337
)
279
338
280
- client_cert_source_func = None
281
- is_mtls = False
282
- if use_client_cert :
283
- if client_options .client_cert_source :
284
- is_mtls = True
285
- client_cert_source_func = client_options .client_cert_source
286
- else :
287
- is_mtls = mtls .has_default_client_cert_source ()
288
- if is_mtls :
289
- client_cert_source_func = mtls .default_client_cert_source ()
290
- else :
291
- client_cert_source_func = None
292
-
293
- # Figure out which api endpoint to use.
294
- if client_options .api_endpoint is not None :
295
- api_endpoint = client_options .api_endpoint
296
- else :
297
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
298
- if use_mtls_env == "never" :
299
- api_endpoint = self .DEFAULT_ENDPOINT
300
- elif use_mtls_env == "always" :
301
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
302
- elif use_mtls_env == "auto" :
303
- if is_mtls :
304
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
305
- else :
306
- api_endpoint = self .DEFAULT_ENDPOINT
307
- else :
308
- raise MutualTLSChannelError (
309
- "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
310
- "values: never, auto, always"
311
- )
339
+ api_key_value = getattr (client_options , "api_key" , None )
340
+ if api_key_value and credentials :
341
+ raise ValueError (
342
+ "client_options.api_key and credentials are mutually exclusive"
343
+ )
312
344
313
345
# Save or instantiate the transport.
314
346
# Ordinarily, we provide the transport, but allowing a custom transport
315
347
# instance provides an extensibility point for unusual situations.
316
348
if isinstance (transport , TextToSpeechTransport ):
317
349
# transport is a TextToSpeechTransport instance.
318
- if credentials or client_options .credentials_file :
350
+ if credentials or client_options .credentials_file or api_key_value :
319
351
raise ValueError (
320
352
"When providing a transport instance, "
321
353
"provide its credentials directly."
@@ -327,6 +359,15 @@ def __init__(
327
359
)
328
360
self ._transport = transport
329
361
else :
362
+ import google .auth ._default # type: ignore
363
+
364
+ if api_key_value and hasattr (
365
+ google .auth ._default , "get_api_key_credentials"
366
+ ):
367
+ credentials = google .auth ._default .get_api_key_credentials (
368
+ api_key_value
369
+ )
370
+
330
371
Transport = type (self ).get_transport_class (transport )
331
372
self ._transport = Transport (
332
373
credentials = credentials ,
0 commit comments