wyang
wyang

Reputation: 57

base64 decoding using Python with attachment downloaded with REST-based Gmail API

I've tried to use the new Gmail api to download an image attachment from a particular email message part. (https://developers.google.com/gmail/api/v1/reference/users/messages/attachments#resource).

The message part is:

{u'mimeType': u'image/png', u'headers': {u'Content-Transfer-Encoding': [u'base64'], u'Content-Type': [u'image/png; name="Screen Shot 2014-03-11 at 11.52.53 PM.png"'], u'Content-Disposition': [u'attachment; filename="Screen Shot 2014-03-11 at 11.52.53 PM.png"'], u'X-Attachment-Id': [u'f_hso95l860']}, u'body': {u'attachmentId': u'', u'size': 266378}, u'partId': u'1', u'filename': u'Screen Shot 2014-03-11 at 11.52.53 PM.png'}

The GET response of Users.messages.attachments is:

{ "data": "", "size": 194659 }

When I decoded the data in Python as follows:

decoded_data1 = base64.b64decode(resp["data"])
decoded_data2 = email.utils._bdecode(resp["data"]) # email, the standard module
with open("image1.png", "w") as f:
    f.write(decoded_data1)
with open("image2.png", "w") as f:
    f.write(decoded_data2)

Both the file image1.png and image2.png have size 188511 and they are invalid png files as I couldn't open them in image viewer. Am I not using the correct base64 decoding for MIME body?

Upvotes: 2

Views: 4444

Answers (3)

Stephen Bealer
Stephen Bealer

Reputation: 31

I'd also like to note that you'll likely want to write binary. Such as:

f = open(path, 'w')

should be:

f = open(path, 'wb')

Upvotes: 2

Eric D
Eric D

Reputation: 7159

You need to use urlsafe base64 decoding. so base64.urlsafe_b64decode() should do it.

Upvotes: 2

johntellsall
johntellsall

Reputation: 15170

hmm. The Gmail API looks a bit different from the standard Python email module, but I did find an example of how to download and store an attachment:

https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get#examples

example

for part in message['payload']['parts']:
      if part['filename']:

        file_data = base64.urlsafe_b64decode(part['body']['data']
                                             .encode('UTF-8'))

        path = ''.join([store_dir, part['filename']])

        f = open(path, 'w')
        f.write(file_data)
        f.close()

Upvotes: 7

Related Questions