def query_more(self, next_records_identifier, identifier_is_url=False, **kwargs): """Retrieves more results from a query that returned more results than the batch maximum. Returns a dict decoded from the Salesforce response JSON payload. Arguments: * next_records_identifier -- either the Id of the next Salesforce object in the result, or a URL to the next record in the result. * identifier_is_url -- True if `next_records_identifier` should be treated as a URL, False if `next_records_identifier` should be treated as an Id. """ if identifier_is_url: # Don't use `self.base_url` here because the full URI is provided url = (u'https://{instance}{next_record_url}'.format( instance=self.sf_instance, next_record_url=next_records_identifier)) else: url = self.base_url + 'query/{next_record_id}' url = url.format(next_record_id=next_records_identifier) result = self._call_salesforce('GET', url, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def _call_salesforce(self, method, url, name="", **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = self.headers.copy() additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers) result = self.session.request(method, url, headers=headers, **kwargs) if result.status_code == 401: # SalesforceExpiredSession print('Reconnecting ...') self._reconnect() print('... reconnected') headers = self.headers.copy() additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers) result = self.session.request(method, url, headers=headers, **kwargs) if result.status_code >= 300: exception_handler(result, name=name) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = self.parse_api_usage(sforce_limit_info) return result
def query_more( self, next_records_identifier, identifier_is_url=False, **kwargs): """Retrieves more results from a query that returned more results than the batch maximum. Returns a dict decoded from the Salesforce response JSON payload. Arguments: * next_records_identifier -- either the Id of the next Salesforce object in the result, or a URL to the next record in the result. * identifier_is_url -- True if `next_records_identifier` should be treated as a URL, False if `next_records_identifier` should be treated as an Id. """ if identifier_is_url: # Don't use `self.base_url` here because the full URI is provided url = (u'https://{instance}{next_record_url}' .format(instance=self.sf_instance, next_record_url=next_records_identifier)) else: url = self.base_url + 'query/{next_record_id}' url = url.format(next_record_id=next_records_identifier) result = self._call_salesforce('GET', url, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + self.session_id, 'X-PrettyPrint': '1' } additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers or dict()) result = self.session.request(method, url, headers=headers, **kwargs) # if result.status_code == 401: # SalesforceExpiredSession # self._reconnect(method, url, **kwargs) if result.status_code >= 300: exception_handler(result, self.name) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = Salesforce.parse_api_usage(sforce_limit_info) return result
def test_generic_error_code(self): """Test an error code that is otherwise not caught""" self.mockresult.status_code = 500 with self.assertRaises(SalesforceGeneralError) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ('Error Code 500. Response content' ': Example Content'))
def test_resource_not_found(self): """Test resource not found (404 code)""" self.mockresult.status_code = 404 with self.assertRaises(SalesforceResourceNotFound) as cm: exception_handler(self.mockresult, 'SpecialContacts') self.assertEqual(str(cm.exception), ( 'Resource SpecialContacts Not' ' Found. Response content: Example Content'))
def test_multiple_records_returned(self): """Test multiple records returned (a 300 code)""" self.mockresult.status_code = 300 with self.assertRaises(SalesforceMoreThanOneRecord) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'More than one record for ' 'http://www.example.com/. Response content: Example Content'))
def test_malformed_request(self): """Test a malformed request (400 code)""" self.mockresult.status_code = 400 with self.assertRaises(SalesforceMalformedRequest) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Malformed request ' 'http://www.example.com/. Response content: Example Content'))
def test_expired_session(self): """Test an expired session (401 code)""" self.mockresult.status_code = 401 with self.assertRaises(SalesforceExpiredSession) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Expired session for ' 'http://www.example.com/. Response content: Example Content'))
def test_request_refused(self): """Test a refused request (403 code)""" self.mockresult.status_code = 403 with self.assertRaises(SalesforceRefusedRequest) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Request refused for ' 'http://www.example.com/. Response content: Example Content'))
def test_generic_error_code(self): """Test an error code that is otherwise not caught""" self.mockresult.status_code = 500 with self.assertRaises(SalesforceGeneralError) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Error Code 500. Response content' ': Example Content'))
def test_resource_not_found(self): """Test resource not found (404 code)""" self.mockresult.status_code = 404 with self.assertRaises(SalesforceResourceNotFound) as cm: exception_handler(self.mockresult, 'SpecialContacts') self.assertEqual(str(cm.exception), ('Resource SpecialContacts Not' ' Found. Response content: Example Content'))
def test_request_refused(self): """Test a refused request (403 code)""" self.mockresult.status_code = 403 with self.assertRaises(SalesforceRefusedRequest) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Request refused for ' 'http://www.example.com/. Response content: Example Content'))
def test_expired_session(self): """Test an expired session (401 code)""" self.mockresult.status_code = 401 with self.assertRaises(SalesforceExpiredSession) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Expired session for ' 'http://www.example.com/. Response content: Example Content'))
def test_malformed_request(self): """Test a malformed request (400 code)""" self.mockresult.status_code = 400 with self.assertRaises(SalesforceMalformedRequest) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'Malformed request ' 'http://www.example.com/. Response content: Example Content'))
def test_multiple_records_returned(self): """Test multiple records returned (a 300 code)""" self.mockresult.status_code = 300 with self.assertRaises(SalesforceMoreThanOneRecord) as cm: exception_handler(self.mockresult) self.assertEqual(str(cm.exception), ( 'More than one record for ' 'http://www.example.com/. Response content: Example Content'))
def limits(self, **kwargs): """Return the result of a Salesforce request to list Organization limits. """ url = self.base_url + 'limits/' result = self._call_salesforce('GET', url, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def limits(self, **kwargs): """Return the result of a Salesforce request to list Organization limits. """ url = self.base_url + 'limits/' result = self._call_salesforce('GET', url, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ result = self.session.request( method, url, headers=self.headers, **kwargs) if result.status_code >= 300: exception_handler(result) return result
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ result = self.session.request(method, url, headers=self.headers, **kwargs) if result.status_code >= 300: exception_handler(result) return result
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ result = self.session.request( method, url, headers=self.headers, **kwargs) if result.status_code >= 300: exception_handler(result) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = self.parse_api_usage(sforce_limit_info) return result
def call_salesforce(url, method, session, headers, **kwargs): """Utility that generates a request to salesforce using urllib3 instead of requests package. This is necessary for connections that use the mutual authentication with encrypted certificates, the package requests can't handle it. PrepareRequest and HttpAdapter are used so that it returns a regular Response <requests.Response> that is expected for the rest of the process. """ additional_headers = kwargs.pop('additional_headers', dict()) headers.update(additional_headers or dict()) request_args = {'method': method.upper(), 'headers': headers} context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) # We will try and load the cert file and pass from the environment variables cert_file = os.environ.get('SIMPLE_SALESFORCE_CERT_FILE', None) cert_pass = os.environ.get('SIMPLE_SALESFORCE_PASSWORD', None) if cert_file and cert_pass: context.load_cert_chain(certfile=cert_file, password=cert_pass) request = PreparedRequest() parsed = urlparse(url) parsed = parsed._replace(netloc="{}:{}".format(parsed.hostname, 8443)) request.prepare(url=parsed.geturl(), data=kwargs.get('data') or {}, **request_args) http = PoolManager(ssl_context=context, cert_reqs='CERT_REQUIRED') result = http.urlopen(url=request.url, body=request.body, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, **request_args) adapter = HTTPAdapter() response = adapter.build_response(request, result) if response.status_code >= 300: from simple_salesforce.util import exception_handler exception_handler(response) adapter.close() return response
def query(self, query, **kwargs): """Return the result of a Salesforce SOQL query as a dict decoded from the Salesforce response JSON payload. Arguments: * query -- the SOQL query to send to Salesforce, e.g. SELECT Id FROM Lead WHERE Email = "*****@*****.**" """ url = self.base_url + 'query/' params = {'q': query} # `requests` will correctly encode the query string passed as `params` result = self._call_salesforce('GET', url, params=params, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + self.session_id, 'X-PrettyPrint': '1' } additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers or dict()) result = self.session.request(method, url, headers=headers, **kwargs) if result.status_code >= 300: exception_handler(result, self.name) return result
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + self.session_id, 'X-PrettyPrint': '1' } additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers or dict()) result = self.session.request(method, url, headers=headers, **kwargs) if result.status_code >= 300: exception_handler(result, self.name) return result
def _call_salesforce(self, method, url, **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ result = self.session.request(method, url, headers=self.headers, **kwargs) if result.status_code >= 300: exception_handler(result) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = self.parse_api_usage(sforce_limit_info) return result
def query(self, query, **kwargs): """Return the result of a Salesforce SOQL query as a dict decoded from the Salesforce response JSON payload. Arguments: * query -- the SOQL query to send to Salesforce, e.g. SELECT Id FROM Lead WHERE Email = "*****@*****.**" """ url = self.base_url + 'query/' params = {'q': query} # `requests` will correctly encode the query string passed as `params` result = self._call_salesforce('GET', url, params=params, **kwargs) if result.status_code != 200: exception_handler(result) return result.json(object_pairs_hook=OrderedDict)
def tooling(self, path, params): """Allows you to make a direct Tooling REST call if you know the path Arguments: * path: The path of the request Example: sobjects/User' * params: dict of parameters to pass to the path """ url = self.tool_url + path result = self.request.get(url, headers=self.headers, params=params) if result.status_code != 200: exception_handler(result) json_result = result.json(object_pairs_hook=OrderedDict) if len(json_result) == 0: return None else: return json_result
def _call_salesforce(self, method, url, name="", **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = self.headers.copy() additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers) result = self.session.request( method, url, headers=headers, **kwargs) if result.status_code >= 300: exception_handler(result, name=name) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = self.parse_api_usage(sforce_limit_info) return result
def _call_salesforce(self, method, url, name="", **kwargs): """Utility method for performing HTTP call to Salesforce. Returns a `requests.result` object. """ headers = self.headers.copy() additional_headers = kwargs.pop('headers', dict()) headers.update(additional_headers) if 'timeout' not in kwargs and self.timeout is not None: kwargs['timeout'] = self.timeout result = self.session.request(method, url, headers=headers, **kwargs) if result.status_code >= 300: exception_handler(result, name=name) sforce_limit_info = result.headers.get('Sforce-Limit-Info') if sforce_limit_info: self.api_usage = self.parse_api_usage(sforce_limit_info) return result