Esempio n. 1
0
 def _get_service(self) -> GoogleAdsClient:
     """Connects and authenticates with the Google Ads API using a service account"""
     with NamedTemporaryFile("w", suffix=".json") as secrets_temp:
         self._get_config()
         self._update_config_with_secret(secrets_temp)
         try:
             client = GoogleAdsClient.load_from_dict(self.google_ads_config)
             return client.get_service("GoogleAdsService",
                                       version=self.api_version)
         except GoogleAuthError as e:
             self.log.error("Google Auth Error: %s", e)
             raise
Esempio n. 2
0
def setup_client():
    from google.ads.google_ads.client import GoogleAdsClient
    credentials = load_credentials()
    return GoogleAdsClient.load_from_dict(credentials)
Esempio n. 3
0
    def ewah_execute(self, context):
        # Task execution happens here
        def get_data_from_ads_output(fields_dict, values, prefix=None):
            if prefix is None:
                prefix = ''
            elif not prefix[-1] == '_':
                prefix += '_'
                # e.g. 2b prefix = 'ad_group_criterion_'
            data = {}
            for key, value in fields_dict.items():
                # e.g. 1 key = 'metrics', value = ['impressions', 'clicks']
                # e.g. 2a key = 'ad_group_criterion', value = [{'keyword': ['text', 'match_type']}]
                # e.g. 2b key = 'keyword', value = ['text', 'match_type']
                node = getattr(values, key)
                # e.g. 1 node = row.metrics
                # e.g. 2a node = row.ad_group_criterion
                # e.g. 2b node = row.ad_group_criterion.keyword
                for item in value:
                    # e.g. 1 item = 'clicks'
                    # e.g. 2a item = {'keyword': ['text', 'match_type']}
                    # e.g. 2b item = 'text'
                    if type(item) == dict:
                        data.update(
                            get_data_from_ads_output(
                                fields_dict=item,
                                values=node,
                                prefix=prefix +
                                key,  # e.g. 2a '' + 'ad_group_criterion'
                            ))
                    else:
                        # e.g. 1: {'' + 'metrics' + '_' + 'clicks': row.metrics.clicks.value}
                        # e.g. 2b: {'ad_group_criterion_' + 'keyeword' + '_' + 'text': row.ad_group_criterion.keyword.text.value}
                        if hasattr(getattr(node, item), 'value'):
                            data.update({
                                prefix + key + '_' + item: \
                                    getattr(node, item).value
                            })
                        else:
                            # some node ends don't respond to .value but are
                            #   already the value
                            data.update({
                                prefix + key + '_' + item:
                                getattr(node, item)
                            })
            return data

        self.data_until = airflow_datetime_adjustments(self.data_until)
        self.data_until = self.data_until or context['next_execution_date']
        if isinstance(self.data_from, timedelta):
            self.data_from = self.data_until - self.data_from
        else:
            self.data_from = airflow_datetime_adjustments(self.data_from)
            self.data_from = self.data_from or context['execution_date']

        conn = BaseHook.get_connection(self.source_conn_id).extra_dejson
        credentials = {}
        for key in self._REQUIRED_KEYS:
            if not key in conn.keys():
                raise Exception(
                    '{0} must be in connection extra json!'.format(key))
            credentials[key] = conn[key]

        # build the query
        query = 'SELECT {0} FROM {1} WHERE segments.date {2} {3}'.format(
            ', '.join(self.fields_list),
            self.resource,
            "BETWEEN '{0}' AND '{1}'".format(
                self.data_from.strftime('%Y-%m-%d'),
                self.data_until.strftime('%Y-%m-%d'),
            ),
            ('AND' + ' AND '.join(self.conditions)) if self.conditions else '',
        )

        self.log.info('executing this google ads query:\n{0}'.format(query))
        cli = GoogleAdsClient.load_from_dict(credentials)
        service = cli.get_service("GoogleAdsService", version="v3")
        search = service.search(
            self.client_id.replace('-', ''),
            query=query,
        )
        data = [row for row in search]

        # get into uploadable format
        upload_data = []
        while data:
            datum = data.pop(0)
            upload_data += [
                get_data_from_ads_output(
                    deepcopy(self.fields_dict),
                    datum,
                )
            ]

        self.upload_data(upload_data)
Esempio n. 4
0
    def ewah_execute(self, context):
        # Task execution happens here
        def get_data_from_ads_output(fields_dict, values, prefix=None):
            if prefix is None:
                prefix = ""
            elif not prefix[-1] == "_":
                prefix += "_"
                # e.g. 2b prefix = 'ad_group_criterion_'
            data = {}
            for key, value in fields_dict.items():
                # e.g. 1 key = 'metrics', value = ['impressions', 'clicks']
                # e.g. 2a key = 'ad_group_criterion', value = [{'keyword': ['text', 'match_type']}]
                # e.g. 2b key = 'keyword', value = ['text', 'match_type']
                node = getattr(values, key)
                # e.g. 1 node = row.metrics
                # e.g. 2a node = row.ad_group_criterion
                # e.g. 2b node = row.ad_group_criterion.keyword
                for item in value:
                    # e.g. 1 item = 'clicks'
                    # e.g. 2a item = {'keyword': ['text', 'match_type']}
                    # e.g. 2b item = 'text'
                    if type(item) == dict:
                        data.update(
                            get_data_from_ads_output(
                                fields_dict=item,
                                values=node,
                                prefix=prefix +
                                key,  # e.g. 2a '' + 'ad_group_criterion'
                            ))
                    else:
                        # e.g. 1: {'' + 'metrics' + '_' + 'clicks': row.metrics.clicks.value}
                        # e.g. 2b: {'ad_group_criterion_' + 'keyeword' + '_' + 'text': row.ad_group_criterion.keyword.text.value}
                        if hasattr(getattr(node, item), "value"):
                            data.update({
                                prefix + key + "_" + item:
                                getattr(node, item).value
                            })
                        else:
                            # some node ends don't respond to .value but are
                            #   already the value
                            data.update({
                                prefix + key + "_" + item:
                                getattr(node, item)
                            })
            return data

        conn = self.source_conn.extra_dejson
        credentials = {}
        for key in self._REQUIRED_KEYS:
            if not key in conn.keys():
                raise Exception(
                    "{0} must be in connection extra json!".format(key))
            credentials[key] = conn[key]

        # build the query
        query = "SELECT {0} FROM {1} WHERE segments.date {2} {3}".format(
            ", ".join(self.fields_list),
            self.resource,
            "BETWEEN '{0}' AND '{1}'".format(
                self.data_from.strftime("%Y-%m-%d"),
                self.data_until.strftime("%Y-%m-%d"),
            ),
            ("AND" + " AND ".join(self.conditions)) if self.conditions else "",
        )

        self.log.info("executing this google ads query:\n{0}".format(query))
        cli = GoogleAdsClient.load_from_dict(credentials)
        service = cli.get_service("GoogleAdsService", version="v3")
        search = service.search(
            self.client_id.replace("-", ""),
            query=query,
        )
        data = [row for row in search]

        # get into uploadable format
        upload_data = []
        fields_dict = deepcopy(self.fields_dict)
        fields_dict.update({self.resource: ["resource_name"]})
        while data:
            datum = data.pop(0)
            upload_data += [get_data_from_ads_output(
                fields_dict,
                datum,
            )]

        self.upload_data(upload_data)