My favorites | English | Sign in

Google Contacts Data API

Developer's Guide: Python

The Contacts Data API allows client applications to view and update a user's contacts. Contacts are stored in the user's Google Account; most Google services have access to the contact list.

Your client application can use the Contacts Data API to create new contacts, edit or delete existing contacts, and query for contacts that match particular criteria.

In addition to providing some background on the capabilities of the Contacts Data API, this document provides examples of how to interact with contacts using the Python client library. If you're interested in understanding more about the underlying protocol that the library uses, see the Protocol section of this developer's guide.

Contents

Audience

This document is intended for programmers who want to write Python client applications that can interact with Google's contact lists.

This document assumes that you understand the general ideas behind the Google Data APIs protocol.

For reference information about the classes and methods provided by the client library, see the pydocs for the Contacts modules. For general Contacts Data API reference information, see the Protocol reference guide.

Getting started

For help setting up the client library, see the Getting Started Guide.

The Python client library requires Python 2.2 or higher. After downloading the client library, you'll find the modules you need to get started in the src/gdata/contacts directory.

Creating a Google Account

You may want to sign up for a Google Account for testing purposes. Contacts are associated with Google Accounts, so if you already have a Google Account, you're all set.

Note: To view your contacts without using the Contacts Data API, you can log in to Gmail and click the Contacts link.

Running the sample code

A full working sample client, containing all the sample code shown in this document, is available in the Python client library distribution, under the directory samples/contacts/contacts_example.py.

The sample client performs several operations on contacts to demonstrate the use of the Contacts Data API.

To run the examples in this document in your own code, you'll need the following import statements:

import atom
import gdata.contacts
import gdata.contacts.service

Authenticating

All Contacts Data API feeds are private. Thus, your client needs to authenticate before accessing a contacts feed. It can authenticate using either of two approaches: ClientLogin username/password authentication or AuthSub proxy authentication.

For more information about authentication with Google Data APIs in general, see the authentication documentation.

AuthSub proxy authentication

AuthSub proxy authentication is used by web applications that need to authenticate their users to Google Accounts. The website operator and the client code don't have access to the username and password for the user; instead, the client obtains special AuthSub tokens that allow the client to act on a particular user's behalf. For more detailed information, see the AuthSub documentation.

When a user first visits your application, they have not yet been authenticated. In this case, you need to display some information and a link directing the user to a Google page to authenticate your request for access to their contacts. The Python client library provides a function to generate the Google page's URL called GenerateAuthSubURL. The code below retrieves the URL of the AuthSubRequest page:

next = 'http://www.example.com/welcome.py'
scope = 'http://www.google.com/m8/feeds/'
secure = False
session = True
authSubLogin = gd_client.GenerateAuthSubURL(next, scope, secure, session)

