Fix lack of top level methods from a service.
This commit is contained in:
@@ -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",
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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()
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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": {
|
||||
|
@@ -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):
|
||||
|
Reference in New Issue
Block a user