0
votes

I'm using Gmail-api to retrieve emails from the reception box and I 'm faced to this error since some time : googleapiclient.errors.HttpError: <HttpError 429 when requesting https://gmail.googleapis.com/gmail/v1/users/***/?alt=json returned "User-rate limit exceeded. Given that the json of the error indicated in the link is:

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED"
  }
}

I'm wondering if this error is due to expired credentials or per-user rate limits reached or some thing else. If the error is due to exired credentials, how can I automatically refresh them via python code. If not, what is the solution?

The code to establish connection to gmail_api is as below:

def connect(self):
    SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
    SERVICE_ACCOUNT_FILE = 'credentials.json'

    # The user we want to "impersonate"
    USER_EMAIL = "[email protected]"

    credentials = service_account.Credentials. \
        from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    delegated_credentials = credentials.with_subject(USER_EMAIL)

    service = discovery.build('gmail', 'v1', credentials=delegated_credentials)

    
    return service

After that I get the emails list to process :

def emails_list_by_labels(self, service, user_id='me', label_ids=[]):
    try:
        response = service.users().messages().list(userId=user_id,
                                                   labelIds=label_ids).execute()
        messages = []
        if 'messages' in response:
            messages.extend(response['messages'])
        while 'nextPageToken' in response:
            page_token = response['nextPageToken']
            response = self.service.users().messages().list(userId=user_id,
                                                            labelIds=label_ids,
                                                            pageToken=page_token).execute()
            messages.extend(response['messages'])
        return messages
    except errors.HttpError as error:
        logging.error('an error occured: %s' % error)

If somebody have any suggestions , i 'll appreciate. I really don't know how to solve this issue.

1
Did you set up domain wide delegation on the service account?DaImTo

1 Answers

0
votes

Looking at your error message -

HttpError 429 when requesting https://gmail.googleapis.com/gmail/v1/users/***/?alt=json returned "User-rate limit exceeded

The link in there is not meant to be 'clicked', it is the url of the failing request. You get an unauthenticated error when trying to access it since you are not authenticated to view it, but your app is so it doesn't have that issue.

The issue your app is running into is too many requests, as indicated by the 429 error. Details for it can be viewed here. You will have to investigate the exact cause for the error and look into finding the appropriate solution from there - exponential backoff, caching, etc.