CoreyG
CoreyG

Reputation: 51

Python Error "TypeError: Got an unexpected keyword argument 'attachmentId'"

I am trying to pull an attachment from an email from gmail using their API and have run into an unexpected keyword argument when trying to plug in a variable. I am very used to Javascript so that is probably why I am running into this error and getting it wrong but here is the relevant block of code:

def main():

    credentials = get_credentials()
    gsa = gspread.authorize(credentials)
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)

    query = ['plc/trending/31day']

    for x in query:

        results = service.users().messages().list(userId='me', labelIds=None, q='label:' + x, pageToken=None, maxResults=1, includeSpamTrash=None).execute()
        mesgid = results['messages'][0]['id']
        attresults = service.users().messages().get(userId='me', id=mesgid, format=None, metadataHeaders=None).execute()
        attid = attresults['payload']['parts'][1]['body']['attachmentId']
        grabattachment = service.users().messages().attachments().get(userId='me', messageId = mesgid, attachmentId = attid)

Upvotes: 0

Views: 3751

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122372

The official documentation states that the id of an attachment is named id, not attachmentId:

grabattachment = service.users().messages().attachments().get(userId='me', messageId = mesgid, id = attid)

You probably want to cache the service.users().messages() and deeper calls like .attachments() and avoid having to call so many objects each time:

messages = service.users().messages()
for x in query:
    results = messages.list(
        userId='me', labelIds=None, q='label:' + x, 
        pageToken=None, maxResults=1, 
        includeSpamTrash=None).execute()
    mesgid = results['messages'][0]['id']
    attresults = messages.get(
        userId='me', id=mesgid, format=None, 
        metadataHeaders=None).execute()
    attid = attresults['payload']['parts'][1]['body']['attachmentId']
    grabattachment = messages.attachments().get(
        userId='me', messageId=mesgid,
        attachmentId=attid)

I also strongly suspect that you are missing the .execute() call at the end.

I also have the impression taht the messages.list() call already contains enough information to retrieve the attachment without requiring a separate messages.get() call:

messages = service.users().messages()
for x in query:
    results = messages.list(
        userId='me', labelIds=None, q='label:' + x, 
        pageToken=None, maxResults=1, 
        includeSpamTrash=None).execute()
    attid = results['messages'][0]['payload']['parts'][1]['body']['attachmentId']
    grabattachment = messages.attachments().get(
        userId='me', messageId=mesgid,
        attachmentId=attid).execute()

Personally, I would still test for multiple attachments, checking if each has a filename before loading the attachment data.

Upvotes: 1

Related Questions