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