2
votes

I need to get a keywords performance report form Adwords into Python. I'm connecting Python to Adwords via de Adwords API using a service account with the googleads library. All seems to run smoothly until I try to download the report with data_downloader.DownloadReportWithAwql, where I get "AttributeError: 'str' object has no attribute 'CreateHttpHeader'".

I'm authenticating to the service account using the adwords module, then I'm calling the "ReportDefinitionService" with the corresponding adwords client. After that I'm creating the data downloader object and building the adwords query to finally download the report with Awql.

I've taken a look at:

How To Pull Data From the Adwords API and put into a Pandas Dataframe

https://developers.google.com/adwords/api/docs/samples/python/reporting

https://github.com/googleads/googleads-python-lib/issues/253

https://developers.google.com/adwords/api/docs/reference/v201809/ReportDefinitionService

I don't have MCC account access (which is getting increasingly hard to get), but I'm supposed to have everything setup in the Google Cloud. Here my code:

from googleads import oauth2
from googleads import adwords
import pandas as pd
import numpy as np
import os



# Initialize the GoogleRefreshTokenClient

oauth2_client = oauth2.GoogleServiceAccountClient("marketing-analytics93839202-038212.json", oauth2.GetAPIScope('adwords'))

# Initialize the Adwords client.
adwords_client = adwords.AdWordsClient(oauth2_client, 'AdWords')
ad_report_service = adwords_client.GetService('ReportDefinitionService', 
version='v201809')


# Construct query

data_downloader = adwords_client.GetReportDownloader(version='v201809')



# Create report query.
 report_query = (adwords.ReportQueryBuilder()
              .Select('CampaignId', 'AdGroupId', 'Id', 'Criteria',
                      'Conversions', 'Impressions', 'Clicks','Ctr',
                      'Cost')
              .From('KEYWORDS_PERFORMANCE')
              .Where('Status').In('ENABLED', 'PAUSED')
              .During('LAST_30_DAYS')
              .Build())

# Up to this point there are no apparent errors. Now write the output

data_downloader.DownloadReportWithAwql(report_query, 
file_format='CSV',client_customer_id='xxx-xxx-xxxx',
skip_report_header=True, skip_column_header=False, 
skip_report_summary=True,include_zero_impressions=False)

>> AttributeError: 'str' object has no attribute 'CreateHttpHeader'

I get AttributeError: 'str' object has no attribute 'CreateHttpHeader'. I'm expecting a pandas dataframe with the report as queried.

2

2 Answers

0
votes

The signature of AdWordsClient's constructor is

def __init__(self, developer_token, oauth2_client,
               user_agent=_DEFAULT_USER_AGENT, soap_impl='zeep',
               timeout=3600, **kwargs):

You are using your oauth2_client instance as developer_token parameter, and pass 'AdWords' where the OAuth2 client should go:

adwords_client = adwords.AdWordsClient(oauth2_client, 'AdWords')

Once you add your developer token as the first argument to adwords.AdWordsClient, the error should go away:

adwords_client = adwords.AdWordsClient(DEV_TOKEN, oauth2_client, 'AdWords')
0
votes

To download a report into a pandas dataframe use this:

oauth2_client = oauth2.GoogleServiceAccountClient("marketing-analytics93839202-038212.json", oauth2.GetAPIScope('adwords'))

# Initialize the Adwords client.
adwords_client = adwords.AdWordsClient(oauth2_client, 'AdWords')
# Define output as a string
output = io.StringIO()

report_downloader = adwords_client.GetReportDownloader(version='v201809')

# Create report query.
report_query = ('''
SELECT CampaignName, CampaignId, AdGroupId, AdGroupName,QueryMatchTypeWithVariant, Query,Cost,Clicks,Conversions,Impressions
from SEARCH_QUERY_PERFORMANCE_REPORT
WHERE CampaignId IN [''' + str(activeCampaignId) +''']''')

# Write query result to output file
report_downloader.DownloadReportWithAwql(
    report_query, 
    'CSV',
    output,
    #client_customer_id='xxx-xxx-xxx', # denotes which adw account to pull from
    skip_report_header=True, 
    skip_column_header=False,
    skip_report_summary=True, 
    include_zero_impressions=False)

output.seek(0)

df = pd.read_csv(output)