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