Here’s an example of implementing an API with many different endpoints. It’s the Google AJAX Search API which lets you access all of Google’s search engines programmatically! A few notes:
- In the Javascript API Google provides “branding” functions to make sure search results are properly attributed. There doesn’t seem to be a corresponding AJAX call — that is, it’s probably implemented directly in the Javascript — but I’d still like to provide a corresponding function. It would be nice if API providers actually gave a branding end-point
- The code doesn’t support (yet) multi-page results: coming soon
- The clever bit is in
_item_path
, which describes how to pull WORK result objects out of the AJAX result - all this code is actually available right now, via SVN: the instructions are here. This library is standalone (and is in fact the basis for many of the other projects I have on Google code)
- The Google API requires a
_http_referer
: the URL of the site that’s using the results - The Google API does not require an API key, but you can pass one (in the constructor or in individual search calls) under the key
api_key
. You can use the same API key that you’ve created for Google Maps.
Here’s the Google API class: quite simple. I’ll probably extend each individual search function to provide all the known parameters by name, rather than passing in a **ad
catch-all.
class Google(bm_api.API): _base_query = { "v" : "1.0", } _item_path = "responseData.results" _meta_path = "responseData.cursor" _convert2work = bm_work.JSON2WORK() def __init__(self, _http_referer, **ad): bm_api.API.__init__(self, _http_referer = _http_referer, **ad) def WebSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/web" self.SearchOn(q = q, **ad) def LocalSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/local" self.SearchOn(q = q, **ad) def VideoSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/video" self.SearchOn(q = q, **ad) def BlogSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/blogs" self.SearchOn(q = q, **ad) def NewsSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/news" self.SearchOn(q = q, **ad) def BookSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/books" self.SearchOn(q = q, **ad) def ImageSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/images" self.SearchOn(q = q, **ad) def PatentSearch(self, q, **ad): self._uri_base = "http://ajax.googleapis.com/ajax/services/search/patentNew" self.SearchOn(q = q, **ad)
Here’s how you use it:
api_key = os.environ["GMAPS_APIKEY"] referer = "http://code.davidjanes.com" query = "Paris Hilton" api = Google(key = api_key, _http_referer = referer) api.VideoSearch(query) for item in api.IterItems(): pprint.pprint(item)
Here’s an example of a results, searching for “Paris Hilton” in Videos. I tried searching in Patents without luck.
{'@Index': 0, '@Page': 1, u'GsearchResultClass': u'GvideoSearch', u'content': u"Paris Hilton's new video clip for 'Nothing In This World'", u'duration': u'204', u'playUrl': u'http://www.youtube.com/v/...', u'published': u'Thu, 12 Oct 2006 09:33:23 PDT', u'publisher': u'www.youtube.com', u'rating': u'4.52872', u'tbHeight': u'240', u'tbUrl': u'http://0.gvt0.com/vi/Ki2M3-2W-cQ/0.jpg', u'tbWidth': u'320', u'title': u'Paris Hilton - Nothing In This World', u'titleNoFormatting': u'Paris Hilton - Nothing In This World', u'url': u'http://www.google.com/url?q=...', u'videoType': u'YouTube'}