@@ -283,6 +283,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
283
283
m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
284
284
return m .groupdict () if m else {}
285
285
286
+ @classmethod
287
+ def get_mtls_endpoint_and_cert_source (
288
+ cls , client_options : Optional [client_options_lib .ClientOptions ] = None
289
+ ):
290
+ """Return the API endpoint and client cert source for mutual TLS.
291
+
292
+ The client cert source is determined in the following order:
293
+ (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
294
+ client cert source is None.
295
+ (2) if `client_options.client_cert_source` is provided, use the provided one; if the
296
+ default client cert source exists, use the default one; otherwise the client cert
297
+ source is None.
298
+
299
+ The API endpoint is determined in the following order:
300
+ (1) if `client_options.api_endpoint` if provided, use the provided one.
301
+ (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
302
+ default mTLS endpoint; if the environment variabel is "never", use the default API
303
+ endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
304
+ use the default API endpoint.
305
+
306
+ More details can be found at https://google.aip.dev/auth/4114.
307
+
308
+ Args:
309
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
310
+ client. Only the `api_endpoint` and `client_cert_source` properties may be used
311
+ in this method.
312
+
313
+ Returns:
314
+ Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
315
+ client cert source to use.
316
+
317
+ Raises:
318
+ google.auth.exceptions.MutualTLSChannelError: If any errors happen.
319
+ """
320
+ if client_options is None :
321
+ client_options = client_options_lib .ClientOptions ()
322
+ use_client_cert = os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
323
+ use_mtls_endpoint = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
324
+ if use_client_cert not in ("true" , "false" ):
325
+ raise ValueError (
326
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
327
+ )
328
+ if use_mtls_endpoint not in ("auto" , "never" , "always" ):
329
+ raise MutualTLSChannelError (
330
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
331
+ )
332
+
333
+ # Figure out the client cert source to use.
334
+ client_cert_source = None
335
+ if use_client_cert == "true" :
336
+ if client_options .client_cert_source :
337
+ client_cert_source = client_options .client_cert_source
338
+ elif mtls .has_default_client_cert_source ():
339
+ client_cert_source = mtls .default_client_cert_source ()
340
+
341
+ # Figure out which api endpoint to use.
342
+ if client_options .api_endpoint is not None :
343
+ api_endpoint = client_options .api_endpoint
344
+ elif use_mtls_endpoint == "always" or (
345
+ use_mtls_endpoint == "auto" and client_cert_source
346
+ ):
347
+ api_endpoint = cls .DEFAULT_MTLS_ENDPOINT
348
+ else :
349
+ api_endpoint = cls .DEFAULT_ENDPOINT
350
+
351
+ return api_endpoint , client_cert_source
352
+
286
353
def __init__ (
287
354
self ,
288
355
* ,
@@ -333,57 +400,22 @@ def __init__(
333
400
if client_options is None :
334
401
client_options = client_options_lib .ClientOptions ()
335
402
336
- # Create SSL credentials for mutual TLS if needed.
337
- if os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not in (
338
- "true" ,
339
- "false" ,
340
- ):
341
- raise ValueError (
342
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
343
- )
344
- use_client_cert = (
345
- os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) == "true"
403
+ api_endpoint , client_cert_source_func = self .get_mtls_endpoint_and_cert_source (
404
+ client_options
346
405
)
347
406
348
- client_cert_source_func = None
349
- is_mtls = False
350
- if use_client_cert :
351
- if client_options .client_cert_source :
352
- is_mtls = True
353
- client_cert_source_func = client_options .client_cert_source
354
- else :
355
- is_mtls = mtls .has_default_client_cert_source ()
356
- if is_mtls :
357
- client_cert_source_func = mtls .default_client_cert_source ()
358
- else :
359
- client_cert_source_func = None
360
-
361
- # Figure out which api endpoint to use.
362
- if client_options .api_endpoint is not None :
363
- api_endpoint = client_options .api_endpoint
364
- else :
365
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
366
- if use_mtls_env == "never" :
367
- api_endpoint = self .DEFAULT_ENDPOINT
368
- elif use_mtls_env == "always" :
369
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
370
- elif use_mtls_env == "auto" :
371
- if is_mtls :
372
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
373
- else :
374
- api_endpoint = self .DEFAULT_ENDPOINT
375
- else :
376
- raise MutualTLSChannelError (
377
- "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
378
- "values: never, auto, always"
379
- )
407
+ api_key_value = getattr (client_options , "api_key" , None )
408
+ if api_key_value and credentials :
409
+ raise ValueError (
410
+ "client_options.api_key and credentials are mutually exclusive"
411
+ )
380
412
381
413
# Save or instantiate the transport.
382
414
# Ordinarily, we provide the transport, but allowing a custom transport
383
415
# instance provides an extensibility point for unusual situations.
384
416
if isinstance (transport , CloudFunctionsServiceTransport ):
385
417
# transport is a CloudFunctionsServiceTransport instance.
386
- if credentials or client_options .credentials_file :
418
+ if credentials or client_options .credentials_file or api_key_value :
387
419
raise ValueError (
388
420
"When providing a transport instance, "
389
421
"provide its credentials directly."
@@ -395,6 +427,15 @@ def __init__(
395
427
)
396
428
self ._transport = transport
397
429
else :
430
+ import google .auth ._default # type: ignore
431
+
432
+ if api_key_value and hasattr (
433
+ google .auth ._default , "get_api_key_credentials"
434
+ ):
435
+ credentials = google .auth ._default .get_api_key_credentials (
436
+ api_key_value
437
+ )
438
+
398
439
Transport = type (self ).get_transport_class (transport )
399
440
self ._transport = Transport (
400
441
credentials = credentials ,
0 commit comments