Search code examples
pythongmail-apigoogle-api-python-client

GMail API using Python Google API Client: error 400, failed precondition


I am trying to access our GSuite GMail API using Google API Python Client with service account authentication. According to the docs, my MCVE code is as follows:

import os
import sys
from google.auth.transport.requests import Request
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

email = sys.argv[1]

cred = Credentials.from_service_account_file(os.getenv('SERVICE_ACCOUNT'))
cred = cred.with_scopes(['https://www.googleapis.com/auth/gmail.labels'])
cred.refresh(Request())

gmail = build('gmail', 'v1', credentials=cred)
try:
    print(gmail.users().labels().list(userId=email).execute())
except Exception as ex:
    print('Error:', ex.content.decode('ascii'))

The output is:

Error: {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "failedPrecondition",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}

The usual suspects:

  • The service account is granted the domain-wide delegation
  • The requested email exists
  • The client scopes are configured in "Admin > Security > Advanced > Manage API client access"

access settings

Another observation: when I access the API, the usage counter increases for the service account, but remains 0 for the corresponding OAuth2 client.

What else can I be missing?


Solution

  • What was missing, is one little piece mentioned in the documentation. In addition to setting the scopes, I need to impersonate a user account by calling with_subject:

    cred = cred.with_subject(email)
    

    After that it works as expected, hope that helps someone.