Search code examples
pythongoogle-apibase64google-contacts-api

Pushing base64 encoded image to Google Contacts with Python


I have a base64 encoded jpeg image which I want to push as a Google Contact photo using the API which is explained here: Updating a photo for a contact.

Looking at the documentation for the ChangePhoto method gives the following:

Type:        instancemethod
String form: <bound method ContactsClient.change_photo of <gdata.contacts.client.ContactsClient object at 0x104756090>>
File:        /Library/Python/2.7/site-packages/gdata/contacts/client.py
Definition:  a.ChangePhoto(self, media, contact_entry_or_url, content_type=None, content_length=None, auth_token=None, **kwargs)
Docstring:
Change the photo for the contact by uploading a new photo.

Performs a PUT against the photo edit URL to send the binary data for the
photo.

Args:
  media: filename, file-like-object, or a gdata.data.MediaSource object to send.
  contact_entry_or_url: ContactEntry or str If it is a ContactEntry, this
                        method will search for an edit photo link URL and
                        perform a PUT to the URL.
  content_type: str (optional) the mime type for the photo data. This is
                necessary if media is a file or file name, but if media
                is a MediaSource object then the media object can contain
                the mime type. If media_type is set, it will override the
                mime type in the media object.
  content_length: int or str (optional) Specifying the content length is
                  only required if media is a file-like object. If media
                  is a filename, the length is determined using
                  os.path.getsize. If media is a MediaSource object, it is
                  assumed that it already contains the content length.

My problem here is, that I do not have a file-like-object. I guess that my only option then is to create a gdata.data.MediaSource object. The problem with this is that I can't find any good documentation on how to construct such an object correct.

How do I construct such a gdata.data.MediaSource object from my base64-encoded image. How do I specify the content_type and the content_length correctly?


Solution

  • Python offers you in-memory file-like objects. On Python 2, use cStringIO.StringIO (with a fallback to StringIO.StringIO in the rare cases the C-optimised version is missing):

    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO
    
    image_data = your_image_data.decode('base64')
    image_file = StringIO(image_data)
    
    a.ChangePhoto(
        image_file, contact_url, content_type='image/jpg',
        content_length=len(image_data))
    

    I do assume that your Base64-encoded image data (stored in your_image_data is straight-up encoded, not a data URI.