@@ -359,6 +359,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
359
359
m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
360
360
return m .groupdict () if m else {}
361
361
362
+ @classmethod
363
+ def get_mtls_endpoint_and_cert_source (
364
+ cls , client_options : Optional [client_options_lib .ClientOptions ] = None
365
+ ):
366
+ """Return the API endpoint and client cert source for mutual TLS.
367
+
368
+ The client cert source is determined in the following order:
369
+ (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
370
+ client cert source is None.
371
+ (2) if `client_options.client_cert_source` is provided, use the provided one; if the
372
+ default client cert source exists, use the default one; otherwise the client cert
373
+ source is None.
374
+
375
+ The API endpoint is determined in the following order:
376
+ (1) if `client_options.api_endpoint` if provided, use the provided one.
377
+ (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
378
+ default mTLS endpoint; if the environment variabel is "never", use the default API
379
+ endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
380
+ use the default API endpoint.
381
+
382
+ More details can be found at https://google.aip.dev/auth/4114.
383
+
384
+ Args:
385
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
386
+ client. Only the `api_endpoint` and `client_cert_source` properties may be used
387
+ in this method.
388
+
389
+ Returns:
390
+ Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
391
+ client cert source to use.
392
+
393
+ Raises:
394
+ google.auth.exceptions.MutualTLSChannelError: If any errors happen.
395
+ """
396
+ if client_options is None :
397
+ client_options = client_options_lib .ClientOptions ()
398
+ use_client_cert = os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
399
+ use_mtls_endpoint = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
400
+ if use_client_cert not in ("true" , "false" ):
401
+ raise ValueError (
402
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
403
+ )
404
+ if use_mtls_endpoint not in ("auto" , "never" , "always" ):
405
+ raise MutualTLSChannelError (
406
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
407
+ )
408
+
409
+ # Figure out the client cert source to use.
410
+ client_cert_source = None
411
+ if use_client_cert == "true" :
412
+ if client_options .client_cert_source :
413
+ client_cert_source = client_options .client_cert_source
414
+ elif mtls .has_default_client_cert_source ():
415
+ client_cert_source = mtls .default_client_cert_source ()
416
+
417
+ # Figure out which api endpoint to use.
418
+ if client_options .api_endpoint is not None :
419
+ api_endpoint = client_options .api_endpoint
420
+ elif use_mtls_endpoint == "always" or (
421
+ use_mtls_endpoint == "auto" and client_cert_source
422
+ ):
423
+ api_endpoint = cls .DEFAULT_MTLS_ENDPOINT
424
+ else :
425
+ api_endpoint = cls .DEFAULT_ENDPOINT
426
+
427
+ return api_endpoint , client_cert_source
428
+
362
429
def __init__ (
363
430
self ,
364
431
* ,
@@ -409,57 +476,22 @@ def __init__(
409
476
if client_options is None :
410
477
client_options = client_options_lib .ClientOptions ()
411
478
412
- # Create SSL credentials for mutual TLS if needed.
413
- if os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not in (
414
- "true" ,
415
- "false" ,
416
- ):
417
- raise ValueError (
418
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
419
- )
420
- use_client_cert = (
421
- os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) == "true"
479
+ api_endpoint , client_cert_source_func = self .get_mtls_endpoint_and_cert_source (
480
+ client_options
422
481
)
423
482
424
- client_cert_source_func = None
425
- is_mtls = False
426
- if use_client_cert :
427
- if client_options .client_cert_source :
428
- is_mtls = True
429
- client_cert_source_func = client_options .client_cert_source
430
- else :
431
- is_mtls = mtls .has_default_client_cert_source ()
432
- if is_mtls :
433
- client_cert_source_func = mtls .default_client_cert_source ()
434
- else :
435
- client_cert_source_func = None
436
-
437
- # Figure out which api endpoint to use.
438
- if client_options .api_endpoint is not None :
439
- api_endpoint = client_options .api_endpoint
440
- else :
441
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
442
- if use_mtls_env == "never" :
443
- api_endpoint = self .DEFAULT_ENDPOINT
444
- elif use_mtls_env == "always" :
445
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
446
- elif use_mtls_env == "auto" :
447
- if is_mtls :
448
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
449
- else :
450
- api_endpoint = self .DEFAULT_ENDPOINT
451
- else :
452
- raise MutualTLSChannelError (
453
- "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
454
- "values: never, auto, always"
455
- )
483
+ api_key_value = getattr (client_options , "api_key" , None )
484
+ if api_key_value and credentials :
485
+ raise ValueError (
486
+ "client_options.api_key and credentials are mutually exclusive"
487
+ )
456
488
457
489
# Save or instantiate the transport.
458
490
# Ordinarily, we provide the transport, but allowing a custom transport
459
491
# instance provides an extensibility point for unusual situations.
460
492
if isinstance (transport , CloudBuildTransport ):
461
493
# transport is a CloudBuildTransport instance.
462
- if credentials or client_options .credentials_file :
494
+ if credentials or client_options .credentials_file or api_key_value :
463
495
raise ValueError (
464
496
"When providing a transport instance, "
465
497
"provide its credentials directly."
@@ -471,6 +503,15 @@ def __init__(
471
503
)
472
504
self ._transport = transport
473
505
else :
506
+ import google .auth ._default # type: ignore
507
+
508
+ if api_key_value and hasattr (
509
+ google .auth ._default , "get_api_key_credentials"
510
+ ):
511
+ credentials = google .auth ._default .get_api_key_credentials (
512
+ api_key_value
513
+ )
514
+
474
515
Transport = type (self ).get_transport_class (transport )
475
516
self ._transport = Transport (
476
517
credentials = credentials ,
0 commit comments