def CallRawMethod(self, soap_message): """Make an API call by posting raw SOAP XML message. Args: soap_message: str SOAP XML message. Returns: tuple Response from the API method. """ # Acquire thread lock. self._lock.acquire() try: buf = AdWordsSoapBuffer(xml_parser=self._config['xml_parser'], pretty_xml=Utils.BoolTypeConvert( self._config['pretty_xml'])) super(AdWordsWebService, self).CallRawMethod( buf, Utils.GetNetLocFromUrl(self._op_config['server']), soap_message) self.__ManageSoap(buf, self._start_time, self._stop_time, {'data': buf.GetBufferAsStr()}) finally: # Release thread lock. if self._lock.locked(): self._lock.release() return (self._response, )
def __GetLogHandlers(self, buf): """Gets a list of log handlers for the DFA library. Args: buf: SoapBuffer SOAP buffer from which calls are retrieved for logging. Returns: list Log handlers for the DFA library. """ return [ { 'tag': 'xml_log', 'name': 'soap_xml', 'data': '' }, { 'tag': 'request_log', 'name': 'request_info', 'data': str('host=%s service=%s method=%s responseTime=%s ' 'requestID=%s' % (Utils.GetNetLocFromUrl(self._service_url), self._service_name, buf.GetCallName(), buf.GetCallResponseTime(), buf.GetCallRequestId())) }, { 'tag': '', 'name': 'dfa_api_lib', 'data': '' } ]
def putrequest(self, method, url, skip_host=False, skip_accept_encoding=False): """Send a request to the server. Args: method: str Specifies an HTTP request method. url: str Specifies the object being requested. [optional] skip_host: bool If True does not add automatically a 'Host:' header. skip_accept_encoding: bool If True does not add automatically an 'Accept-Encoding:' header. """ if HttpConnectionHandler.compress: skip_accept_encoding = True if self.__http_proxy != self.__host: scheme = Utils.GetSchemeFromUrl(url) or 'http' netloc = Utils.GetNetLocFromUrl(url) or self.__host path = Utils.GetPathFromUrl(url) uri = '%s://%s%s' % (scheme, netloc, path) else: uri = url httplib.HTTPConnection.putrequest( self, method=method, url=uri, skip_host=skip_host, skip_accept_encoding=skip_accept_encoding)
def __ManageSoap(self, buf, start_time, stop_time, error={}): """Manage SOAP XML message. Args: buf: SoapBuffer SOAP buffer. start_time: str Time before service call was invoked. stop_time: str Time after service call was invoked. [optional] error: dict Error, if any. """ try: # Set up log handlers. handlers = [{ 'tag': 'xml_log', 'name': 'soap_xml', 'data': '' }, { 'tag': 'request_log', 'name': 'request_info', 'data': str('host=%s service=%s method=%s responseTime=%s ' 'requestId=%s' % (Utils.GetNetLocFromUrl( self._url), buf.GetServiceName(), buf.GetCallName(), buf.GetCallResponseTime(), buf.GetCallRequestId())) }, { 'tag': '', 'name': 'dfp_api_lib', 'data': '' }] fault = super(DfpWebService, self)._ManageSoap(buf, handlers, LIB_URL, ERRORS, start_time, stop_time, error) if fault: # Raise a specific error, subclass of DfpApiError. if 'detail' in fault: if 'code' in fault['detail']: code = int(fault['detail']['code']) if code in ERRORS: raise ERRORS[code](fault) elif 'errors' in fault['detail']: type = fault['detail']['errors'][0]['type'] if type in ERRORS: raise ERRORS[str(type)](fault) if isinstance(fault, str): raise DfpError(fault) elif isinstance(fault, dict): raise DfpApiError(fault) except DfpApiError, e: raise e
def __MakeRequest(self, url, headers=None, file_path=None): """Performs an HTTPS request and slightly processes the response. If file_path is provided, saves the body to file instead of including it in the return value. Args: url: str Resource for the request line. headers: dict Headers to send along with the request. file_path: str File to save to (optional). Returns: dict process response with the following structure {'body': 'body of response', 'status': 'http status code', 'headers': 'headers that came back with the response'} """ headers = headers or {} # Download report. conn = httplib.HTTPSConnection( Utils.GetNetLocFromUrl(self._op_config['server'])) conn.connect() conn.putrequest('GET', url) for key in headers: conn.putheader(key, headers[key]) conn.endheaders() response = conn.getresponse() response_headers = {} for key, value in response.getheaders(): response_headers[key] = value body = None if file_path: self.__DumpToFile(response, file_path) else: body = response.read() return { 'body': body, 'status': response.status, 'headers': response_headers, 'reason': response.reason }
def __ManageSoap(self, buf, start_time, stop_time, error={}): """Manage SOAP XML message. Args: buf: SoapBuffer SOAP buffer. start_time: str Time before service call was invoked. stop_time: str Time after service call was invoked. [optional] error: dict Error, if any. """ try: # Update the number of units and operations consumed by API call. if buf.GetCallUnits() and buf.GetCallOperations(): self._config['units'][0] += int(buf.GetCallUnits()) self._config['operations'][0] += int(buf.GetCallOperations()) self._config['last_units'][0] = int(buf.GetCallUnits()) self._config['last_operations'][0] = int( buf.GetCallOperations()) # Set up log handlers. handlers = [{ 'tag': 'xml_log', 'name': 'soap_xml', 'data': '' }, { 'tag': 'request_log', 'name': 'request_info', 'data': str('host=%s service=%s method=%s operator=%s ' 'responseTime=%s operations=%s units=%s requestId=%s' % (Utils.GetNetLocFromUrl(self._url), buf.GetServiceName(), buf.GetCallName(), buf.GetOperatorName(), buf.GetCallResponseTime(), buf.GetCallOperations(), buf.GetCallUnits(), buf.GetCallRequestId())) }, { 'tag': '', 'name': 'adwords_api_lib', 'data': '' }] fault = super(AdWordsWebService, self)._ManageSoap(buf, handlers, LIB_URL, ERRORS, start_time, stop_time, error) if fault: # Raise a specific error, subclass of AdWordsApiError. if 'detail' in fault: if 'code' in fault['detail']: code = int(fault['detail']['code']) if code in ERRORS: raise ERRORS[code](fault) elif 'errors' in fault['detail']: type = fault['detail']['errors'][0]['type'] if type in ERRORS: raise ERRORS[str(type)](fault) if isinstance(fault, str): raise AdWordsError(fault) elif isinstance(fault, dict): raise AdWordsApiError(fault) except AdWordsApiError, e: raise e
def CallRawMethod(self, soap_message): """Makes an API call by POSTing a raw SOAP XML message to the server. Args: soap_message: str SOAP XML message. Returns: tuple Raw XML response from the API method. Raises: Error: if the SOAP call is not successful. Most likely this is the result of the server sending back an HTTP error, such as a 502. """ self._lock.acquire() try: buf = self._buffer_class(xml_parser=self._config['xml_parser'], pretty_xml=Utils.BoolTypeConvert( self._config['pretty_xml'])) http_header = { 'post': self._service_url, 'host': Utils.GetNetLocFromUrl(self._op_config['server']), 'user_agent': '%s; CallRawMethod' % self.__class__.__name__, 'content_type': 'text/xml; charset=\"UTF-8\"', 'content_length': '%d' % len(soap_message), 'soap_action': '' } if self._headers.get('oauth2credentials'): self._headers['oauth2credentials'].apply(http_header) self._start_time = time.strftime('%Y-%m-%d %H:%M:%S') buf.write( '%s Outgoing HTTP headers %s\nPOST %s\nHost: %s\nUser-Agent: ' '%s\nContent-type: %s\nContent-length: %s\nSOAPAction: %s\n' % ('*' * 3, '*' * 46, http_header['post'], http_header['host'], http_header['user_agent'], http_header['content_type'], http_header['content_length'], http_header['soap_action'])) if self._headers.get('oauth2credentials'): buf.write('Authorization: ' + http_header['Authorization'] + '\n') buf.write('%s\n%s Outgoing SOAP %s\n%s\n%s\n' % ('*' * 72, '*' * 3, '*' * 54, soap_message, '*' * 72)) if self._op_config['http_proxy']: real_address = self._op_config['http_proxy'] else: real_address = http_header['host'] # Construct header and send SOAP message. web_service = httplib.HTTPS(real_address) web_service.putrequest('POST', http_header['post']) web_service.putheader('Host', http_header['host']) web_service.putheader('User-Agent', http_header['user_agent']) web_service.putheader('Content-type', http_header['content_type']) web_service.putheader('Content-length', http_header['content_length']) web_service.putheader('SOAPAction', http_header['soap_action']) if self._headers.get('oauth2credentials'): web_service.putheader('Authorization', http_header['Authorization']) web_service.endheaders() web_service.send(soap_message) # Get response. status_code, status_message, header = web_service.getreply() response = web_service.getfile().read() header = str(header).replace('\r', '') buf.write( ('%s Incoming HTTP headers %s\n%s %s\n%s\n%s\n%s Incoming SOAP' ' %s\n%s\n%s\n' % ('*' * 3, '*' * 46, status_code, status_message, header, '*' * 72, '*' * 3, '*' * 54, response, '*' * 72))) self._stop_time = time.strftime('%Y-%m-%d %H:%M:%S') # Catch local errors prior to going down to the SOAP layer, which may not # exist for this error instance. if not buf.IsHandshakeComplete() or not buf.IsSoap(): # The buffer contains non-XML data, most likely an HTML page. This # happens in the case of 502 errors. html_error = Utils.GetErrorFromHtml(buf.GetBufferAsStr()) if html_error: msg = html_error else: msg = 'Unknown error.' raise Error(msg) self._HandleLogsAndErrors(buf, self._start_time, self._stop_time) finally: self._lock.release() if self._config['wrap_in_tuple']: response = MessageHandler.WrapInTuple(response) return response