Posts tagged with python

I recently got my new Macbook Pro and installed 3.8.6 with pyenv and created a virtualenv for my project. When I try to run the tests for this project i get the following error about a module not found by a dependency (abridged). The the files are all there, ad_manager is a file right next to the __init__.py file that is importing it. This was not a problem on my old machine.

echo $PYTHONPATH is empty

python -c 'import sys; print(sys.path)' -> ['', '/Users/derek/.pyenv/versions/3.8.6/lib/python38.zip', '/Users/derek/.pyenv/versions/3.8.6/lib/python3.8', '/Users/derek/.pyenv/versions/3.8.6/lib/python3.8/lib-dynload', '/Users/derek/.pyenv/versions/VIRTUAL_ENV_3.8.6/lib/python3.8/site-packages']

Traceback (most recent call last):   File "/Users/derek/dev/PATH_TO_PROJECT/tests/../src/services/adwords_service.py", line 18, in <module>     from googleads import oauth2, adwords   File "/Users/derek/.pyenv/versions/VIRTUAL_ENV_3.8.6/lib/python3.8/site-packages/googleads/__init__.py", line 17, in <module>     from ad_manager import AdManagerClient ModuleNotFoundError: No module named 'ad_manager' 

I am migrating our API ingestion from googleads to google-ads in python and I noticed that the campaign resource only returns entities that have status "ENABLED". In the googleads version, it returns all entities by default when you request for it.

I tried modifying the GAQL to include filtering like where campaign.status != 'ENABLED' and I get no results back from the API.

