@@ -353,6 +353,24 @@ def _get_external_account_credentials(
353353 return credentials , credentials .get_project_id (request = request )
354354
355355
356+ def _get_api_key_credentials (quota_project_id = None ):
357+ """Gets API key credentials and project ID."""
358+ from google .auth import api_key
359+
360+ api_key_value = os .environ .get (environment_vars .API_KEY )
361+ if api_key_value :
362+ return api_key .Credentials (api_key_value ), quota_project_id
363+ else :
364+ return None , None
365+
366+
367+ def get_api_key_credentials (api_key_value ):
368+ """Gets API key credentials using the given api key value."""
369+ from google .auth import api_key
370+
371+ return api_key .Credentials (api_key_value )
372+
373+
356374def default (scopes = None , request = None , quota_project_id = None , default_scopes = None ):
357375 """Gets the default credentials for the current environment.
358376
@@ -361,7 +379,14 @@ def default(scopes=None, request=None, quota_project_id=None, default_scopes=Non
361379 This function acquires credentials from the environment in the following
362380 order:
363381
364- 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
382+ 1. If both ``GOOGLE_API_KEY`` and ``GOOGLE_APPLICATION_CREDENTIALS``
383+ environment variables are set, throw an exception.
384+
385+ If ``GOOGLE_API_KEY`` is set, an `API Key`_ credentials will be returned.
386+ The project ID returned is the one defined by ``GOOGLE_CLOUD_PROJECT`` or
387+ ``GCLOUD_PROJECT`` environment variables.
388+
389+ If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
365390 to the path of a valid service account JSON private key file, then it is
366391 loaded and returned. The project ID returned is the project ID defined
367392 in the service account file if available (some older files do not
@@ -409,6 +434,7 @@ def default(scopes=None, request=None, quota_project_id=None, default_scopes=Non
409434 .. _Metadata Service: https://cloud.google.com/compute/docs\
410435 /storing-retrieving-metadata
411436 .. _Cloud Run: https://cloud.google.com/run
437+ .. _API Key: https://cloud.google.com/docs/authentication/api-keys
412438
413439 Example::
414440
@@ -444,16 +470,25 @@ def default(scopes=None, request=None, quota_project_id=None, default_scopes=Non
444470 invalid.
445471 """
446472 from google .auth .credentials import with_scopes_if_required
473+ from google .auth .credentials import CredentialsWithQuotaProject
447474
448475 explicit_project_id = os .environ .get (
449476 environment_vars .PROJECT , os .environ .get (environment_vars .LEGACY_PROJECT )
450477 )
451478
479+ if os .environ .get (environment_vars .API_KEY ) and os .environ .get (
480+ environment_vars .CREDENTIALS
481+ ):
482+ raise exceptions .DefaultCredentialsError (
483+ "Environment variables GOOGLE_API_KEY and GOOGLE_APPLICATION_CREDENTIALS are mutually exclusive"
484+ )
485+
452486 checkers = (
453487 # Avoid passing scopes here to prevent passing scopes to user credentials.
454488 # with_scopes_if_required() below will ensure scopes/default scopes are
455489 # safely set on the returned credentials since requires_scopes will
456490 # guard against setting scopes on user credentials.
491+ lambda : _get_api_key_credentials (quota_project_id = quota_project_id ),
457492 lambda : _get_explicit_environ_credentials (quota_project_id = quota_project_id ),
458493 lambda : _get_gcloud_sdk_credentials (quota_project_id = quota_project_id ),
459494 _get_gae_credentials ,
@@ -477,7 +512,9 @@ def default(scopes=None, request=None, quota_project_id=None, default_scopes=Non
477512 request = google .auth .transport .requests .Request ()
478513 project_id = credentials .get_project_id (request = request )
479514
480- if quota_project_id :
515+ if quota_project_id and isinstance (
516+ credentials , CredentialsWithQuotaProject
517+ ):
481518 credentials = credentials .with_quota_project (quota_project_id )
482519
483520 effective_project_id = explicit_project_id or project_id
0 commit comments