Fix lack of top level methods from a service.

This commit is contained in:
Joe Gregorio
2011-01-31 21:55:21 -05:00
parent 28ee089ca3
commit 7a6df3a31a
9 changed files with 67 additions and 58 deletions

View File

@@ -91,6 +91,7 @@ def build(serviceName, version,
return build_from_document(content, discoveryServiceUrl, future,
http, developerKey, model, requestBuilder)
def build_from_document(
service,
base,
@@ -105,8 +106,8 @@ def build_from_document(
base: string, base URI for all HTTP requests, usually the discovery URI
future: string, discovery document with future capabilities
auth_discovery: dict, information about the authentication the API supports
http: httplib2.Http, An instance of httplib2.Http or something that acts like
it that HTTP requests will be made through.
http: httplib2.Http, An instance of httplib2.Http or something that acts
like it that HTTP requests will be made through.
developerKey: string, Key for controlling API usage, generated
from the API Console.
model: Model class instance that serializes and
@@ -116,45 +117,26 @@ def build_from_document(
service = simplejson.loads(service)
base = urlparse.urljoin(base, service['restBasePath'])
resources = service['resources']
if future:
doc = simplejson.loads(future)
future = doc['resources']
auth_discovery = doc.get('auth', {})
future = simplejson.loads(future)
auth_discovery = future.get('auth', {})
else:
future = {}
auth_discovery = {}
class Service(object):
"""Top level interface for a service"""
resource = createResource(http, base, model, requestBuilder, developerKey,
service, future)
def __init__(self, http=http):
self._http = http
self._baseUrl = base
self._model = model
self._developerKey = developerKey
self._requestBuilder = requestBuilder
def auth_method():
"""Discovery information about the authentication the API uses."""
return auth_discovery
def auth_discovery(self):
return auth_discovery
setattr(resource, 'auth_discovery', auth_method)
def createMethod(theclass, methodName, methodDesc, futureDesc):
def method(self):
return createResource(self._http, self._baseUrl, self._model,
self._requestBuilder, methodName,
self._developerKey, methodDesc, futureDesc)
setattr(method, '__doc__', 'A description of how to use this function')
setattr(method, '__is_resource__', True)
setattr(theclass, methodName, method)
for methodName, methodDesc in resources.iteritems():
createMethod(Service, methodName, methodDesc, future.get(methodName, {}))
return Service()
return resource
def createResource(http, baseUrl, model, requestBuilder, resourceName,
def createResource(http, baseUrl, model, requestBuilder,
developerKey, resourceDesc, futureDesc):
class Resource(object):
@@ -322,8 +304,8 @@ def createResource(http, baseUrl, model, requestBuilder, resourceName,
def method(self):
return createResource(self._http, self._baseUrl, self._model,
self._requestBuilder, methodName,
self._developerKey, methodDesc, futureDesc)
self._requestBuilder, self._developerKey,
methodDesc, futureDesc)
setattr(method, '__doc__', 'A description of how to use this function')
setattr(method, '__is_resource__', True)
@@ -335,10 +317,10 @@ def createResource(http, baseUrl, model, requestBuilder, resourceName,
else:
future = {}
createMethod(Resource, methodName, methodDesc,
future.get(methodName, {}))
future)
# Add <m>_next() methods to Resource
if futureDesc:
if futureDesc and 'methods' in futureDesc:
for methodName, methodDesc in futureDesc['methods'].iteritems():
if 'next' in methodDesc and methodName in resourceDesc['methods']:
createNextMethod(Resource, methodName + "_next",

View File

@@ -79,10 +79,12 @@ class Credentials(object):
"""
_abstract()
class Flow(object):
"""Base class for all Flow objects."""
pass
class OAuthCredentials(Credentials):
"""Credentials object for OAuth 1.0a
"""
@@ -254,4 +256,3 @@ class FlowThreeLegged(Flow):
oauth_params['oauth_token_secret'])
return OAuthCredentials(consumer, token, self.user_agent)

View File

@@ -15,12 +15,12 @@ DEVELOPER_KEY = 'AIzaSyACZJW4JwcWwz5taR2gjIMNQrtgDLfILPc'
def main():
"""Get and print a feed of public products in the United States mathing a text
search query for 'digital camera' and grouped by the 8 top brands.
"""Get and print a feed of public products in the United States mathing a
text search query for 'digital camera' and grouped by the 8 top brands.
The list method of the resource should be called with the "crowdBy" parameter.
Each parameter should be designed as <attribute>:<occurence>, where
<occurrence> is the number of that <attribute> that will be used. For
The list method of the resource should be called with the "crowdBy"
parameter. Each parameter should be designed as <attribute>:<occurence>,
where <occurrence> is the number of that <attribute> that will be used. For
example, to crowd by the 5 top brands, the parameter would be "brand:5". The
possible rules for crowding are currently:

View File

@@ -23,9 +23,10 @@ def main():
The "|" operator can be used to search for alternative search terms, for
example: q = 'banana|apple' will search for bananas or apples.
Search phrases such as those containing spaces can be specified by surrounding
them with double quotes, for example q='"mp3 player"'. This can be useful when
combining with the "|" operator such as q = '"mp3 player"|ipod'.
Search phrases such as those containing spaces can be specified by
surrounding them with double quotes, for example q='"mp3 player"'. This can
be useful when combining with the "|" operator such as q = '"mp3
player"|ipod'.
"""
client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
resource = client.products()

View File

@@ -16,16 +16,17 @@ def main():
"""Get and print a histogram of the top 15 brand distribution for a search
query.
Histograms are created by using the "Facets" functionality of the API. A Facet
is a view of a certain property of products, containing a number of buckets,
one for each value of that property. Or concretely, for a parameter such as
"brand" of a product, the facets would include a facet for brand, which would
contain a number of buckets, one for each brand returned in the result.
Histograms are created by using the "Facets" functionality of the API. A
Facet is a view of a certain property of products, containing a number of
buckets, one for each value of that property. Or concretely, for a parameter
such as "brand" of a product, the facets would include a facet for brand,
which would contain a number of buckets, one for each brand returned in the
result.
A bucket contains either a value and a count, or a value and a range. In the
simple case of a value and a count for our example of the "brand" property,
the value would be the brand name, eg "sony" and the count would be the number
of results in the search.
the value would be the brand name, eg "sony" and the count would be the
number of results in the search.
"""
client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
resource = client.products()

View File

@@ -15,11 +15,12 @@ DEVELOPER_KEY = 'AIzaSyACZJW4JwcWwz5taR2gjIMNQrtgDLfILPc'
def main():
"""Get and print a feed of public products in the United States mathing a text
search query for 'digital camera' ranked by ascending price.
"""Get and print a feed of public products in the United States mathing a
text search query for 'digital camera' ranked by ascending price.
The list method for the resource should be called with the "rankBy" parameter.
5 parameters to rankBy are currently supported by the API. They are:
The list method for the resource should be called with the "rankBy"
parameter. 5 parameters to rankBy are currently supported by the API. They
are:
"relevancy"
"modificationTime:ascending"
@@ -33,8 +34,8 @@ def main():
"""
client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
resource = client.products()
# The rankBy parameter to the list method causes results to be ranked, in this
# case by ascending price.
# The rankBy parameter to the list method causes results to be ranked, in
# this case by ascending price.
request = resource.list(source='public', country='US', q=u'digital camera',
rankBy='price:ascending')
response = request.execute()

View File

@@ -3,7 +3,8 @@
#
# Copyright 2010 Google Inc. All Rights Reserved.
"""Query that is restricted by a parameter against the public shopping search API"""
"""Query that is restricted by a parameter against the public shopping search
API"""
import pprint

View File

@@ -4,6 +4,20 @@
"description": "Zoo API used for testing",
"restBasePath": "/zoo",
"rpcPath": "/rpc",
"methods": {
"query": {
"restPath": "query",
"rpcMethod": "bigquery.query",
"httpMethod": "GET",
"parameters": {
"q": {
"restParameterType": "query",
"required": false,
"repeated": false
}
}
}
},
"resources": {
"my": {
"resources": {

View File

@@ -113,6 +113,14 @@ class Discovery(unittest.TestCase):
q = parse_qs(parsed[4])
self.assertEqual(q['max-results'], ['5'])
def test_top_level_functions(self):
self.http = HttpMock('zoo.json', {'status': '200'})
zoo = build('zoo', 'v1', self.http)
self.assertTrue(getattr(zoo, 'query'))
request = zoo.query(q="foo")
parsed = urlparse.urlparse(request.uri)
q = parse_qs(parsed[4])
self.assertEqual(q['q'], ['foo'])
class Next(unittest.TestCase):