def build(serviceName, version, http=None, discoveryServiceUrl=DISCOVERY_URI, developerKey=None, model=None, requestBuilder=HttpRequest): """Construct a Resource for interacting with an API. Construct a Resource object for interacting with an API. The serviceName and version are the names from the Discovery service. Args: serviceName: string, name of the service. version: string, the version of the service. http: httplib2.Http, An instance of httplib2.Http or something that acts like it that HTTP requests will be made through. discoveryServiceUrl: string, a URI Template that points to the location of the discovery service. It should have two parameters {api} and {apiVersion} that when filled in produce an absolute URI to the discovery document for that service. developerKey: string, key obtained from https://code.google.com/apis/console. model: googleapiclient.Model, converts to and from the wire format. requestBuilder: googleapiclient.http.HttpRequest, encapsulator for an HTTP request. Returns: A Resource object with methods for interacting with the service. """ params = {'api': serviceName, 'apiVersion': version} if http is None: http = httplib2.Http() requested_url = uritemplate.expand(discoveryServiceUrl, params) # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment # variable that contains the network address of the client sending the # request. If it exists then add that to the request for the discovery # document to avoid exceeding the quota on discovery requests. if 'REMOTE_ADDR' in os.environ: requested_url = _add_query_parameter(requested_url, 'userIp', os.environ['REMOTE_ADDR']) logger.info('URL being requested: GET %s' % requested_url) resp, content = http.request(requested_url) if resp.status == 404: raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, version)) if resp.status >= 400: raise HttpError(resp, content, uri=requested_url) try: service = simplejson.loads(content) except ValueError, e: logger.error('Failed to parse as JSON: ' + content) raise InvalidJsonError()
def _retrieve_discovery_doc(url, http, cache_discovery, cache=None): """Retrieves the discovery_doc from cache or the internet. Args: url: string, the URL of the discovery document. http: httplib2.Http, An instance of httplib2.Http or something that acts like it through which HTTP requests will be made. cache_discovery: Boolean, whether or not to cache the discovery doc. cache: googleapiclient.discovery_cache.base.Cache, an optional cache object for the discovery documents. Returns: A unicode string representation of the discovery document. """ if cache_discovery: from . import discovery_cache from .discovery_cache import base if cache is None: cache = discovery_cache.autodetect() if cache: content = cache.get(url) if content: return content actual_url = url # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment # variable that contains the network address of the client sending the # request. If it exists then add that to the request for the discovery # document to avoid exceeding the quota on discovery requests. if 'REMOTE_ADDR' in os.environ: actual_url = _add_query_parameter(url, 'userIp', os.environ['REMOTE_ADDR']) logger.info('URL being requested: GET %s', actual_url) resp, content = http.request(actual_url) if resp.status == 404: raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, version)) if resp.status >= 400: raise HttpError(resp, content, uri=actual_url) try: content = content.decode('utf-8') except AttributeError: pass try: service = json.loads(content) except ValueError as e: logger.error('Failed to parse as JSON: ' + content) raise InvalidJsonError() if cache_discovery and cache: cache.set(url, content) return content
def test_get_pubsub_service_with_invalid_service_account(self): """Test getting the pubsub service""" self.mox.StubOutWithMock(os.path, 'isfile') self.mox.StubOutWithMock(GoogleCredentials, 'from_stream') os.path.isfile(pubsub_utils.CLOUD_SERVICE_ACCOUNT_FILE).AndReturn(True) credentials = self.mox.CreateMock(GoogleCredentials) GoogleCredentials.from_stream( pubsub_utils.CLOUD_SERVICE_ACCOUNT_FILE).AndReturn(credentials) credentials.create_scoped_required().AndReturn(True) credentials.create_scoped(pubsub_utils.PUBSUB_SCOPES).AndReturn( credentials) self.mox.StubOutWithMock(discovery, 'build') discovery.build(pubsub_utils.PUBSUB_SERVICE_NAME, pubsub_utils.PUBSUB_VERSION, credentials=credentials).AndRaise(UnknownApiNameOrVersion()) self.mox.ReplayAll() pubsub = pubsub_utils._get_pubsub_service() self.assertIsNone(pubsub) self.mox.VerifyAll()
def test_pubsub_with_invalid_service_account(self): """Test pubsubwith invalid service account.""" self.mox.StubOutWithMock(os.path, 'isfile') self.mox.StubOutWithMock(GoogleCredentials, 'from_stream') os.path.isfile(_TEST_CLOUD_SERVICE_ACCOUNT_FILE).AndReturn(True) credentials = self.mox.CreateMock(GoogleCredentials) GoogleCredentials.from_stream( _TEST_CLOUD_SERVICE_ACCOUNT_FILE).AndReturn(credentials) credentials.create_scoped_required().AndReturn(True) credentials.create_scoped( pubsub_utils.PUBSUB_SCOPES).AndReturn(credentials) self.mox.StubOutWithMock(discovery, 'build') discovery.build(pubsub_utils.PUBSUB_SERVICE_NAME, pubsub_utils.PUBSUB_VERSION, credentials=credentials).AndRaise( UnknownApiNameOrVersion()) self.mox.ReplayAll() with self.assertRaises(pubsub_utils.PubSubException): msg = _create_sample_message() pubsub_client = pubsub_utils.PubSubClient( _TEST_CLOUD_SERVICE_ACCOUNT_FILE) pubsub_client.publish_notifications('test_topic', [msg]) self.mox.VerifyAll()
def build(serviceName, version, http=None, discoveryServiceUrl=DISCOVERY_URI, developerKey=None, model=None, requestBuilder=HttpRequest, credentials=None, cache_discovery=True, cache=None): """Construct a Resource for interacting with an API. Construct a Resource object for interacting with an API. The serviceName and version are the names from the Discovery service. Args: serviceName: string, name of the service. version: string, the version of the service. http: httplib2.Http, An instance of httplib2.Http or something that acts like it that HTTP requests will be made through. discoveryServiceUrl: string, a URI Template that points to the location of the discovery service. It should have two parameters {api} and {apiVersion} that when filled in produce an absolute URI to the discovery document for that service. developerKey: string, key obtained from https://code.google.com/apis/console. model: googleapiclient.Model, converts to and from the wire format. requestBuilder: googleapiclient.http.HttpRequest, encapsulator for an HTTP request. credentials: oauth2client.Credentials or google.auth.credentials.Credentials, credentials to be used for authentication. cache_discovery: Boolean, whether or not to cache the discovery doc. cache: googleapiclient.discovery_cache.base.CacheBase, an optional cache object for the discovery documents. Returns: A Resource object with methods for interacting with the service. """ params = {'api': serviceName, 'apiVersion': version} if http is None: discovery_http = build_http() else: discovery_http = http for discovery_url in ( discoveryServiceUrl, V2_DISCOVERY_URI, ): requested_url = uritemplate.expand(discovery_url, params) try: content = _retrieve_discovery_doc(requested_url, discovery_http, cache_discovery, cache) return build_from_document(content, base=discovery_url, http=http, developerKey=developerKey, model=model, requestBuilder=requestBuilder, credentials=credentials) except HttpError as e: if e.resp.status == http_client.NOT_FOUND: continue else: raise e raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, version))