def build_from_document(service, base=None, future=None, http=None, developerKey=None, model=None, requestBuilder=HttpRequest): """Create a Resource for interacting with an API. Same as `build()`, but constructs the Resource object from a discovery document that is it given, as opposed to retrieving one over HTTP. Args: service: string or object, the JSON discovery document describing the API. The value passed in may either be the JSON string or the deserialized JSON. base: string, base URI for all HTTP requests, usually the discovery URI. This parameter is no longer used as rootUrl and servicePath are included within the discovery document. (deprecated) future: string, discovery document with future capabilities (deprecated). 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 de-serializes requests and responses. requestBuilder: Takes an http request and packages it up to be executed. Returns: A Resource object with methods for interacting with the service. """ # future is no longer used. future = {} if isinstance(service, basestring): service = simplejson.loads(service) base = urlparse.urljoin(service['rootUrl'], service['servicePath']) schema = Schemas(service) if model is None: features = service.get('features', []) model = JsonModel('dataWrapper' in features) return Resource(http=http, baseUrl=base, model=model, developerKey=developerKey, requestBuilder=requestBuilder, resourceDesc=service, rootDesc=service, schema=schema)
def _build(self, key): """ Get all arguments needed to construct a Resource object. _build shortcuts the googleapiclient.discovery functions build() and build_from_document(), which construct the Resource class. See googleapiclient.discovery.Resource for more information. """ # auth baseUrl = 'https://sheets.googleapis.com/' discUrl = (baseUrl + '$discovery/rest?version=v4') scope = ['https://spreadsheets.google.com/feeds'] creds = ServiceAccountCredentials.from_json_keyfile_name(key, scope) http = creds.authorize(Http()) # service JSON response, body = http.request(discUrl) if response.status >= 400: raise HttpError(response, body, uri=discUrl) service = json.loads(body) # model from service features = service.get('features', []) model = JsonModel('dataWrapper' in features) # schema from service schema = Schemas(service) return dict(http=http, baseUrl=baseUrl, model=model, developerKey=None, requestBuilder=HttpRequest, resourceDesc=service, rootDesc=service, schema=schema)
def build_from_document(service, base=None, future=None, http=None, developerKey=None, model=None, requestBuilder=HttpRequest, credentials=None): """Create a Resource for interacting with an API. Same as `build()`, but constructs the Resource object from a discovery document that is it given, as opposed to retrieving one over HTTP. Args: service: string or object, the JSON discovery document describing the API. The value passed in may either be the JSON string or the deserialized JSON. base: string, base URI for all HTTP requests, usually the discovery URI. This parameter is no longer used as rootUrl and servicePath are included within the discovery document. (deprecated) future: string, discovery document with future capabilities (deprecated). 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 de-serializes requests and responses. requestBuilder: Takes an http request and packages it up to be executed. credentials: oauth2client.Credentials or google.auth.credentials.Credentials, credentials to be used for authentication. Returns: A Resource object with methods for interacting with the service. """ if http is not None and credentials is not None: raise ValueError( 'Arguments http and credentials are mutually exclusive.') if isinstance(service, six.string_types): service = json.loads(service) if 'rootUrl' not in service and (isinstance(http, (HttpMock, HttpMockSequence))): logger.error( "You are using HttpMock or HttpMockSequence without" + "having the service discovery doc in cache. Try calling " + "build() without mocking once first to populate the " + "cache.") raise InvalidJsonError() base = urljoin(service['rootUrl'], service['servicePath']) schema = Schemas(service) # If the http client is not specified, then we must construct an http client # to make requests. If the service has scopes, then we also need to setup # authentication. if http is None: # Does the service require scopes? scopes = list( service.get('auth', {}).get('oauth2', {}).get('scopes', {}).keys()) # If so, then the we need to setup authentication if no developerKey is # specified. if scopes and not developerKey: # If the user didn't pass in credentials, attempt to acquire application # default credentials. if credentials is None: credentials = _auth.default_credentials() # The credentials need to be scoped. credentials = _auth.with_scopes(credentials, scopes) # Create an authorized http instance http = _auth.authorized_http(credentials) # If the service doesn't require scopes then there is no need for # authentication. else: http = build_http() if model is None: features = service.get('features', []) model = JsonModel('dataWrapper' in features) return Resource(http=http, baseUrl=base, model=model, developerKey=developerKey, requestBuilder=requestBuilder, resourceDesc=service, rootDesc=service, schema=schema)
def build_from_document(service, base=None, future=None, http=None, developerKey=None, model=None, requestBuilder=HttpRequest, credentials=None): """Create a Resource for interacting with an API. Same as `build()`, but constructs the Resource object from a discovery document that is it given, as opposed to retrieving one over HTTP. Args: service: string or object, the JSON discovery document describing the API. The value passed in may either be the JSON string or the deserialized JSON. base: string, base URI for all HTTP requests, usually the discovery URI. This parameter is no longer used as rootUrl and servicePath are included within the discovery document. (deprecated) future: string, discovery document with future capabilities (deprecated). 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 de-serializes requests and responses. requestBuilder: Takes an http request and packages it up to be executed. credentials: object, credentials to be used for authentication. Returns: A Resource object with methods for interacting with the service. """ if http is None: http = httplib2.Http() # future is no longer used. future = {} if isinstance(service, six.string_types): service = json.loads(service) if 'rootUrl' not in service and (isinstance(http, (HttpMock, HttpMockSequence))): logger.error( "You are using HttpMock or HttpMockSequence without" + "having the service discovery doc in cache. Try calling " + "build() without mocking once first to populate the " + "cache.") raise InvalidJsonError() base = urljoin(service['rootUrl'], service['servicePath']) schema = Schemas(service) if credentials: # If credentials were passed in, we could have two cases: # 1. the scopes were specified, in which case the given credentials # are used for authorizing the http; # 2. the scopes were not provided (meaning the Application Default # Credentials are to be used). In this case, the Application Default # Credentials are built and used instead of the original credentials. # If there are no scopes found (meaning the given service requires no # authentication), there is no authorization of the http. if (isinstance(credentials, GoogleCredentials) and credentials.create_scoped_required()): scopes = service.get('auth', {}).get('oauth2', {}).get('scopes', {}) if scopes: credentials = credentials.create_scoped(list(scopes.keys())) else: # No need to authorize the http object # if the service does not require authentication. credentials = None if credentials: http = credentials.authorize(http) if model is None: features = service.get('features', []) model = JsonModel('dataWrapper' in features) return Resource(http=http, baseUrl=base, model=model, developerKey=developerKey, requestBuilder=requestBuilder, resourceDesc=service, rootDesc=service, schema=schema)
def setUp(self): f = file(datafile('zoo.json')) discovery = f.read() f.close() discovery = simplejson.loads(discovery) self.sc = Schemas(discovery)
class SchemasTest(unittest.TestCase): def setUp(self): f = file(datafile('zoo.json')) discovery = f.read() f.close() discovery = simplejson.loads(discovery) self.sc = Schemas(discovery) def test_basic_formatting(self): self.assertEqual(sorted(LOAD_FEED.splitlines()), sorted(self.sc.prettyPrintByName('LoadFeed').splitlines())) def test_empty_edge_case(self): self.assertTrue('Unknown type' in self.sc.prettyPrintSchema({})) def test_simple_object(self): self.assertEqual({}, eval(self.sc.prettyPrintSchema({'type': 'object'}))) def test_string(self): self.assertEqual(type(""), type(eval(self.sc.prettyPrintSchema({'type': 'string'})))) def test_integer(self): self.assertEqual(type(20), type(eval(self.sc.prettyPrintSchema({'type': 'integer'})))) def test_number(self): self.assertEqual(type(1.2), type(eval(self.sc.prettyPrintSchema({'type': 'number'})))) def test_boolean(self): self.assertEqual(type(True), type(eval(self.sc.prettyPrintSchema({'type': 'boolean'})))) def test_string_default(self): self.assertEqual('foo', eval(self.sc.prettyPrintSchema({'type': 'string', 'default': 'foo'}))) def test_integer_default(self): self.assertEqual(20, eval(self.sc.prettyPrintSchema({'type': 'integer', 'default': 20}))) def test_number_default(self): self.assertEqual(1.2, eval(self.sc.prettyPrintSchema({'type': 'number', 'default': 1.2}))) def test_boolean_default(self): self.assertEqual(False, eval(self.sc.prettyPrintSchema({'type': 'boolean', 'default': False}))) def test_null(self): self.assertEqual(None, eval(self.sc.prettyPrintSchema({'type': 'null'}))) def test_any(self): self.assertEqual('', eval(self.sc.prettyPrintSchema({'type': 'any'}))) def test_array(self): self.assertEqual([{}], eval(self.sc.prettyPrintSchema({'type': 'array', 'items': {'type': 'object'}}))) def test_nested_references(self): feed = { 'items': [ { 'photo': { 'hash': 'A String', 'hashAlgorithm': 'A String', 'filename': 'A String', 'type': 'A String', 'size': 42 }, 'kind': 'zoo#animal', 'etag': 'A String', 'name': 'A String' } ], 'kind': 'zoo#animalFeed', 'etag': 'A String' } self.assertEqual(feed, eval(self.sc.prettyPrintByName('AnimalFeed'))) def test_additional_properties(self): items = { 'animals': { 'a_key': { 'photo': { 'hash': 'A String', 'hashAlgorithm': 'A String', 'filename': 'A String', 'type': 'A String', 'size': 42 }, 'kind': 'zoo#animal', 'etag': 'A String', 'name': 'A String' } }, 'kind': 'zoo#animalMap', 'etag': 'A String' } self.assertEqual(items, eval(self.sc.prettyPrintByName('AnimalMap'))) def test_unknown_name(self): self.assertRaises(KeyError, self.sc.prettyPrintByName, 'UknownSchemaThing')
def discovery_schema(api, version, resource, api_schema=None, object_schema=None): if not resource: return None if not api_schema: api_document = discovery_download(api, version) api_schema = Schemas(api_document) if not object_schema: object_schema = api_schema.get(resource)['properties'] bigquery_schema = [] for key, value in object_schema.items(): if '$ref' in value: bigquery_schema.append({ 'name': key, 'type': 'RECORD', 'mode': 'NULLABLE', 'fields': discovery_schema(api, version, value['$ref'], api_schema) }) else: if value['type'] == 'array': if '$ref' in value['items']: bigquery_schema.append({ 'name': key, 'type': 'RECORD', 'mode': 'REPEATED', 'fields': discovery_schema(api, version, value['items']['$ref'], api_schema) }) else: bigquery_schema.append({ 'description': ', '.join(value['items'].get('enum', [])), 'name': key, 'type': discovery_type(value['items']), 'mode': 'REPEATED', }) else: bigquery_schema.append({ 'description': ', '.join(value.get('enum', [])), 'name': key, 'type': discovery_type(value), 'mode': 'NULLABLE' }) return bigquery_schema
def setUp(self): f = open(datafile("zoo.json")) discovery = f.read() f.close() discovery = json.loads(discovery) self.sc = Schemas(discovery)
class SchemasTest(unittest.TestCase): def setUp(self): f = open(datafile("zoo.json")) discovery = f.read() f.close() discovery = json.loads(discovery) self.sc = Schemas(discovery) def test_basic_formatting(self): self.assertEqual( sorted(LOAD_FEED.splitlines()), sorted(self.sc.prettyPrintByName("LoadFeed").splitlines()), ) def test_empty_edge_case(self): self.assertTrue("Unknown type" in self.sc.prettyPrintSchema({})) def test_simple_object(self): self.assertEqual({}, eval(self.sc.prettyPrintSchema({"type": "object"}))) def test_string(self): self.assertEqual( type(""), type(eval(self.sc.prettyPrintSchema({"type": "string"}))) ) def test_integer(self): self.assertEqual( type(20), type(eval(self.sc.prettyPrintSchema({"type": "integer"}))) ) def test_number(self): self.assertEqual( type(1.2), type(eval(self.sc.prettyPrintSchema({"type": "number"}))) ) def test_boolean(self): self.assertEqual( type(True), type(eval(self.sc.prettyPrintSchema({"type": "boolean"}))) ) def test_string_default(self): self.assertEqual( "foo", eval(self.sc.prettyPrintSchema({"type": "string", "default": "foo"})) ) def test_integer_default(self): self.assertEqual( 20, eval(self.sc.prettyPrintSchema({"type": "integer", "default": 20})) ) def test_number_default(self): self.assertEqual( 1.2, eval(self.sc.prettyPrintSchema({"type": "number", "default": 1.2})) ) def test_boolean_default(self): self.assertEqual( False, eval(self.sc.prettyPrintSchema({"type": "boolean", "default": False})), ) def test_null(self): self.assertEqual(None, eval(self.sc.prettyPrintSchema({"type": "null"}))) def test_any(self): self.assertEqual("", eval(self.sc.prettyPrintSchema({"type": "any"}))) def test_array(self): self.assertEqual( [{}], eval( self.sc.prettyPrintSchema( {"type": "array", "items": {"type": "object"}} ) ), ) def test_nested_references(self): feed = { "items": [ { "photo": { "hash": "A String", "hashAlgorithm": "A String", "filename": "A String", "type": "A String", "size": 42, }, "kind": "zoo#animal", "etag": "A String", "name": "A String", } ], "kind": "zoo#animalFeed", "etag": "A String", } self.assertEqual(feed, eval(self.sc.prettyPrintByName("AnimalFeed"))) def test_additional_properties(self): items = { "animals": { "a_key": { "photo": { "hash": "A String", "hashAlgorithm": "A String", "filename": "A String", "type": "A String", "size": 42, }, "kind": "zoo#animal", "etag": "A String", "name": "A String", } }, "kind": "zoo#animalMap", "etag": "A String", } self.assertEqual(items, eval(self.sc.prettyPrintByName("AnimalMap"))) def test_unknown_name(self): self.assertRaises(KeyError, self.sc.prettyPrintByName, "UknownSchemaThing")
def build_from_document( service, base=None, future=None, http=None, developerKey=None, model=None, requestBuilder=HttpRequest, credentials=None, client_options=None, adc_cert_path=None, adc_key_path=None, ): if http is not None and credentials is not None: raise ValueError( "Arguments http and credentials are mutually exclusive.") if isinstance(service, six.string_types): service = json.loads(service) elif isinstance(service, six.binary_type): service = json.loads(service.decode("utf-8")) if "rootUrl" not in service and isinstance(http, (HttpMock, HttpMockSequence)): logger.error( "You are using HttpMock or HttpMockSequence without" + "having the service discovery doc in cache. Try calling " + "build() without mocking once first to populate the " + "cache.") raise InvalidJsonError() base = urljoin(service["rootUrl"], service["servicePath"]) if client_options: if isinstance(client_options, six.moves.collections_abc.Mapping): client_options = google.api_core.client_options.from_dict( client_options) if client_options.api_endpoint: base = client_options.api_endpoint schema = Schemas(service) if http is None: scopes = list( service.get("auth", {}).get("oauth2", {}).get("scopes", {}).keys()) if scopes and not developerKey: if credentials is None: credentials = _auth.default_credentials() credentials = _auth.with_scopes(credentials, scopes) if credentials: http = _auth.authorized_http(credentials) else: http = build_http() client_cert_to_use = None if client_options and client_options.client_cert_source: raise MutualTLSChannelError( "ClientOptions.client_cert_source is not supported, please use ClientOptions.client_encrypted_cert_source." ) if (client_options and hasattr(client_options, "client_encrypted_cert_source") and client_options.client_encrypted_cert_source): client_cert_to_use = client_options.client_encrypted_cert_source elif adc_cert_path and adc_key_path and mtls.has_default_client_cert_source( ): client_cert_to_use = mtls.default_client_encrypted_cert_source( adc_cert_path, adc_key_path) if client_cert_to_use: cert_path, key_path, passphrase = client_cert_to_use() http_channel = (http.http if google_auth_httplib2 and isinstance( http, google_auth_httplib2.AuthorizedHttp) else http) http_channel.add_certificate(key_path, cert_path, "", passphrase) if "mtlsRootUrl" in service and (not client_options or not client_options.api_endpoint): mtls_endpoint = urljoin(service["mtlsRootUrl"], service["servicePath"]) use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if not use_mtls_env in ("never", "auto", "always"): raise MutualTLSChannelError( "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) if use_mtls_env == "always" or (use_mtls_env == "auto" and client_cert_to_use): base = mtls_endpoint if model is None: features = service.get("features", []) model = JsonModel("dataWrapper" in features) return { 'http': http, 'baseUrl': base, 'model': model, 'developerKey': developerKey, 'requestBuilder': requestBuilder, 'resourceDesc': service, 'rootDesc': service, 'schema': schema, }