def __init__(self, headers, config, op_config, lock, logger): """Inits TrafficEstimatorService. Args: headers: dict Dictionary object with populated authentication credentials. config: dict Dictionary object with populated configuration values. op_config: dict Dictionary object with additional configuration values for this operation. lock: thread.lock Thread lock logger: Logger Instance of Logger """ url = [ op_config['server'], 'api/adwords', op_config['version'], self.__class__.__name__ ] if AdWordsSanityCheck.IsJaxbApi(op_config['version']): url.insert(2, 'o') if config['access']: url.insert(len(url) - 1, config['access']) self.__name_space = 'https://adwords.google.com/api/adwords' self.__service = AdWordsWebService(headers, config, op_config, '/'.join(url), lock, logger) self._wsdl_types_map = WSDL_MAP[op_config['version']][ self.__service._GetServiceName()] super(TrafficEstimatorService, self).__init__(headers, config, op_config, url, 'adspygoogle.adwords', lock, logger)
def CallMethod(self, method_name, params, service_name=None, loc=None, request=None): """Make an API call to specified method. Args: method_name: str API method name. params: list List of parameters to send to the API method. [optional] service_name: str API service name. loc: service Locator. request: instance Holder of the SOAP request. Returns: tuple/str Response from the API method. If 'raw_response' flag enabled a string is returned, tuple otherwise. """ # Acquire thread lock. self._lock.acquire() try: if not service_name and self.__service: service_name = self.__service headers = self._headers config = self._config config['data_injects'] = () error = {} # Load/unload version specific authentication and configuration data. if AdWordsSanityCheck.IsJaxbApi(self._op_config['version']): # Set boolean to the format expected by the server, True => true. for key in ['validateOnly', 'partialFailure']: if key in self._headers: self._headers[key] = self._headers[key].lower() # Load/set authentication token. If authentication token has expired, # regenerate it. now = time.time() if ((('authToken' not in headers and 'auth_token_epoch' not in config) or int(now - config['auth_token_epoch']) >= AUTH_TOKEN_EXPIRE) and not 'oauth_enabled' in config): if ('email' not in headers or not headers['email'] or 'password' not in headers or not headers['password']): msg = ( 'Required authentication headers, \'email\' and ' '\'password\', are missing. Unable to regenerate ' 'authentication token.') raise ValidationError(msg) headers['authToken'] = Utils.GetAuthToken( headers['email'], headers['password'], AUTH_TOKEN_SERVICE, LIB_SIG, config['proxy']) config['auth_token_epoch'] = time.time() self._headers = headers self._config = config headers = Utils.UnLoadDictKeys( headers, ['email', 'password', 'useragent']) ns = '/'.join([ 'https://adwords.google.com/api/adwords', self._op_config['group'], self._op_config['version'] ]) default_ns = '/'.join([ 'https://adwords.google.com/api/adwords', self._op_config['default_group'], self._op_config['version'] ]) config['ns_target'] = (ns, 'RequestHeader') if (config['soap_lib'] == SOAPPY and (self._op_config['default_group'] != self._op_config['group'] or self.__service == 'BulkMutateJobService')): from adspygoogle.adwords.soappy import SERVICE_TYPES data_injects = [] for header in headers: if headers[header]: data_injects.append((header, 'ns1:%s' % header)) data_injects.append( ('<RequestHeader>', '<RequestHeader xmlns="%s" xmlns:ns1="%s">' % (ns, default_ns))) data_injects.append( ('<SOAP-ENV:Body xmlns="%s">' % ns, '<SOAP-ENV:Body xmlns="%s" xmlns:ns1="%s">' % (ns, default_ns))) for item in SERVICE_TYPES: if (item['group'] == self._op_config['default_group'] and re.compile( '<%s>|<%s ' % (item['attr'], item['attr'])).findall(params)): # TODO(api.sgrinberg): Find a more elegant solution that doesn't # involve manual triggering for attributes that show up in both # groups. if ((self._op_config['group'] == 'o' and item['attr'] == 'urls') or (self.__service == 'TrafficEstimatorService' and item['attr'] == 'maxCpc') or item['attr'] == 'selector' or item['attr'] == 'operator'): continue if self.__service != 'BulkMutateJobService': data_injects.append( (' xsi3:type="%s">' % item['type'], '>')) data_injects.append(('<%s>' % item['attr'], '<ns1:%s>' % item['attr'])) data_injects.append(('<%s ' % item['attr'], '<ns1:%s ' % item['attr'])) data_injects.append(('</%s>' % item['attr'], '</ns1:%s>' % item['attr'])) config['data_injects'] = tuple(data_injects) else: headers['useragent'] = headers['userAgent'] headers = Utils.UnLoadDictKeys(headers, ['authToken', 'userAgent']) config = Utils.UnLoadDictKeys( config, ['ns_target', 'auth_token_epoch']) buf = AdWordsSoapBuffer(xml_parser=self._config['xml_parser'], pretty_xml=Utils.BoolTypeConvert( self._config['pretty_xml'])) start_time = time.strftime('%Y-%m-%d %H:%M:%S') response = super(AdWordsWebService, self).CallMethod( headers, config, method_name, params, buf, AdWordsSanityCheck.IsJaxbApi(self._op_config['version']), LIB_SIG, LIB_URL, service_name, loc, request) stop_time = time.strftime('%Y-%m-%d %H:%M:%S') # Restore list type which was overwritten by SOAPpy. if config['soap_lib'] == SOAPPY and isinstance(response, tuple): from adspygoogle.common.soappy import MessageHandler holder = [] for element in response: holder.append( MessageHandler.RestoreListType( element, ('value', 'partialFailureErrors', 'conversionTypes'))) response = tuple(holder) if isinstance(response, dict) or isinstance(response, Error): error = response if not Utils.BoolTypeConvert(self.__config['raw_debug']): self.__ManageSoap(buf, start_time, stop_time, error) finally: # Release thread lock. if self._lock.locked(): self._lock.release() if Utils.BoolTypeConvert(self._config['raw_response']): return response return response
def testValidateService_infoAllowed(self): AdWordsSanityCheck.ValidateService('AdExtensionOverrideService', 'v201306')
# Patch v*/*.py: # - In local instances, whenever we encounter 'get' or 'mutate', we use # 'getXxx' or 'mutateXxx' respectively. The Xxx refer to the name of the # service (i.e. Campaign, AdGroup). # # This patch allows Python to import generated types with out collision. # Otherwise, we end up with types like 'mutate_Dec', 'mutate', etc. which # show up in all services and cause invalid instance of a service to be # invoked (defaults to the first instance that is found). So, if you invoke # an instance of CampaignService and AdGroupService and then try to add an # ad group, it will invoke 'mutate' from wrong service (CampaignService in # this case) resulting in a failure. for f_name in os.listdir(os.path.abspath(target['location'])): f_path = os.path.join(os.path.abspath(target['location']), f_name) f_parts = f_name.split('Service_') if AdWordsSanityCheck.IsJaxbApi(target['version']): if os.path.exists(f_path): fh = open(f_path, 'r') try: data = fh.read() ops = ['get', 'mutate'] if f_name.find('_services.py') > -1: for op in ops: data = data.replace('def %s(' % op, 'def %s%s(' % (op, f_parts[0])) data = data.replace('# op: %s' % op, '# %s: get%s' % (op, f_parts[0])) data = data.replace('%sRequest' % op, '%s%sRequest' % (op, f_parts[0])) data = data.replace('%sResponse' % op, '%s%sResponse' % (op, f_parts[0]))
def testValidateService_infoAllowed(self): AdWordsSanityCheck.ValidateService('CampaignSharedSetService', 'v201409')
# Prompt user to update configuration values. if header == 'soap_lib' or header == 'xml_parser': res = raw_input('%s: ' % prompt_msg).rstrip('\r') if not SanityCheck.IsConfigUserInputValid(res, ['1', '2']): msg = 'Possible values are \'1\' or \'2\'.' raise InvalidInputError(msg) else: res = raw_input('%s [y/n]: ' % prompt_msg).rstrip('\r') if not SanityCheck.IsConfigUserInputValid(res, ['y', 'n']): msg = 'Possible values are \'y\' or \'n\'.' raise InvalidInputError(msg) config[header] = res # Raise an exception, if required headers are missing. SanityCheck.ValidateRequiredHeaders(auth, REQUIRED_SOAP_HEADERS) if not AdWordsSanityCheck.IsClientIdSet(auth['clientEmail'], auth['clientCustomerId']): msg = 'Set either clientEmail or clientCustomerId, but not both.' raise InvalidInputError(msg) # Load new authentication credentials into adwords_api_auth.pkl. try: fh = open(AUTH_PKL, 'w') try: pickle.dump(auth, fh) finally: fh.close() except IOError, e: logger.Log(LOG_NAME, e, log_level=Logger.ERROR) # Load new configuratation values into adwords_api_config.pkl. try:
def testValidateService_infoAllowed(self): AdWordsSanityCheck.ValidateService('InfoService', 'v201209')