Fix lack of top level methods from a service.
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index b39e1b2..b557b8b 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -91,6 +91,7 @@
return build_from_document(content, discoveryServiceUrl, future,
http, developerKey, model, requestBuilder)
+
def build_from_document(
service,
base,
@@ -105,8 +106,8 @@
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 @@
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 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 @@
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",
diff --git a/apiclient/oauth.py b/apiclient/oauth.py
index 469b6e0..68e4300 100644
--- a/apiclient/oauth.py
+++ b/apiclient/oauth.py
@@ -79,10 +79,12 @@
"""
_abstract()
+
class Flow(object):
"""Base class for all Flow objects."""
pass
+
class OAuthCredentials(Credentials):
"""Credentials object for OAuth 1.0a
"""
@@ -254,4 +256,3 @@
oauth_params['oauth_token_secret'])
return OAuthCredentials(consumer, token, self.user_agent)
-
diff --git a/samples/searchforshopping/crowding.py b/samples/searchforshopping/crowding.py
index bf1114e..2eea38f 100644
--- a/samples/searchforshopping/crowding.py
+++ b/samples/searchforshopping/crowding.py
@@ -15,12 +15,12 @@
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:
diff --git a/samples/searchforshopping/fulltextsearch.py b/samples/searchforshopping/fulltextsearch.py
index 9a5fa5e..f838223 100644
--- a/samples/searchforshopping/fulltextsearch.py
+++ b/samples/searchforshopping/fulltextsearch.py
@@ -23,9 +23,10 @@
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()
diff --git a/samples/searchforshopping/histograms.py b/samples/searchforshopping/histograms.py
index 6d198ff..6bd3a2f 100644
--- a/samples/searchforshopping/histograms.py
+++ b/samples/searchforshopping/histograms.py
@@ -16,16 +16,17 @@
"""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()
diff --git a/samples/searchforshopping/ranking.py b/samples/searchforshopping/ranking.py
index bf6dc0f..86ad2ee 100644
--- a/samples/searchforshopping/ranking.py
+++ b/samples/searchforshopping/ranking.py
@@ -15,11 +15,12 @@
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 @@
"""
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()
diff --git a/samples/searchforshopping/restricting.py b/samples/searchforshopping/restricting.py
index 07a4474..1d21c69 100644
--- a/samples/searchforshopping/restricting.py
+++ b/samples/searchforshopping/restricting.py
@@ -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
diff --git a/tests/data/zoo.json b/tests/data/zoo.json
index f83e9dd..4f90c3d 100644
--- a/tests/data/zoo.json
+++ b/tests/data/zoo.json
@@ -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": {
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 0c64a09..541210c 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -113,6 +113,14 @@
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):