Example #1
0
    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
Example #3
0
 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')
Example #6
0
        # 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:
Example #7
0
 def testValidateService_infoAllowed(self):
   AdWordsSanityCheck.ValidateService('InfoService', 'v201209')