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