def test_no_data_wrapper_deserialize(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({'status': '200'}) resp.reason = 'OK' content = '{"data": "is good"}' content = model.response(resp, content) self.assertEqual(content, {'data': 'is good'})
def test_data_wrapper_deserialize_nodata(self): model = JsonModel(data_wrapper=True) resp = httplib2.Response({'status': '200'}) resp.reason = 'OK' content = '{"atad": "is good"}' content = model.response(resp, content) self.assertEqual(content, {'atad': 'is good'})
def test_retry(self): num_retries = 5 resp_seq = [({'status': '500'}, '')] * num_retries resp_seq.append(({'status': '200'}, '{}')) http = HttpMockSequence(resp_seq) model = JsonModel() uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar' method = u'POST' request = HttpRequest(http, model.response, uri, method=method, body=u'{}', headers={'content-type': 'application/json'}) sleeptimes = [] request._sleep = lambda x: sleeptimes.append(x) request._rand = lambda: 10 request.execute(num_retries=num_retries) self.assertEqual(num_retries, len(sleeptimes)) for retry_num in xrange(num_retries): self.assertEqual(10 * 2**(retry_num + 1), sleeptimes[retry_num])
def test_json_build_query(self): model = JsonModel(data_wrapper=False) headers = {} path_params = {} query_params = { 'foo': 1, 'bar': u'\N{COMET}', 'baz': ['fe', 'fi', 'fo', 'fum'], # Repeated parameters 'qux': [] } body = {} headers, params, query, body = model.request(headers, path_params, query_params, body) self.assertEqual(headers['accept'], 'application/json') self.assertEqual(headers['content-type'], 'application/json') query_dict = parse_qs(query[1:]) self.assertEqual(query_dict['foo'], ['1']) self.assertEqual(query_dict['bar'], [u'\N{COMET}'.encode('utf-8')]) self.assertEqual(query_dict['baz'], ['fe', 'fi', 'fo', 'fum']) self.assertTrue('qux' not in query_dict) self.assertEqual(body, '{}')
def test_no_retry_fails_fast(self): http = HttpMockSequence([({ 'status': '500' }, ''), ({ 'status': '200' }, '{}')]) model = JsonModel() uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar' method = u'POST' request = HttpRequest(http, model.response, uri, method=method, body=u'{}', headers={'content-type': 'application/json'}) request._rand = lambda: 1.0 request._sleep = lambda _: self.fail( 'sleep should not have been called.') try: request.execute() self.fail('Should have raised an exception.') except HttpError: pass
def test_media_io_base_next_chunk_retries(self): try: import io except ImportError: return f = open(datafile('small.png'), 'r') fd = io.BytesIO(f.read()) upload = MediaIoBaseUpload(fd=fd, mimetype='image/png', chunksize=500, resumable=True) # Simulate 5XXs for both the request that creates the resumable upload and # the upload itself. http = HttpMockSequence([ ({ 'status': '500' }, ''), ({ 'status': '500' }, ''), ({ 'status': '503' }, ''), ({ 'status': '200', 'location': 'location' }, ''), ({ 'status': '500' }, ''), ({ 'status': '500' }, ''), ({ 'status': '503' }, ''), ({ 'status': '200' }, '{}'), ]) model = JsonModel() uri = u'https://www.googleapis.com/someapi/v1/upload/?foo=bar' method = u'POST' request = HttpRequest(http, model.response, uri, method=method, headers={}, resumable=upload) sleeptimes = [] request._sleep = lambda x: sleeptimes.append(x) request._rand = lambda: 10 request.execute(num_retries=3) self.assertEqual([20, 40, 80, 20, 40, 80], sleeptimes)
def test_good_response(self): model = JsonModel(data_wrapper=True) resp = httplib2.Response({'status': '200'}) resp.reason = 'OK' content = '{"data": "is good"}' content = model.response(resp, content) self.assertEqual(content, 'is good')
def test_good_response_wo_data(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({'status': '200'}) resp.reason = 'OK' content = '{"foo": "is good"}' content = model.response(resp, content) self.assertEqual(content, {'foo': 'is good'})
def test_good_response_wo_data_str(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({'status': '200'}) resp.reason = 'OK' content = '"data goes here"' content = model.response(resp, content) self.assertEqual(content, 'data goes here')
def test_no_content_response(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({'status': '204'}) resp.reason = 'No Content' content = '' content = model.response(resp, content) self.assertEqual(content, {})
def build_from_document( service, base, 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, discovery 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. 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. """ service = simplejson.loads(service) base = six.moves.urllib.parse.urljoin(base, service['basePath']) if future: future = simplejson.loads(future) auth_discovery = future.get('auth', {}) else: future = {} auth_discovery = {} schema = Schemas(service) if model is None: features = service.get('features', []) model = JsonModel('dataWrapper' in features) resource = createResource(http, base, model, requestBuilder, developerKey, service, future, schema) def auth_method(): """Discovery information about the authentication the API uses.""" return auth_discovery setattr(resource, 'auth_discovery', auth_method) return resource
def main(argv): # Load the key in PKCS 12 format that you downloaded from the xTuple Mobile # Web Client OAuth 2.0 Client registration workspace when you created your # Service account client. Place the file in the same directory as this file. f = file('privatekey.p12', 'rb') key = f.read() f.close() # Create an httplib2.Http object to handle our HTTP requests and authorize it # with the Credentials. Note that the first parameter, service_account_name, # is the Client ID created for the Service Account. #################### # TODO: Set these parameters to match your OAuth 2.0 Client values. #################### credentials = SignedJwtAssertionCredentials( 'example_f8ad6a5f-883b-4d41-ea6a-1971af1919e8', #service_account_name key, #private_key 'https://your-demo.xtuplecloud.com/your-db-name/auth', #scope private_key_password='******', user_agent=None, token_uri='https://your-demo.xtuplecloud.com/your-db-name/oauth/token', revoke_uri= 'https://your-demo.xtuplecloud.com/your-db-name/oauth/revoke-token', prn='admin') #################### # TODO: On production, do not disable_ssl_certificate_validation. Development only!!! #################### http = httplib2.Http(disable_ssl_certificate_validation=True) http = credentials.authorize(http) # By default, JsonModel is used and it sets alt_param = 'json'. The xTuple API # does not support an 'alt' query parameter, so we strip it off the model. # @See: google-api-python-client\apiclient\model.py _build_query() features = [] model = JsonModel('dataWrapper' in features) model.alt_param = None # Fetch the Discovery Document and build a service for the resources. #################### # TODO: Set the discoveryServiceUrl parameter to match your OAuth 2.0 Client value. # Optionally, use a difference resource than contact. #################### service = build( "contact", #serviceName "v1alpha1", #version http=http, discoveryServiceUrl= "https://your-demo.xtuplecloud.com/your-db-name/discovery/{apiVersion}/apis/{api}/{apiVersion}/rest", model=model) # List all the Contacts. lists = service.Contact().list().execute(http=http) pprint.pprint(lists)
def test_user_agent(self): model = JsonModel(data_wrapper=False) headers = {'user-agent': 'my-test-app/1.23.4'} path_params = {} query_params = {} body = {} headers, params, query, body = model.request(headers, path_params, query_params, body) self.assertEqual(headers['user-agent'], 'my-test-app/1.23.4 google-api-python-client/1.0')
def test_bad_response(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({'status': '401'}) resp.reason = 'Unauthorized' content = '{"error": {"message": "not authorized"}}' try: content = model.response(resp, content) self.fail('Should have thrown an exception') except HttpError, e: self.assertTrue('not authorized' in str(e))
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, str): service = simplejson.loads(service) base = urllib.parse.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 test_json_no_body(self): model = JsonModel(data_wrapper=False) headers = {} path_params = {} query_params = {} body = None headers, params, query, body = model.request(headers, path_params, query_params, body) self.assertEqual(headers['accept'], 'application/json') self.assertTrue('content-type' not in headers) self.assertNotEqual(query, '') self.assertEqual(body, None)
def test_json_body_data_wrapper(self): model = JsonModel(data_wrapper=True) headers = {} path_params = {} query_params = {} body = {} headers, params, query, body = model.request(headers, path_params, query_params, body) self.assertEqual(headers['accept'], 'application/json') self.assertEqual(headers['content-type'], 'application/json') self.assertNotEqual(query, '') self.assertEqual(body, '{"data": {}}')
def test_json_body_default_data(self): """Test that a 'data' wrapper doesn't get added if one is already present.""" model = JsonModel(data_wrapper=True) headers = {} path_params = {} query_params = {} body = {'data': 'foo'} headers, params, query, body = model.request(headers, path_params, query_params, body) self.assertEqual(headers['accept'], 'application/json') self.assertEqual(headers['content-type'], 'application/json') self.assertNotEqual(query, '') self.assertEqual(body, '{"data": "foo"}')
def test_logging(self): class MockLogging(object): def __init__(self): self.info_record = [] self.debug_record = [] def info(self, message, *args): self.info_record.append(message % args) def debug(self, message, *args): self.debug_record.append(message % args) class MockResponse(dict): def __init__(self, items): super(MockResponse, self).__init__() self.status = items['status'] for key, value in items.iteritems(): self[key] = value old_logging = apiclient.model.logging apiclient.model.logging = MockLogging() apiclient.model.FLAGS = copy.deepcopy(FLAGS) apiclient.model.FLAGS.dump_request_response = True model = JsonModel() request_body = {'field1': 'value1', 'field2': 'value2'} body_string = model.request({}, {}, {}, request_body)[-1] json_body = simplejson.loads(body_string) self.assertEqual(request_body, json_body) response = { 'status': 200, 'response_field_1': 'response_value_1', 'response_field_2': 'response_value_2' } response_body = model.response(MockResponse(response), body_string) self.assertEqual(request_body, response_body) self.assertEqual(apiclient.model.logging.info_record[:2], ['--request-start--', '-headers-start-']) self.assertTrue('response_field_1: response_value_1' in apiclient.model.logging.info_record) self.assertTrue('response_field_2: response_value_2' in apiclient.model.logging.info_record) self.assertEqual( simplejson.loads(apiclient.model.logging.info_record[-2]), request_body) self.assertEqual(apiclient.model.logging.info_record[-1], '--response-end--') apiclient.model.logging = old_logging
def test_unicode(self): http = HttpMock(datafile('zoo.json'), headers={'status': '200'}) model = JsonModel() uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar' method = u'POST' request = HttpRequest(http, model.response, uri, method=method, body=u'{}', headers={'content-type': 'application/json'}) request.execute() self.assertEqual(uri, http.uri) self.assertEqual(str, type(http.uri)) self.assertEqual(method, http.method) self.assertEqual(str, type(http.method))
def test_ensure_response_callback(self): m = JsonModel() request = HttpRequest( None, m.response, 'https://www.googleapis.com/someapi/v1/collection/?foo=bar', method='POST', body='{}', headers={'content-type': 'application/json'}) h = HttpMockSequence([ ({'status': 200}, '{}')]) responses = [] def _on_response(resp, responses=responses): responses.append(resp) request.add_response_callback(_on_response) request.execute(http=h) self.assertEqual(1, len(responses))
def setUp(self): model = JsonModel() self.request1 = HttpRequest( None, model.response, 'https://www.googleapis.com/someapi/v1/collection/?foo=bar', method='POST', body='{}', headers={'content-type': 'application/json'}) self.request2 = HttpRequest( None, model.response, 'https://www.googleapis.com/someapi/v1/collection/?foo=bar', method='GET', body='', headers={'content-type': 'application/json'})
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. """ # future is no longer used. future = {} if isinstance(service, basestring): service = json.loads(service) base = urlparse.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(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)
import pprint import sys from apiclient.discovery import build from apiclient.model import JsonModel FLAGS = gflags.FLAGS logger = logging.getLogger() logger.setLevel(logging.INFO) def main(argv): try: argv = FLAGS(argv) except gflags.FlagsError, e: print '%s\\nUsage: %s ARGS\\n%s' % (e, argv[0], FLAGS) sys.exit(1) service = build('translate', 'v2', developerKey='AIzaSyAQIKv_gwnob-YNrXV2stnY86GSGY81Zr0', model=JsonModel()) print service.translations().list( source='en', target='fr', q=['flower', 'car'] ).execute() if __name__ == '__main__': main(sys.argv)