0
votes

The response after I sent out my batch request to the gmail is the same as described in the documentation (https://developers.google.com/gmail/api/guides/handle-errors#exponential-backoff):

  "error": {
    "errors": [
      {
        "domain": "global",
        "reason": "authError",
        "message": "Invalid Credentials",
        "locationType": "header",
        "location": "Authorization",
      }
    ],
    "code": 401,
    "message": "Invalid Credentials"
  }
}

My request code is:

creds = None

# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)

# If there are no (valid) credentials available, let the user log in.

elif not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
        creds = flow.run_local_server(port=0)

    # Save the credentials for the next run.
    with open('token.pickle', 'wb') as token:
        pickle.dump(creds, token)


gmailUrl = "https://gmail.googleapis.com/batch/gmail/v1"

request_header = {"Authorization": f"Bearer {creds}", "Host": "www.googleapis.com", "Content-Type": "multipart/mixed; boundary=boundary"}

body = []

for n in message_Ids:
    boundary = "--boundary\n"
    content_type = "Content-Type: application/http\n\n"
    request = f'GET /gmail/v1/users/me/messages/{n}\n'
    requestObj = boundary + content_type + request + "Accept: application/json; charset=UTF-8\n"
    body.append(requestObj)
body.append("--boundary")

body = "\n".join(body)

response = req.post(url=gmailUrl, headers=request_header, data=body, auth=)
pprint(response)
pprint(response.text)

As I managed to somehow get a response from the gmail server I suppose my request got accepted. But I do not understand why I get the 401 error. If I send the GET requests as single ones my application works fine.

What do I have to put in the "Autorization": f"Bearer {creds}" line?

Thanks in advance!

2
Is there are reason why you're not using the official library? Can you provide the code related to creds?Iamblichus
There is no batch request in the gmail library for the get-method. See the documentation: developers.google.com/gmail/api/guides/batchMxngls
Batch requests are supported in the library, ref. Also, at "Autorization": f"Bearer {creds}" you should provide the access token, and you are providing your instance of credentials instead. To provide the access token, use creds.token, so "Autorization": f"Bearer {creds.token}" instead.Iamblichus
Thanks! I do not quite understand the documentation in the link you provided. I managed to construct a custom batch request myself, but the method you linked to seems to be quite simpler. Unfortunately I don't quite understand the documentation. What is meant with callback or request ID? The example in here: googleapis.github.io/google-api-python-client/docs/batch.html doesn't get me any further.Mxngls
I managed to get it work! But I don't seem to really understand it which really bothers me.Mxngls

2 Answers

1
votes

As mentioned in comments, you were providing an instance of credentials in the Authorization header:

"Authorization": f"Bearer {creds}"

You should provide the credentials' access_token instead:

"Authorization": f"Bearer {creds.token}"

Reference:

0
votes

As pointed out in the comments below my question my mistake was that I did provide an instance of the credentials, not the token itself.