The GenerateAuthSubURL method takes the following parameters (corresponding to the query parameters:

next
The URL of the page that Google should redirect the user to after authentication.
scope
Indicates that the application is requesting a token to access contacts feeds. The scope string to use is http://www.google.com/m8/feeds/.
secure
Indicates whether the client is requesting a secure token.
session
Indicates whether the token returned can be exchanged for a multi-use (session) token.

The above example shows a call that doesn't request a secure token (the value of secure is False). The resulting request URL might look like this:

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.example.com%2Fwelcome.py

The user follows the link to Google's site and authenticates to their Google Account.

After the user authenticates, the AuthSub system redirects them to the URL you specified in the next query parameter of the AuthSubRequest URL. The AuthSub system appends an authentication token to that URL, as the value of the token query parameter. For example:

http://www.example.com/welcome.py?token=yourAuthToken

This token value represents a single-use AuthSub token. In this example, since session = True was specified, this token can be exchanged for an AuthSub session token by calling UpgradeToSessionToken with the single-use token in an Authorization header, as follows, where token is the token URL parameter that AuthSub appended the next URL:

import cgi
parameters = cgi.FieldStorage()
authsub_token = parameters['token']

gd_client = gdata.contacts.service.ContactsService()
gd_client.auth_token = authsub_token
gd_client.UpgradeToSessionToken()

That is, you set your one-time-use token then call the UpgradeToSessionToken method. For more information about registered applications and private keys, refer to the "Signing requests" section of the AuthSub documentation.

Your application can then use the session token value in subsequent interactions with contacts. The client library automatically sends the token along with requests.

ClientLogin username/password authentication

Use ClientLogin authentication if your client is a standalone, single-user "installed" client (such as a desktop application). Just call the ClientLogin or ProgrammaticLogin method on your ContactsService object and all subsequent interactions with contacts will be authenticated:

gd_client = gdata.contacts.service.ContactsService()
gd_client.email = email
gd_client.password = password
gd_client.source = 'exampleCo-exampleApp-1'
gd_client.ProgrammaticLogin()

For more information about ClientLogin authentication, including sample requests and responses, see the Account Authentication for Installed Applications documentation.

Creating contacts

You can use the Python client library to add new contact entries.

First, create a ContactEntry object to represent the contact. Then you can set the name, notes and other attributes of the contact. Finally, use the ContactsService object to insert the contact. Here's an example of how to publish a new contact:

new_contact = gdata.contacts.ContactEntry(title=atom.Title(text=name))
new_contact.content = atom.Content(text=notes)
# Create a work email address for the contact and use as primary.
new_contact.email.append(gdata.contacts.Email(address=primary_email,
    primary='true', rel=gdata.contacts.REL_WORK))
# Add extended properties to add data which is used in your application.
new_contact.extended_property.append(gdata.ExtendedProperty(
    name='favourite flower', value='daisy'))
sports_property = gdata.ExtendedProperty(name='sports')
sports_property.SetXmlBlob('<dance><salsa/><ballroom_dancing/></dance>')
new_contact.extended_property.append(sports_property)

# Send the contact data to the server.
contact_entry = gd_client.CreateContact(new_contact)

The CreateContact method takes the service's post URL as an optional parameter. If omitted, the new contact POST request is sent to the default URL ('/m8/feeds/contacts/default/base'). Then the method returns the entry as it was stored by the server. The entry returned is the same one you sent, but it also contains various elements added by the server, such as a contact ID.

If your request fails for some reason, Google may return a different status code. For information about the status codes, see the Google Data API protocol reference document. If you attempt to create a contact with the same primary email as a preexisting contact, the server will return a 409 conflict error.

Note: A photo cannot be added to a contact while creating the contact.

Adding a photo for a contact

To add a photo to an existing contact, you can use the ChangePhoto method. When adding a photo, you must specify the content_type to describe the type of the image data. The content_type can be specififed as a parameter when calling ChangePhoto, or as a member of a MediaSource object.

Example of adding a photo in a jpg format:

image_filename = 'my_picture.jpg'
photo_metadata = gd_client.ChangePhoto(image_filename, contact_entry, content_type='image/jpeg')

Retrieving contacts

Retrieving all contacts

To retrieve the user's contacts, call the GetContactsFeed method with the contact feed URL. If no URL is specified, GetContactsFeed will use the default feed to get the contacts of the authenticated user.

def PrintFeed(feed):
  for i, entry in enumerate(feed.entry):
    print '\n%s %s' % (i+1, entry.title.text)
    if entry.content:
      print '    %s' % (entry.content.text)
    # Display the primary email address for the contact.
    for email in entry.email:
      if email.primary and email.primary == 'true':
        print '    %s' % (email.address)
    # Show the contact groups that this contact is a member of.
    for group in entry.group_membership_info:
      print '    Member of group: %s' % (group.href)
    # Display extended properties.
    for extended_property in entry.extended_property:
      if extended_property.value:
        value = extended_property.value
      else:
        value = extended_property.GetXmlBlobString()
      print '    Extended Property - %s: %s' % (extended_property.name, value)
feed = gd_client.GetContactsFeed()
PrintFeed(feed)

Note: The feed may not contain all of the user's contacts, because there's a default limit on the number of results returned. For more information, see the max_results query argument in Retrieving contacts using query parameters.

Retrieving contacts using query parameters

The Contacts Data API lets you request a set of contacts that match specified criteria, such as requesting contacts created or updated in a given date range, or published by a particular author. To do this, you create a ContactsQuery object and pass it to the ContactsService.GetContactsFeed(query_object.ToUri()) method.

For example, to send a date-range query, set the updated_min property of the ContactsQuery object. The following code snippet prints the title, note, and primary email address of each contact updated after the given start time:

updated_min = raw_input(
    'Enter updated min (example: 2007-03-16T00:00:00): ')
query = gdata.contacts.service.ContactsQuery()
query.updated_min = updated_min
feed = gd_client.GetContactsFeed(query.ToUri())
# Use the print feed method defined above.
PrintFeed(feed)

Notice that the ContactsQuery object has a feed member which represents the base URL of the query. It uses the same default URL as GetContactsFeed.

The Contacts Data API supports the following ContactsQuery properties:

query.max_results
Set the maximum number of entries to return.
query.start_index
Set the 1-based index of the first result to be retrieved (for paging).
query.updated_min
Set the lower bound on entry update dates.
query['showdeleted'] = 'true'
Include deleted contacts in the returned contacts feed. Deleted contacts are shown as entries that contain nothing but an <atom:id> element and a <gd:deleted> element. (Google retains placeholders for deleted contacts for 30 days after deletion; during that time, you can request the placeholders using the showdeleted query parameter.)
query.orderby = 'lastmodified'
Sort the returned contacts by last-modified date.
query['sortorder'] = direction
Set sorting order direction. direction can be either "ascending" or "descending".

Note: To track incremental changes to a contact list, do the following: When you send a request for a feed, keep track of the value of the feed's <updated> element. Then you can later retrieve only the contacts that have changed since the previous request by setting updated-min to that <updated> value, and setting showdeleted to true.

For more information about query parameters, see the Contacts Data API Reference Guide and the Google Data APIs Reference Guide. In particular, there is no support for full-text queries or locating a contact by email address.

Note: By default, the entries in a feed are not ordered.

Retrieving a photo for a contact

You can download the photo data for one of your contacts by using the GetPhoto method. GetPhoto will return the binary data for the image, which you can then write to a file.

Here is an example of using GetPhoto with a contacy entry that you have retrieved earlier:

hosted_image_binary = gd_client.GetPhoto(contact_entry)
image_file = open('test.jpg', 'wb')
image_file.write(hosted_image_binary)
image_file.close()

Updating contacts

To update an existing contact, first retrieve the entry you want to update, modify it, and then send it to the server using the UpdateContact method. The following code snippet modifies a contact's name, assuming that you've already retrieved the contact from the server.

Note: In the underlying XML, the contact's name is stored in the <atom:title> element.

new_name = raw_input('Enter a new name for the contact: ')
if not selected_entry.title:
  selected_entry.title = atom.Title()
selected_entry.title.text = new_name
gd_client.UpdateContact(selected_entry.GetEditLink().href, selected_entry)

The above code returns a ContactEntry containing the entire newly-updated post. To update any other properties, simply set them in the ContactEntry object before calling UpdateContact.

Photo management

Updating a photo is the same as adding a photo.

Deleting contacts

To delete a contact, pass the contact's edit URL to the DeleteContact method on your ContactsService object, like this:

gd_client.DeleteContact(selected_entry.GetEditLink().href)

Note: To update existing contacts, see Updating contacts; don't update by deleting contacts and then re-adding them.

Creating contact groups

You can use the Python client library to publish new contact group entries. Contact groups are available as a way to organize your contacts, and each contact lists the groups it belongs to.

Here's an example of how to publish a new contact group:

new_group = gdata.contacts.GroupEntry(title=atom.Title(text='my best friends'))
group_entry = gd_client.CreateGroup(new_group)

First, create a GroupEntry object and set a name and other attributes for the contact group. Then use the ContactsService object to insert the contact group. The CreateGroup method takes the new GroupEntry object and will use a default value for the POST URL if a insert_uri is not specificed, as in the above example. The method returns the entry as it was stored by the server. The entry returned is the entry you sent with additional elements added by the server, such as a contact group ID, edit link, and others.

If your request fails for some reason, Google may return a different status code. For information about the status codes, see the Google Data API protocol reference document.

Retrieving contact groups

Retrieving all contact groups

Sample code to retrieve the user's contact groups:

def PrintGroupsFeed(feed):
  for i, entry in enumerate(feed.entry):
    print '\n%s %s' % (i+1, entry.title.text)
    # Display the group id which can be used to query the contacts feed.
    print '    Group ID: %s' % entry.id.text
    # Display extended properties.
    for extended_property in entry.extended_property:
      if extended_property.value:
        value = extended_property.value
      else:
        value = extended_property.GetXmlBlobString()
      print '    Extended Property %s: %s' % (extended_property.name, value)

# Request the list of the current user's contact groups.
feed = gd_client.GetGroupsFeed()
PrintGroupsFeed(feed)

Retrieving contact groups using query parameters

The Contacts Data API supports the same Query methods allowed for contacts for contact groups, except for the group parameter.

Sample code to retrieve contact groups which have been updated since the updated_min value:

updated_min = raw_input(
    'Enter updated min (example: 2007-03-16T00:00:00): ')
query = gdata.service.Query(feed='/m8/feeds/groups/default/full')
query.updated_min = updated_min
feed = gd_client.GetGroupsFeed(query.ToUri())
PrintGroupsFeed(feed)

Updating contact groups

To update an existing contact group, first you retrieve the entry you want to update, then modify it, and, finally, send it to the server using the UpdateGroup method. The following code snippet modifies a contact group's name, assuming that you've already retrieved the group from the server.

# Change the name of the group.
group_entry.title.text = 'new group name'
# Send the modified group entry to the server and replace the current 
# group_entry with new data from the server.
group_entry = self.gd_client.UpdateGroup(group_entry.GetEditLink().href, group_entry)

The above code returns a GroupEntry containing the entire newly-updated group data. To update any other properties, simply set them in the GroupEntry object before calling UpdateGroup.

Note: 409 error code can be returned if you are trying to update a contact group and are using an old edit URI - this could happen when the contact group was updated after the edit URI was saved.

Deleting contact groups

Deleting a contact group can look like this:

gd_client.DeleteGroup(group_entry.GetEditLink().href)

Note: To update existing contact groups, see Updating contact groups; don't update by deleting contact groups and then re-adding them.

Back to top