Is there a way to get entities with all status like "PAUSED", "REMOVED" etc? Also, is there a place to run the GAQL in the web UI? (They have the GAQL validator but it doesn't let me run it)

I am trying to create a report for Extended Text Ads using Google Ads API.

I was able to do this for my reporting using Adwords API whereby I selected labels and labelids in the columns field.

cols = [     'AccountDescriptiveName', 'AdGroupId', 'AdGroupName', 'AdGroupStatus',     'AdNetworkType2', 'AdType', 'CampaignId', 'CampaignName',     'CampaignStatus', 'Clicks', 'Conversions', 'Cost', 'CreativeFinalUrls',     'Description', 'ExpandedTextAdDescription2', 'HeadlinePart1',     'HeadlinePart2', 'ExpandedTextAdHeadlinePart3', 'Id', 'Impressions',     'LabelIds', 'Labels', 'Path1', 'Path2', 'Status' ] sel = create_selector(     cols,     pred_fields=['Status', 'CampaignStatus', 'AdGroupStatus', 'AdNetworkType2', 'AdType'],     pred_operators=['EQUALS', 'EQUALS', 'EQUALS', 'EQUALS', 'EQUALS'],     pred_values=['ENABLED', 'ENABLED', 'ENABLED', 'SEARCH', 'EXPANDED_TEXT_AD']) ads_df = get_report_as_df(     client,     selector=sel,     report_type='AD_PERFORMANCE_REPORT',     date_range_type='LAST_30_DAYS', ) 

However, from what I understand the new GAQL approach requires using the ad_group_ad resource which does not have labelids and labelname inside? I know there is a ad_group_ad_label resource however, I am not sure how I can make use of it. Also https://developers.google.com/google-ads/api/docs/migration/mapping#ad_performance tells me that I should "Select label.resource_name from the resource ad_group_ad_label" but as GAQL queries only allow retrieval of one resource how do I go about it?

Currently I have these in my GAQL Query

SELECT customer.descriptive_name, ad_group.id, ad_group.name, ad_group.status, ad_group_ad.ad.type, campaign.id, campaign.name, campaign.status, metrics.clicks, metrics.conversions, metrics.cost_micros, ad_group_ad.ad.final_urls, ad_group_ad.ad.expanded_text_ad.description, ad_group_ad.ad.expanded_text_ad.description2, ad_group_ad.ad.expanded_text_ad.headline_part1, ad_group_ad.ad.expanded_text_ad.headline_part2, ad_group_ad.ad.expanded_text_ad.headline_part3, ad_group_ad.ad.id, metrics.impressions, ad_group_ad.ad.expanded_text_ad.path1, ad_group_ad.ad.expanded_text_ad.path2, ad_group_ad.status FROM ad_group_ad WHERE ad_group_ad.status = ENABLED AND campaign.status = ENABLED AND ad_group.status = ENABLED AND ad_group_ad.ad.type = EXPANDED_TEXT_AD 

I am trying to get the reports such as geo_performance_report, keywords_perfromance_report etc. but I am unable to figure how do to this with the new version of google-ads api. I tried this way trying to use the new google-ads but was not successful. is there any other ways to automate this process using Python.

def googleads_report(client, client_id, report_type, columns, start_date, end_date):     client.SetClientCustomerId(client_id)     report_downloader = googleads_client.GetReportDownloader(version="v201809")     report = {         'reportName': 'report-google-campaign-performance',         'dateRangeType': 'CUSTOM_DATE',         'reportType': report_type,         'downloadFormat': 'CSV',         'selector': {             'fields': columns,             'dateRange': {'min': start_date, 'max': end_date}         }     }     file = io.StringIO(report_downloader.DownloadReportAsString(         report,         skip_report_header=True,         skip_column_header=True,         skip_report_summary=True,         include_zero_impressions=False)     )     df = pd.read_csv(file, names=columns)     return df def main(client, customer_id):     keyword_columns = [         'Date',         'AccountDescriptiveName',         'AdGroupId',         'AdGroupName',         'AdGroupStatus',         'CampaignId',         'CampaignName',         'CampaignStatus',         'CpcBid',         'Criteria',         'CriteriaDestinationUrl',         'ExternalCustomerId',         'FirstPageCpc',         'FirstPositionCpc',         'Id',         'KeywordMatchType',         'Labels',         'QualityScore',         'SearchImpressionShare',         'Status',         'TopOfPageCpc',         'Clicks',         'Conversions',         'Cost',         'ConversionValue',         'Impressions',         'ViewThroughConversions'     ]     report_types = [         'KEYWORDS_PERFORMANCE_REPORT'     ]     for report in report_types:         base_df = pd.DataFrame()         if report == 'CAMPAIGN_PERFORMANCE_REPORT':             table_suffix = 'campaigns'             #columns = campaign_columns         elif report == 'KEYWORDS_PERFORMANCE_REPORT':             table_suffix = 'keywords'             columns = keyword_columns         elif report == 'AD_PERFORMANCE_REPORT':             table_suffix = 'ads'             #columns = ad_columns         start_date = '2019-01-01'         df = googleads_report(client,customer_id, report, columns, start_date, yesterday)         df = df.applymap(str)         # Powershell output         print(df.head())         # csv output         df.to_csv('my_path' + table_suffix + '.csv') if __name__ == "__main__":     # GoogleAdsClient will read the google-ads.yaml configuration file in the     # home directory if none is specified.     googleads_client = GoogleAdsClient.load_from_storage(path="mypath")     today = datetime.now().date()     yesterday = today - timedelta(days=1)     thirty_days_ago = today - timedelta(days=30)     try:         main( googleads_client, "#######")     except GoogleAdsException as ex:         print(             f'Request with ID "{ex.request_id}" failed with status '             f'"{ex.error.code().name}" and includes the following errors:'         )         for error in ex.failure.errors:             print(f'\tError with message "{error.message}".')             if error.location:                 for field_path_element in error.location.field_path_elements:                     print(f"\t\tOn field: {field_path_element.field_name}")             sys.exit(1) 

I have two issues:

I'm calling G-Ads API to bulk remove ads (code)

for error_detail in error_details:             # Retrieve an instance of the google_ads_failure class from the client             failure_message = gAdsServiceWrapper.client.get_type("google_ads_failure")             # Parse the string into a google_ads_failure message instance.             # To access class-only methods on the message we retrieve its type.             google_ads_failure = type(failure_message)             failure_object = google_ads_failure.deserialize(error_detail.value)             for error in failure_object.errors:                 # Construct and print a string that details which element in                 # the above ad_group_operations list failed (by index number)                 # as well as the error message and error code.                 print("A partial failure at index "                       f"{error.location.field_path_elements[0].index} occurred "                       f"\nError message: {error.message}\nError code: "                       f"{error.error_code}")                 index_array.append(error.location.field_path_elements[0].index)                 error_array.append({"error_message": error.message, "error_code": error.error_code}) 
  1. I get a partial error
  2. And the code fails to parse it (taken form the official website)

My terminal shows:

Partial failures occurred. Details will be shown below.

Traceback (most recent call last):   File "D:\projects\bowling\venv\lib\site-packages\google\ads\googleads\client.py", line 426, in get_type     message_class = getattr(type_classes, name)   File "D:\projects\bowling\venv\lib\site-packages\google\ads\googleads\v8\__init__.py", line 1753, in __getattr__     raise AttributeError(f"unknown type {name!r}.") AttributeError: unknown type 'google_ads_failure'. During handling of the above exception, another exception occurred: Traceback (most recent call last):   File "D:\projects\bowling\src\main.py", line 535, in <module>     main(args.top_id)   File "D:\projects\bowling\src\main.py", line 141, in main     removed_ads_count = remove_disapproved_ads_for_account(account)   File "D:\projects\bowling\src\main.py", line 206, in remove_disapproved_ads_for_account     remove_ads(ad_removal_operations, ads_to_remove_json, account_id)   File "D:\projects\bowling\src\main.py", line 300, in remove_ads     index_array, error_array = _print_results(response_chunk)   File "D:\projects\bowling\src\main.py", line 439, in _print_results     failure_message = gAdsServiceWrapper.client.get_type("google_ads_failure")   File "D:\projects\bowling\venv\lib\site-packages\google\ads\googleads\client.py", line 428, in get_type     raise ValueError( ValueError: Specified type 'google_ads_failure' does not exist in Google Ads API v8