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