English | Site Directory

Google Base Data API

Using the Google Base data API Python Client Library

Google provides an extension to the Google data Python Client Library that helps connect to the Google Base feeds and interprets the result. For help setting up the client library, see the Client Library Getting Started Guide.

This client library is by no means the only way of connecting to the Google Base API server. You can achieve the same result using an Atom or XML parser.

Contents

  1. Audience
  2. Introduction
  3. Setting up
  4. Executing a query and interpreting the results
    1. Attributes and types
    2. Accessing the itemtypes feed
    3. Accessing the attributes feed
  5. Authenticating
  6. Inserting items
    1. Choosing which attributes to use
  7. Updating items
  8. Deleting items
  9. Handling errors
  10. Reference

Audience

This document assumes that you know Python programming, and that you are familiar with the basic concepts of Google Base.

Introduction

The Google Base client library extends the Google data client library and adds some Google Base-specific objects to make it easier to use. It tries to stick to the XML representation.

The XML element in a feed or entry corresponds to a single Python Object in the library. For example, both the <atom:feed> element and the <atom:entry> element corresponds to a GBaseItem.

Google Base extends the Google data feeds with elements from the g namespace (http://base.google.com/ns-metadata/1.0) and elements from the gm namespace (http://base.google.com/ns/1.0). Elements in the g: namespace in an entry correspond to an instance of the class ItemAttribute. Elements in the gm: namespace in an entry correspond to instances of the classes Attribute and Value.

Setting up

For help setting up the client library, see the Client Library Getting Started Guide. You can find the Google Base specific extensions under src/gdata/base. The client library is an open source project found here.

You can import the classes you will need using the following import statement:

import gdata.base.service
import gdata.service
try:
    from xml.etree import ElementTree 
except ImportError:
    from elementtree import ElementTree 
import atom 
import gdata.base

gdata.base.service extends gdata.service to streamline Google Base operations. It provides methods for communicating with the server.

gdata.service provides CRUD operations and programmatic login for GData services.

gdata.base contains the data model classes which parse the XML and translate to and from Python objects.

Executing a query and interpreting the results

As described in the Snippets Feed reference you can search all items in Google Base by connecting to the snippets feed URL:

http://www.google.com/base/feeds/snippets?bq=digital+camera

and then interpreting the resulting atom feed.

To do this programatically, you need to create a GBaseService object. This is done as follows:

gb_client = gdata.base.service.GBaseService()  
q = gdata.base.service.BaseQuery()  

q.feed = '/base/feeds/snippets'  
q['start-index'] = '1'  
q['max-results'] = '10'  

q.bq = 'digital camera'  

feed = gb_client.QuerySnippetsFeed(q.ToUri())

gdata.base.service.BaseQuery() instantiates a query object. The feed parameter is set to the URL of the feed you want to access. q.bq sets the value of the bq query construction parameter. Refer to the Attributes and Queries document for information about how to write a query.

You may add additional parameters or categories as explained in the Google data documentation. Most parameters supported by the correspond to a property in the BaseQuery object.

When querying the snippets feed, gdata.base.service.QuerySnippetsFeed() is called to execute the query.

Next, the application connects to the URL generated by q.ToUri(), gets the result, parses it and returns a GBaseSnippetFeed. TheGBaseSnippetFeed contains a list of GBaseSnippetSnippets feed objects, one for each Google Base item returned by the server.

feed = gb_client.QuerySnippetsFeed(q.ToUri()) 
while(int(q['start-index']) < 989):   
	# Display the titles of the snippets.
		print 'Snippet query results items %s to %s' % (q['start-index'],
		int(q['start-index'])+10)
	for entry in feed.entry:
		print '  ', entry.title.text
		
	# Show the next 10 results from the snippets feed when the user presses   
	# enter.
    nothing = raw_input('Press enter to see the next 10 results')
	q['start-index'] = str(int(q['start-index']) + 10)
	feed = gb_client.QuerySnippetsFeed(q.ToUri()) 

The code snippet above displays the title of each entry (entry.title.text) and sends another request each time you press enter.

Attributes and types

In the client library, an attribute is identified by its name, as reflected by the class ItemAttributeContainer.  When getting and setting attribute values, only the attribute name is important.

When performing queries, an attribute is always identified by both its type and its name, as reflected by the class ItemAttribute. Make sure you always specify the type when setting an attribute, as it will have an impact on which queries can be run on your items. For more details on constructing queries, see Attributes and Queries and also the Query Language Specification.

The Python client library query methods do not take the attribute type into account. You can find all attributes from your snippets or items feed entry by using the same method: entry.FindItemAttribute(name).

If you set the number of bathrooms in your "house" item using AddItemAttribute('bathrooms') the attribute appear on the XML output, if users run this query: " [bathrooms > 2]" they will never get your item as an answer. Make sure you choose the correct type for your attributes to get the maximum benefit from the Google Base data API.

In some cases, when it is unclear whether an attribute should be an int or a float, you can avoid the dilemma by using the type number . The number type covers both int and float typed attributes.

Accessing the item types feed

The Item types feed contains a list of item types recommended by Google. For each item type, it lists the attributes that Google thinks might be useful.

You can access the itemtypes feed using the client library by setting q.feed to the URL of the itemtypes feed, along with the locale. This is accomplished with the following code.

client = gdata.base.service.GBaseService()

q = gdata.base.service.BaseQuery() 
q.feed = '/base/feeds/itemtypes/en_US' 
q.max_results = '25'

When querying the itemtypes feed, QueryItemTypesFeed() is called to execute the query.

The GBaseItemTypesFeed contains a list of GBaseItemTypeEntry objects, one for each item type returned by the server.

feed = client.QueryItemTypesFeed (q.ToUri())
# List the item types and their attributes 
for entry in feed.entry:
  print 'Item Type:', entry.title.text
  print 'Attributes:'
  for attribute in entry.attributes:
    print '   %s (%s)' % (attribute.name, attribute.type)

Remember that the data in this feed is just a suggestion. It is not the final list of all item types or of all attributes. The items already in Google Base might not even follow these suggestions, or you might need an item type that is not on this list.

Accessing the attributes feed

The Attributes feed might answer these kinds of questions. The code below uses the client library to find out the 10 most commonly-used attributes for a digital camera and for these, the 5 most common values (for text attributes).

You can access the attributes feed using the client library by setting q.feed to the URL of the attributes feed.

q = gdata.base.service.BaseQuery() 
q.feed = '/base/feeds/attributes' 
q.bq = 'digital camera'
q['max-results'] = '10'
q['max-values'] = '5'

feed = client.QueryAttributesFeed (q.ToUri())

When querying the attributes feed, QueryAttributesFeed() is called to execute the query.

As before, the code that connects to the URL generated by q.ToUri(), gets the result, but now the method parses it and returns a GBaseAttributeFeed is the same. The GBaseAttributesFeed contains a list of GBaseAttributeEntry objects, one for each Google Base attribute returned by the server.

feed = client.QueryAttributesFeed (q.ToUri())
for entry in feed.entry:
  print 'Attribute:', entry.attribute[0].name
  if len(entry.attribute[0].value) > 0:
    print 'Common values:'
    for value in entry.attribute[0].value:
      print ' ', value.text

Authenticating

To insert, update, or delete items, you need to be authenticated. The authentication methods are exposed in gdata.base.service. The example code also uses getpass is to prompt the user to enter a password over the command line.

The following code prompts the user for a Google Base account name and password. It sends this information to GBaseService.

gb_client = gdata.base.service.GBaseService() 
gb_client.email = raw_input('Please enter your username: ') 
gb_client.password = getpass.getpass() 

print 'Logging in' 
gb_client.ProgrammaticLogin()

Note that this example supposes you're writing a desktop application and that you have access to the user name and password. That might not be the case when writing a server, such as a web application. For more information about authentication, see the Google Account Authentication documentation.

Inserting items

To insert items into Google Base, you use the items feed.

The full source code of an example that does exactly what is described in this section is available in the distribution in the file samples/base/dryRunInsert.py. You can find documentation for this example in the Sample Applications section.

First,create the GBaseItem you would like to insert.

item = gdata.base.GBaseItem() 
item.author.append(atom.Author(name=atom.Name(text='Mr. Smith'))) 
item.title = atom.Title(text='He Jingxian\'s chicken') 
item.link.append(atom.Link(rel='alternate', link_type='text/html',     
	href='http://www.host.com/123456jsh9')) 
item.label.append(gdata.base.Label(text='kung pao chicken')) 
item.label.append(gdata.base.Label(text='chinese cuisine')) 
item.label.append(gdata.base.Label(text='recipes')) 
item.item_type = gdata.base.ItemType(text='recipes') 
item.AddItemAttribute(name='cooking_time', value='30 minutes') 
item.AddItemAttribute(name='main_ingredient', value='chicken') 
item.AddItemAttribute(name='main_ingredient', value='chili')

Note that the attribute name cannot have spaces.

Finally, insert this GBaseItem object into the Items feed.

result = gb_client.InsertItem(item, url_params={'dry-run': 'true'})

The dry=run: true flag specifies that the request is a test request and should not actually insert the items into the Google Base snippets feed. When you are ready to submit the item, remove this argument.

You can access the insertion time using result.published as follows:

insertion_time = result.published.text

The Google Base server assigns precomputed attributes for your entry, such as the creation date and time, the author and, probably most importantly, the identifier (or URL) of the new entry. Keep this ID (my_entry_id), as you will need it to update or delete your item.

my_entry_id = result.id.text

You can also get this information by running a query on the Items feed.

Choosing which attributes to use

When you are creating or modifying an item using the Google Base client library, keep in mind that an attribute is always identified by both its type and its name, as reflected by the class ItemAttribute. Make sure you always specify the type when setting an attribute, as it will have an impact on which Google Base queries may be run on your items.

For example, if you set the number of bathrooms in your "house" item using entry.AddItemAttribute('bathrooms', '2') the attribute will appear on the XML output. However, if users run the query: [bathrooms > 2] they will never get your item as an answer.

In the above example, you would need to specify a type of float as follows: entry.AddItemAttribute('bathrooms', '2', value_type='float').

Make sure you choose the correct type for your attributes to get the maximum benefit from Google Base.

For Google Base queries to be really useful, it's best if people agree on a common set of g: attributes. Google does not constrain the attributes you can use in an item, so you might need to be careful when choosing attribute name and types for your own items.

Updating items

To modify an item you have inserted, get it back from the server, change it, then call update on it:

entry = GBaseItemFromString(service.Get(my_entry_id).ToString())
entry.SetItemAttribute('rooms', '7')
service.UpdateItem(my_entry_id, entry)

You might avoid reading the entry from the server if you know exactly what your entry should look like. This is dangerous, as updating will replace everything with the entry you specify to UpdateItem. If you forget to set an attribute that is already in the entry, it will be removed when it is updated.

my_entry_id should be the ID that was assigned to your entry when you inserted it. You might have written it down when creating the entry or you might have found it by running a query on the Items feed.

Deleting items

To delete an item, all you need is its ID, expressed as a URL:

service.DeleteItem(my_entry_id)

Handling errors

The examples above do not contain any error-handling code to keep things simple.

The GBaseService methods throw Error exceptions, which can have different meaning depending on the concrete subclass that has been thrown, such as RequestError or BadAuthentication.

If you receive an Error, make sure you get the body of the error message.  If it is indeed an XML message, you can parse it to get the real error message.

The following shows an example of very basic error handling:

try:
service.DeleteItem("wrong_URI")
except gdata.service.Error, message:
print message[0]['reason']
print message[0]['body']

Reference

For referential information about the methods in the Python library, refer to the comments in the header files. You may also wish to consult: