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