Giter Site home page Giter Site logo

google-ads-python's People

Contributors

adamchainz avatar akaashhazarika avatar anashoommen avatar andrewmburke avatar arammaliachi avatar artemrys avatar benrkarl avatar bobhancock avatar bobhancockg avatar danielfrg avatar davedavis avatar fblascogarma avatar fiboknacky avatar githaruo avatar jiulongw avatar johnjameswhitman avatar jradcliff avatar jsshandle avatar laurachevalier4 avatar msaniscalchi avatar pierrickvoulet avatar sarahdorich avatar sbloodys avatar stevenberger avatar vishket avatar wihl avatar xflesym avatar yangda avatar yukiyamamuro avatar yunstanford avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

google-ads-python's Issues

No Planning Examples

Several other libraries (.NET, Java, PHP) have a planning example folder covering keyword idea generation and traffic estimation. Is this likely to come to the Python library any time soon?

dependendancy PyYAML <5 seems to have broken pipenv install

specifying a non-existent PyYAML version seems to have broken pipenv locking of dependancies, you can reproduce this with pipenv install googleads==15.0.2

Here is what am getting:

Adding googleads to Pipfile's [packages]…
Pipfile.lock (35a056) out of date, updating to (269757)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…

Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
Could not find a version that matches pyyaml<5.0,>=4.2b1
Tried: 3.10, 3.10, 3.11, 3.11, 3.12, 3.12, 3.12, 3.12, 3.12, 3.12, 3.12, 3.12, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13, 3.13
Skipped pre-versions: 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13b1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 3.13rc1, 4.2b1, 4.2b2, 4.2b4, 4.2b4, 4.2b4, 4.2b4, 4.2b4
There are incompatible versions in the resolved dependencies

module 'google.ads.google_ads' has no attribute 'client'

I'm trying to use this library to access my clients' data, so authenticating via token and not YAML file.

With the AdWords library I would do something like this:

oauth2_client = oauth2.GoogleRefreshTokenClient(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, refresh_token)
adwords_client = adwords.AdWordsClient(ADWORDS_DEV_TOKEN'], oauth2_client, client_customer_id=aw_account)
service = adwords_client.GetService('CampaignService', version='v201806')

Now I'm trying to migrate to this new library and I'm doing something like this:

import google
##
credentials = google.oauth2.credentials.Credentials(None,refresh_token = refresh_token,client_id =GOOGLE_CLIENT_ID,client_secret = GOOGLE_CLIENT_SECRET, token_uri = 'https://accounts.google.com/o/oauth2/token')
credentials.refresh(google.auth.transport.requests.Request())
client = google.ads.google_ads.client.GoogleAdsClient(credentials,ADWORDS_DEV_TOKEN)
ga_service = client.get_service('GoogleAdsService')

However I get the following error:
module 'google.ads.google_ads' has no attribute 'client'
What am I doing wrong?

ExceptionInterceptor fails to capture error data

The ExceptionInterceptor in client.py is intended to scan the response's trailing_metadata and parse a GoogleAdsFailure, which is then used to construct a detailed GoogleAdsException.

It seems that some (all?) exceptions are no longer being correctly parsed, resulting in very generic and potentially misleading error messages.

As a temporary work-around, users can catch the exception and view its trailing metadata to determine if there is an underlying Google Ads API error.

provide dynamically loading client settings by object instead of using load_by_string

Following the example, we need to make a yaml file to set client settings and use GoogleAdsClient.load_from_storage to create a new client instance, but it does not make sense in production service that provides multiple customers to fetch their ads.

My current solution is like this,

   configuration_string = '\n'.join([
        'developer_token: %s' % developer_token,
        'client_id: %s' % client_id,
        'client_secret: %s' % client_secret,
        'refresh_token: %s' % refresh_token,
        'login_customer_id: %s' % login_customer_id
    ])
    client = google.ads.google_ads.client.GoogleAdsClient.load_from_string(configuration_string)

I use GoogleAdsClient.load_from_string to make a string as yaml format, but I think it had better provide a function to load settings by dictionary(object), and it will be more easy to use.

custom date ranges not working in queries

Using library 0.5.

When I submit this query, everything works fine:

        SELECT
          date,
          campaign.id,
          metrics.impressions
        FROM campaign
        WHERE date DURING LAST_7_DAYS
          AND metrics.impressions > 0

but this query fails with GoogleAdsException:

        SELECT
          date,
          campaign.id,
          metrics.impressions
        FROM campaign
        WHERE date >= '2018-11-03'
          AND date <= '2018-11-10'
          AND metrics.impressions > 0

The code executing the queries looks like:

client = (google_ads.client.GoogleAdsClient.load_from_storage())
service = self.client.get_service('GoogleAdsService')
service.search(customer_id, query=query, page_size=1000)

The documentation on custom date ranges says this is the correct format, and I've seen Google employees suggest queries that look like this in the forums... so why does this query fail when sent from this library?

my hunch is that maybe the quotes are being encoded incorrectly by this library?

Response to issues #29 and #30

Google's github policies forbid me to respond to issues, so I'm opening a new issue to respond to @BenRKarl's response to my ticket

@BenRKarl -

  1. when are these fixes going to be released?
  2. why wasn't it ready to go when a breaking change to the API was released?

I thought this was the official client library. We have a large amount of adwords spend dependent on this library working; to suddenly break the world like this without having an official client library ready seems like borderline technological malpractice.

New "Discovery" campaigns are not reporting spend

Recently Google Ads rolled out a whole new type of inventory - "Discovery" campaigns - which is in beta.

Making basic AWQL queries (spend by campaign) via this package does not seem to return any spend on these new types of campaigns. Is that expected or am I missing something?

(Similar to googleads/googleads-python-lib#388 which I created in the wrong library)

Feature Request: Add Option to Cache Access Token

Hi,

I'm trying to get a basic example working, but keep receiving the same error:

...
    return _end_unary_response_blocking(state, call, True, None)
  File "/Users/Louis/anaconda3/lib/python3.6/site-packages/grpc/_channel.py", line 466, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNAUTHENTICATED
	details = "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."
	debug_error_string = "{"created":"@1537546478.122567000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1099,"grpc_message":"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.","grpc_status":16}"

The example code is shown below:

import google.ads.google_ads.client

customer_id = "123"
client = google.ads.google_ads.client.GoogleAdsClient.load_from_storage(
    "google-ads.yaml")
ga_service = client.get_service("GoogleAdsService")

query = ('SELECT campaign.id FROM campaign ORDER BY campaign.id')
results = ga_service.search(customer_id, query)

try:
    for row in results:
        print('Campaign with ID %d and name "%s" was found.'
              % (row.campaign.id.value, row.campaign.name.value))
except google.ads.google_ads.errors.GoogleAdsException as ex:
    print('Request with ID "%s" failed with status "%s" and includes the '
          'following errors:' % (ex.request_id, ex.error.code().name))

My credentials file google-ads.yaml is set up as follows:

client_id: CLIENT_ID
client_secret: CLIENT_SECRET
refresh_token: REFRESH_TOKEN
developer_token: DEVELOPER_TOKEN 

I assume the GoogleAdsClient generates an access_token from the refresh_token? Am I misunderstanding how to send an authenticated request?

Thanks,

Louis

'serialized_options' not found in google\protobuf\descriptor.py

Running the get_campaign.py example, using Python 3.6.6 and google-ads 0.7.0.

Full stack trace:

Traceback (most recent call last):
File "C:\Users\david\Red Apple Services\Admin\Processes and Templates\Python Scripts - Live\get_campaign.py", line 25, in
import google.ads.google_ads.client
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads_init_.py", line 19, in
import google.ads.google_ads.client
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads\client.py", line 27, in
from google.ads.google_ads.v0.proto.errors import errors_pb2 as error_protos
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads\v0_init_.py", line 19, in
from google.ads.google_ads.v0 import types
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads\v0\types.py", line 22, in
from google.ads.google_ads.v0.proto.common import ad_type_infos_pb2
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads\v0\proto\common\ad_type_infos_pb2.py", line 15, in
from google.ads.google_ads.v0.proto.enums import call_conversion_reporting_state_pb2 as google_dot_ads_dot_googleads__v0_dot_proto_dot_enums_dot_call__conversion__reporting__state__pb2
File "C:\Users\david\AppData\Roaming\Python\Python36\site-packages\google\ads\google_ads\v0\proto\enums\call_conversion_reporting_state_pb2.py", line 22, in
serialized_pb=_b('\nIgoogle/ads/googleads_v0/proto/enums/call_conversion_reporting_state.proto\x12\x1dgoogle.ads.googleads.v0.enums"\xcc\x01\n CallConversionReportingStateEnum"\xa7\x01\n\x1c\x43\x61llConversionReportingState\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0b\n\x07UNKNOWN\x10\x01\x12\x0c\n\x08\x44ISABLED\x10\x02\x12,\n(USE_ACCOUNT_LEVEL_CALL_CONVERSION_ACTION\x10\x03\x12-\n)USE_RESOURCE_LEVEL_CALL_CONVERSION_ACTION\x10\x04\x42\xf6\x01\n!com.google.ads.googleads.v0.enumsB!CallConversionReportingStateProtoP\x01ZBgoogle.golang.org/genproto/googleapis/ads/googleads/v0/enums;enums\xa2\x02\x03GAA\xaa\x02\x1dGoogle.Ads.GoogleAds.V0.Enums\xca\x02\x1dGoogle\Ads\GoogleAds\V0\Enums\xea\x02!Google::Ads::GoogleAds::V0::Enumsb\x06proto3')
TypeError: init() got an unexpected keyword argument 'serialized_options'

[Feature request] device bid adjustments for campaigns

At the moment is possible to add bid adjustments for devices only selecting Ad Groups.

It would be very useful if we could do the same for campaigns which at the moment support only CALL bid adjustments.

Is this feature going to be released sometime soon? Thanks!

Service Accounts working on Google Ads API

Hi,

You indicate here that service accounts are currently not supported by Google Ads API.

Is there an estimate for this feature? Or an alternative that supports the same functionality?
My use case requires service accounts to authenticate services in Google Ads, but mainly requires those services to act on behalf of an user, and have that users's visibility over ads accounts.

We are developing new services, and would rather not have to user AdWords api to implement this since is being discontinued. However, we need the functionality on Google Ads API.

Thanks for the attention.

-c/--customer_id error

Hi, I am working to get my Google Ads API setup through Python and I'm currently running into an issue with the get_campaigns.py initial request.

I have completed the setup of the API and added the developer_token, client_id, client_secret, refresh_token, and login_customer_id to my google-ads.yaml file but when I run the get_campaigns.py from the examples folder in this repository I am getting this error in my command line:

(PythonData) BSKEG1ML1:~ bskedgell$ python get_campaigns.py usage: get_campaigns.py [-h] -c CUSTOMER_ID get_campaigns.py: error: the following arguments are required: -c/--customer_id (PythonData) BSKEG1ML1:~ bskedgell$

I'm not sure where I need to input this customer_id as I'm guessing it's the 10 digit number associated with MCC Google Ads account. It is referenced in the correct format in the google-ads.yaml file and I cannot find many resources online to troubleshoot this specific error. Also I took a look at the common errors section of this webpage (https://developers.google.com/google-ads/api/docs/common-errors) and the two errors relating to "customer_id" seem not to be causing my issue.

Furthermore, I have confirmed that I set up the API correctly with an older version of this API (AdWords) using the googleads.yaml file and then the get get_account_hierarchy.py file from the AdWords repository.

Here is a snippet of the API running correctly on the AdWords version:

(PythonData) BSKEG1ML1:~ bskedgell$ python get_account_hierarchy.py CustomerId, Name

Could someone help me out with this issue? Happy to document and contribute more info if needed. Thanks for your time!

keyword plan idea service does not give suggested bid like in old target idea service

the old version of target idea service was giving suggested bid for each keyword, on the other hand in the new keyword plan idea service, it only gives a field called competition which has values low, medium, high.

Is there any way by which I can get suggested bid for keywords? if not, is there any plan to introduce it again in future updates?

Adding Sitelinks to Campaign

I am having difficulties to understand how to add SiteLinks to a campaign, any chance somebody could point me into the right direction.

I would assume that I have to do something like this:

extension_setting_service = client.get_service('CampaignExtensionSettingService', version='v1')
extension_budget_operation = client.get_service('CampaignExtensionSettingOperation', version='v1')

And then create a SiteLink Ressource? However, the CampaignExtensionSettingOperation does not exist. So that does not seem to be the way to go.

Reading through the developer documentation, it would appear that some field mapping from a feed could be the solution, but again I am somewhat lost here.

Probably something generated akin of this
https://developers.google.com/google-ads/api/reference/rpc/google.ads.googleads.v1.enums#google.ads.googleads.v1.enums.SitelinkPlaceholderFieldEnum.SitelinkPlaceholderField
should go somewhere here
https://developers.google.com/google-ads/api/reference/rpc/google.ads.googleads.v1.resources#campaignextensionsetting

Any pointers appreciated!

Issue mutating campaign network targeting settings

An update mutate operation on a campaign which includes just changes to the network_targeting settings (4 booleans) goes successfully through the mutate operation, however upon re-requesting the resource, the changes to the network targeting settings appear to have not taken place.

Campaign is a search campaign, modifying any of the following values has no apparent effect:

campaign.network_settings.target_content_network
campaign.network_settings.target_google_search
campaign.network_settings.target_partner_search_network
campaign.network_settings.target_search_network

As I said above, the mutate happens successfully and the campaign resource path is returned in the response. Thanks.

get_all_disapproved_ads.py: "google.api_core.exceptions.InternalServerError: 500 Internal error encountered"

Hi,

when I'm running this example-code:

https://github.com/googleads/google-ads-python/blob/master/examples/campaign_management/get_all_disapproved_ads.py

... I keep getting the same error message (campaign.id and customerId redacted):

Request: {
"query": "SELECT ad_group_ad.ad.id, ad_group_ad.ad.type, ad_group_ad.policy_summary FROM ad_group_ad WHERE campaign.id = 1234567890",
"customerId": "1234567890",
"pageSize": 1000
}

Response

Headers: {
"request-id": "4YSRSCHSrLkHLNIIaUWIyA"
}
Fault: {
"created": "@1554112639.978011373",
"description": "Error received from peer",
"file": "src/core/lib/surface/call.cc",
"file_line": 1039,
"grpc_message": "Internal error encountered.",
"grpc_status": 13
}

The problem is persistant and replicable.
There are no disapproved ads in the campaigns affected but there are ads with multiple restrictions. I figure that these multiple restrictions are not handled correctly by the API.

Would you have someone look into it?

Regards
Mat

querying video_quartile_25_rate causes google.protobuf.internal.well_known_types.Error: Fail to print FieldMask to Json string

This issue arose trying to upgrade to package 0.6/API 0.7. Trying to query metrics.video_quartile_25_rate gives google.protobuf.internal.well_known_types.Error: Fail to print FieldMask to Json string: The character after a "_" must be a lowercase letter in path name metrics.video_quartile_25_rate.

full stack trace:

File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/page_iterator.py", line 199, in _items_iter
   for page in self._page_iter(increment=False):
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/page_iterator.py", line 230, in _page_iter
   page = self._next_page()
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/page_iterator.py", line 512, in _next_page
   response = self._method(self._request)
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
   return wrapped_func(*args, **kwargs)
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
   on_error=on_error,
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/retry.py", line 177, in retry_target
   return target()
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
   return func(*args, **kwargs)
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
   return callable_(*args, **kwargs)
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/grpc/_interceptor.py", line 201, in __call__
   credentials=credentials)
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/grpc/_interceptor.py", line 226, in _with_call
   return call.result(), call
 File "/Users/oogabooga/repos/airflow-workflows/.venv/lib/python2.7/site-packages/grpc/_interceptor.py", line 116, in result
   raise self._exception
google.protobuf.internal.well_known_types.Error: Fail to print FieldMask to Json string: The character after a "_" must be a lowercase letter in path name metrics.video_quartile_25_rate.

How do you compare `ErrorCode`s?

If I have the following:

        results = ga_service.search(self.client_customer_id, query=query, page_size=page_size)

        try:
            yield from results

        except GoogleAdsException as ex:
            <'error handling here'>

There is a lot of information in ex. The examples in this repo print the exception request_id and the name of the status (ex.error.code().name)

Instead of accessing the status, which can be general, I want to access the actual failures,
ex.failure.errors.

for error in ex.failure.errors:
    if error.code == <'not sure what to do here'>:
        <'process individual failure'>

A use-case I have is that I want to trigger a certain code path if we receive a CLIENT_CUSTOMER_ID_INVALID and a different one if we get a CUSTOMER_NOT_ACTIVE. Using the StatusCode, both of these errors have a status of UNAUTHENTICATED.

My thoughts are that you need to create your own ErrorCode, but I am not having success with that using

error_code = client.get_type('ErrorCode', version='v1')

Any ideas?

filtering on segments.device breaks query

query is as follows:

SELECT
  segments.date,
  campaign.id,
  segments.ad_network_type,
  campaign.advertising_channel_type,
  campaign.advertising_channel_sub_type,
  metrics.clicks,
  metrics.cost_micros,
  metrics.all_conversions,
  metrics.all_conversions_value,
  metrics.impressions,
  metrics.average_position,
  metrics.conversions,
  metrics.content_impression_share,
  metrics.content_budget_lost_impression_share,
  metrics.content_rank_lost_impression_share,
  metrics.search_impression_share,
  metrics.search_budget_lost_impression_share,
  metrics.search_rank_lost_impression_share
FROM
    campaign
WHERE
    segments.date >= '2019-02-01' AND
    segments.date <= '2019-02-04' AND 
    segments.device IN (MOBILE) AND
    metrics.impressions >= 0

the query works properly except for when clause below is present:
segments.device IN (MOBILE) AND

the field in question should be selectable as well as filterable. the error i'm receiving back is not verbose (other errors i've received have been verbose in terms of the logging). this is what i get:

InvalidArgument: 400 Request contains an invalid argument.

i also tried reducing the selected fields to comply with the supported metrics listed in the documentation under segments.device as follows:

SELECT
  segments.date,
  campaign.id,
  segments.ad_network_type,
  campaign.advertising_channel_type,
  campaign.advertising_channel_sub_type,
  metrics.clicks,
  metrics.cost_micros,
  metrics.all_conversions,
  metrics.all_conversions_value,
  metrics.impressions,
  metrics.average_position,
  metrics.conversions,
  metrics.search_impression_share,
  metrics.search_budget_lost_impression_share,
  metrics.search_rank_lost_impression_share
FROM
    campaign
WHERE
    segments.date >= '2019-02-01' AND
    segments.date <= '2019-02-04' AND 
    segments.device = MOBILE AND
    metrics.impressions >= 0

i'm hoping i haven't missed something in the documentation. i am using v0.7 of the client library

segments.device documentation

ValueError: Specified Google Ads API version "v1" does not exist.

Good morning

When running the get_campaigns.py from the basic example folder we get to following error

`Traceback (most recent call last):
File "/Users/cgagnon/Documents/projects/gads-beta/.venv/lib/python3.7/site-packages/google/ads/google_ads/client.py", line 334, in _get_version
version = getattr(google.ads.google_ads, name)
AttributeError: module 'google.ads.google_ads' has no attribute 'v1'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/user/Documents/projects/gads-beta/google-ads-python/examples/basic_operations/get_campaigns.py", line 67, in
main(google_ads_client, args.customer_id, _DEFAULT_PAGE_SIZE)
File "/Users/user/Documents/projects/gads-beta/google-ads-python/examples/basic_operations/get_campaigns.py", line 32, in main
ga_service = client.get_service('GoogleAdsService', version='v1')
File "/Users/user/Documents/projects/gads-beta/.venv/lib/python3.7/site-packages/google/ads/google_ads/client.py", line 173, in get_service
version = _get_version(version)
File "/Users/user/Documents/projects/gads-beta/.venv/lib/python3.7/site-packages/google/ads/google_ads/client.py", line 337, in _get_version
% name)
ValueError: Specified Google Ads API version "v1" does not exist.`

"No status received" with 100 operations for MutateAdGroupAds

I'm getting a "No status received" grpc response (see below), when calling:

service = client.get_service("AdGroupAdService")
resp = service.mutate_ad_group_ads(customer_id, operations) # len(operations) == 100

I believe that I can get a proper response if I send fewer operations (around 10? untested).
However, since the API should be able to handle 5000 operations at a time, I think this is an issue that should be flagged.

An element in operations above looks like

google.ads.googleads_v0.types.AdGroupAdOperation

create {
  ad_group {
    value: "customers/{redacted}/adGroups/{redacted}"
  }
  ad {
    final_urls {
      value: "https://redacted.com"
    }
    display_url {
    }
    expanded_text_ad {
      headline_part1 {
        value: "redacted"
      }
      headline_part2 {
        value: "redacted"
      }
      description {
        value: "redcated"
      }
      description2 {
        value: "redacted"
      }
    }
  }
}

Traceback

WARNING:google.ads.google_ads.client:Request made: ClientCustomerId: [REDACTED], Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v0.services.AdGroupAdService/MutateAdGroupAds, RequestId: None, IsFault: True, FaultMessage: No status received
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 57, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 215, in __call__
    wait_for_ready=wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 245, in _with_call
    return call.result(), call
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 295, in result
    raise self
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 236, in continuation
    wait_for_ready=new_wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 258, in with_call
    wait_for_ready=wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 245, in _with_call
    return call.result(), call
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 295, in result
    raise self
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 236, in continuation
    wait_for_ready=new_wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 258, in with_call
    wait_for_ready=wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 244, in _with_call
    continuation, client_call_details, request)
  File "/usr/local/lib/python3.7/site-packages/google/ads/google_ads/client.py", line 335, in intercept_unary_unary
    self._handle_grpc_failure(response)
  File "/usr/local/lib/python3.7/site-packages/google/ads/google_ads/client.py", line 310, in _handle_grpc_failure
    raise exception
  File "/usr/local/lib/python3.7/site-packages/grpc/_interceptor.py", line 236, in continuation
    wait_for_ready=new_wait_for_ready)
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 560, in with_call
    return _end_unary_response_blocking(state, call, True, None)
  File "/usr/local/lib/python3.7/site-packages/grpc/_channel.py", line 467, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNKNOWN
	details = "No status received"
	debug_error_string = "{"created":"@1550664734.372858800","description":"No status received","file":"src/core/lib/surface/call.cc","file_line":1058,"grpc_status":2}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/google/ads/google_ads/v0/services/ad_group_ad_service_client.py", line 278, in mutate_ad_group_ads
    request, retry=retry, timeout=timeout, metadata=metadata)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py", line 143, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/retry.py", line 270, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.7/site-packages/google/api_core/retry.py", line 179, in retry_target
    return target()
  File "/usr/local/lib/python3.7/site-packages/google/api_core/timeout.py", line 214, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unknown: None No status received

[API Issue] SearchGoogleAdsRequest fails if there are too many results

I believe that this is an issue with the underlying API, but I wasn't sure where to bring it up. I currently can't tell what the error message is from this library, but my own wrapper for the api suggests that the response from the server is:

{
  "error": {
    "code": 503,
    "message": "The service is currently unavailable.",
    "status": "UNAVAILABLE"
  }
}

I believe using page_token and page_size does not resolve this.

keyword_plan_idea_service_client.py

Hello

I am trying to run the service KeywordPlanIdeaService in keyword_plan_idea_service_client.py.

File "/Code/new_/ai_analyzer/venv/lib/python3.7/site-packages/google/ads/google_ads/v1/services/keyword_plan_idea_service_client.py", line 249, in generate_keyword_ideas
    url_seed=url_seed,
TypeError: Parameter to MergeFrom() must be instance of same class: expected google.protobuf.StringValue got str.

I can't import google.protobuf.StringValue and also can't find the format of UrlSeed.

How do I run this service.

Also when I am trying to use rest api from this url
'https://googleads.googleapis.com/v1/customers/' + customer_id + ':generateKeywordIdeas/', I am only able get keywords when I give customer_id of MCC account. but if I try to give ids of linked accounts to MCC one, it does not work, as it fails in authentication.

So , do I have to obtain separate authentication token for each linked accounts to MCC account?

Regards
Pratiksha

ConversionUploadService GRPC Internal error encountered

Hi,

I'm trying to upload offline conversion using ConversionUploadService, and I've been receiving 500 Internal error encountered

Here's the code:

conversion_upload_service = client.get_service('ConversionUploadService', version='v1')
conversion_upload_service.upload_click_conversions(<customer_id>, <conversions>, <partial_failure>)

Error stack trace:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/muhammad.khadafi/.pyenv/versions/2.7.15/lib/python2.7/site-packages/google/ads/google_ads/v1/services/conversion_upload_service_client.py", line 220, in upload_click_conversions
    request, retry=retry, timeout=timeout, metadata=metadata)
  File "/Users/muhammad.khadafi/.pyenv/versions/2.7.15/lib/python2.7/site-packages/google/api_core/gapic_v1/method.py", line 143, in __call__
    return wrapped_func(*args, **kwargs)
  File "/Users/muhammad.khadafi/.pyenv/versions/2.7.15/lib/python2.7/site-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "/Users/muhammad.khadafi/.pyenv/versions/2.7.15/lib/python2.7/site-packages/six.py", line 737, in raise_from
    raise value
google.api_core.exceptions.InternalServerError: 500 Internal error encountered.

errors from google.api_core.exceptions.GoogleAPICallError shows me:

[<_Rendezvous of RPC that terminated with:
	status = StatusCode.INTERNAL
	details = "Internal error encountered."
	debug_error_string = "{"created":"@1555357512.579840000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1039,"grpc_message":"Internal error encountered.","grpc_status":13}"
>]

I've tried this on Python 2.7.15 and 3.6.6

I've mentioned this on #68, but the ticket was closed when it was resolved for the original poster. However, it still applies to my problem.

Any help would be greatly appreciated. Thanks!

Regards,
Dafi

Syntax error when call service

  File "/home/nikolai/projects/google-ads-adapter/sdfdsdf.py", line 16, in <module>
    print list(campaigns)
  File "/home/nikolai/projects/google-ads-adapter/google_adapter/adapter/services/campaign.py", line 32, in get
    service = self._client.get_service('GoogleAdsService', version='v1')
  File "/home/nikolai/.virtualenvs/google-ads-adapter-qiVpOMiY/local/lib/python2.7/site-packages/google/ads/google_ads/client.py", line 189, in get_service
    api_module = _get_version(version)
  File "/home/nikolai/.virtualenvs/google-ads-adapter-qiVpOMiY/local/lib/python2.7/site-packages/google/ads/google_ads/client.py", line 681, in _get_version
    version = import_module('google.ads.google_ads.%s' % name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/nikolai/.virtualenvs/google-ads-adapter-qiVpOMiY/local/lib/python2.7/site-packages/google/ads/google_ads/v1/__init__.py", line 19
    from google.ads.google_ads.1 import types
                               ^
SyntaxError: invalid syntax```

get recommendation example prints nothing

Hello

I am trying the following piece of code

https://github.com/googleads/google-ads-python/blob/master/examples/recommendations/get_text_ad_recommendations.py

It does not print anything, I have tries with multiple customer ids.
Also , by looking at the API and other example of apply recommendation , I tried to use get recommendation from Recommendation Service. I do not know what should be resource name to get recommendations for text ads. I tried with 'google.ads.googleads.v1.resources.Recommendation.TextAdRecommendation' but it gives the following error.

`google.ads.google_ads.errors.GoogleAdsException: (<_Rendezvous of RPC that terminated with:
status = StatusCode.NOT_FOUND
details = "Requested entity was not found."
debug_error_string = "{"created":"@1553604325.576345000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1036,"grpc_message":"Requested entity was not found.","grpc_status":5}"

, <_Rendezvous of RPC that terminated with:
status = StatusCode.NOT_FOUND
details = "Requested entity was not found."
debug_error_string = "{"created":"@1553604325.576345000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1036,"grpc_message":"Requested entity was not found.","grpc_status":5}"
, errors {
error_code {
request_error: BAD_RESOURCE_ID
}
message: "'google.ads.googleads.v1.resources.Recommendation.TextAdRecommendation' part of the resource name is invalid."
}
`

Kindly update how to use the example to get recommendations for text ad.

Regards
Pratiksha

BiddingSource Enum Numbers are not valid for V1 (0,1,2,3,5 vs 0,1,5,6,7)

Hey,

We've noticed that the BiddingSource enum numbers need to be updated for V1.
They are now 0,1,5,6,7
Where as for V0 they were
0,1,2,3,5

2 and 3 appear to have been changed to 6 and 7 and further qualified with the prefix "AD_GROUP" instead of "ADGROUP".

V1 base proto description:
https://github.com/googleapis/googleapis/blob/master/google/ads/googleads/v1/enums/bidding_source.proto

V1 python library pb2 file
https://github.com/googleads/google-ads-python/blob/master/google/ads/google_ads/v1/proto/enums/bidding_source_pb2.py

This can be confirmed by issuing a request against the API and results containing 6 and 7 come back.

ad_group_criterion { resource_name: "customers/xxxx/adGroupCriteria/yyyy~385605240383" status: ENABLED ad_group { value: "customers/xxxx/adGroups/yyyy" } cpc_bid_micros { value: 100000000 } effective_cpc_bid_micros { value: 100000000 } effective_cpm_bid_micros { value: 1000000 } effective_cpc_bid_source: 7 effective_cpm_bid_source: 6 type: KEYWORD criterion_id { value: 385605240383 } keyword { text { value: "+test +8" } match_type: BROAD } negative { } system_serving_status: ELIGIBLE }

Let me know if you have any questions.

Unable to update ad_group.targeting_setting.target_restrictions

Hey Ben,

I'm not even sure if this is supposed to be possible but I'm having trouble updating ad_group.targeting_setting.target_restrictions it appears to throw a server side error saying the field is immutable. Do you know if this is an error, functionality that is yet to be implemented, or soon to be no longer supported?

I did look in the documentation https://developers.google.com/google-ads/api/reference/rpc/google.ads.googleads.v1.common#google.ads.googleads.v1.common.TargetingSetting
On other fields that are non mutable there is a note that says something like "This field is required for CREATE operations and is prohibited on UPDATE operations."
This note is not on TargetingSetting, and historically these values were mutable on the AdWords API. So I'm not entirely sure whats going on.

Below is the API log incase I'm making some mistake and you have some suggestions. Thanks!

Peter

Request
-------
Method: /google.ads.googleads.v1.services.AdGroupService/MutateAdGroups
Host: googleads.googleapis.com:443
Headers: {
  "developer-token": "REDACTED",
  "login-customer-id": "6715128853",
  "x-goog-api-client": "gl-python/2.7.12 grpc/1.14.2 gax/1.4.1 gapic/1.1.1"
}
Request: {
  "operations": [
    {
      "update": {
        "resourceName": "customers/6715128853/adGroups/69225813358",
        "targetingSetting": {
          "targetRestrictions": [
            {
              "bidOnly": true,
              "targetingDimension": "AUDIENCE"
            }
          ]
        }
      },
      "updateMask": "resourceName,targetingSetting.targetRestrictions"
    }
  ],
  "partialFailure": true,
  "customerId": "6715128853"
}
Response
-------
Headers: {
  "content-disposition": "attachment",
  "request-id": "WmQbbceJWjM_JLvM7LhFOA"
}
Response: {
  "partialFailureError": {
    "message": "Field 'targeting_setting.target_restrictions' cannot be modified by 'UPDATE' operation., at operations[0].update.targeting_setting.target_restrictions",
    "code": 3,
    "details": [
      {
        "@type": "type.googleapis.com/google.ads.googleads.v1.errors.GoogleAdsFailure",
        "errors": [
          {
            "errorCode": {
              "requestError": "IMMUTABLE_FIELD"
            },
            "message": "Field 'targeting_setting.target_restrictions' cannot be modified by 'UPDATE' operation.",
            "location": {
              "fieldPathElements": [
                {
                  "index": "0",
                  "fieldName": "operations"
                },
                {
                  "fieldName": "update"
                },
                {
                  "fieldName": "targeting_setting"
                },
                {
                  "fieldName": "target_restrictions"
                }
              ]
            }
          }
        ]
      }
    ]
  },
  "results": [
    {}
  ]
}

503 DNS resolution failed for keyword report example

I'm attempting to walk through the example for pulling a keyword report, and it looks like I'm successfully initializing the client and service.

I'm using Anaconda Python 3.7.1, have installed google-ads 1.3.1. The service is set to version 'v1' as in the provided example.

When I run the sample query, I get to line 48:

for row in response:
        campaign = row.campaign
        ad_group = row.ad_group
...

Which throws an exception:

Request made: ClientCustomerId: XXX-XXX-XXXX, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v1.services.GoogleAdsService/Search, RequestId: None, IsFault: True, FaultMessage: DNS resolution failed

and

_Rendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "DNS resolution failed"
debug_error_string = "{"created":"@1555542001.640383000","description":"Failed to create subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":2715,"referenced_errors":[{"created":"@1555541990.752433000","description":"Resolver transient failure","file":"src/core/ext/filters/client_channel/resolving_lb_policy.cc","file_line":335,"referenced_errors":[{"created":"@1555541990.752432000","description":"DNS resolution failed","file":"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc","file_line":326,"grpc_status":14,"referenced_errors":[{"created":"@1555541990.752381000","description":"C-ares status is not ARES_SUCCESS: DNS query cancelled","file":"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc","file_line":240,"referenced_errors":[{"created":"@1555541990.752374000","description":"C-ares status is not ARES_SUCCESS: DNS query cancelled","file":"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc","file_line":240}]}]}]}]}"

Error with campaign.advertising_channel_type

I am using the python client library to connect to Google Ads's API.

ga_service = client_service.get_service('GoogleAdsService')
    query = ('SELECT campaign.id, campaign.name, campaign.advertising_channel_type '
            'FROM campaign WHERE date BETWEEN \''+fecha+'\' AND \''+fecha+'\'')

    response = ga_service.search(<client_id>, query=query,page_size=1000)
    result = {}
    result['campanas'] = []

    try:
        for row in response:
            print row
            info = {}
            info['id'] = row.campaign.id.value
            info['name'] = row.campaign.name.value
            info['type'] = row.campaign.advertising_channel_type

When I parse the values this is the result I get:

{
  "campanas": [
    {
      "id": <campaign_id>, 
      "name": "Lanzamiento SIKU", 
      "type": 2
    }, 
    {
      "id": <campaign_id>, 
      "name": "lvl1 - website traffic", 
      "type": 2
    }, 
    {
      "id": <campaign_id>, 
      "name": "Lvl 2 - display", 
      "type": 3
    }
  ]
}

Why am I getting an integer for result["type"] ? When I check the traceback call I can see a string:

campaign {
  resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
  id {
    value: 397083380
  }
  name {
    value: "Lanzamiento SIKU"
  }
  advertising_channel_type: SEARCH
}

campaign {
  resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
  id {
    value: 1590766475
  }
  name {
    value: "lvl1 - website traffic"
  }
  advertising_channel_type: SEARCH
}

campaign {
  resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
  id {
    value: 1590784940
  }
  name {
    value: "Lvl 2 - display"
  }
  advertising_channel_type: DISPLAY
}

I've searched on the Documentation for the API and found out that it's because the field: advertising_channel_type is of Data Type: Enum. How can I manipulate this object of the Enum class to get the string value? There is no helpful information about this on their Documentation.

You have this documentation where it mentions the Enum class for the field AdvertisingChannelType: https://github.com/googleapis/googleapis/blob/master/google/ads/googleads/v0/enums/advertising_channel_type.proto

but there are missing values for 3 and 4, so it is impossible to map which number corresponds to which advertising channel type:

 // Enum describing the various advertising channel types.
  enum AdvertisingChannelType {
    // Not specified.
    UNSPECIFIED = 0;
    // Used for return value only. Represents value unknown in this version.
    UNKNOWN = 1;
    // Search Network. Includes display bundled, and Search+ campaigns.
    SEARCH = 2;
    // Hotel Ads campaigns.
    HOTEL = 5;
  }
}

segments.date is not returned in query response

before the release of 0.7 today/yesterday, i had this AWQL and it was fine:

SELECT
  date,
  customer.id,
  campaign.id,
  campaign.name,
  metrics.cost_micros
FROM campaign
WHERE metrics.impressions > 0
  AND date >= '2019-11-22'
  AND date <= '2019-12-22'

this broke with the release of 0.7. after some fiddling i figured out that we now have to use segments, so i updated it to be:

SELECT
  segments.date,
  customer.id,
  campaign.id,
  campaign.name,
  metrics.cost_micros
FROM campaign
WHERE metrics.impressions > 0
  AND segments.date >= '2019-11-22'
  AND segments.date <= '2019-12-22'

this runs but... when i inspect the rows that are returned, the segments.date does not appear at all.

customer {
  resource_name: "customers/9704954372"
  id {
    value: 9704954372
  }
}
campaign {
  resource_name: "customers/9704954372/campaigns/1355772182"
  id {
    value: 1234
  }
  name {
    value: "Search|Branded|Blah"
  }
}
metrics {
  cost_micros {
    value: 2025690000
  }
}

what gives?

__future__ imports must occur at beginning of file

Using python 3.6 and running the keyword recommendation service I get the following error:

SyntaxError: from __future__ imports must occur at the beginning of the file

Python version is what is bundled/maintained by Anaconda (using Spyder), deleted comments at start of file seems to fix this but that's a bit hacky.

Exception not being parsed properly

Related to #8

There still seems to be an issue, with AttributeError: '_Rendezvous' object has no attribute 'request_id' on this line. This can easily be replicated with a GoogleAdsService.search request with an syntactically invalid query.

RecursionError: maximum recursion depth exceeded

I'm trying to perform an API call from my tests (pytest) and just this command: GetReportDownloader(version='v201809') already throws an exception as follows:

tests/test_googleads_api.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
env/lib/python3.6/site-packages/googleads/adwords.py:426: in GetReportDownloader
    return ReportDownloader(self, version, server)
env/lib/python3.6/site-packages/googleads/adwords.py:1269: in __init__
    self.proxy_config, self._namespace, self._adwords_client.cache)
env/lib/python3.6/site-packages/googleads/common.py:821: in __init__
    data = transport.load(endpoint)
env/lib/python3.6/site-packages/zeep/transports.py:110: in load
    content = self._load_remote_data(url)
env/lib/python3.6/site-packages/zeep/transports.py:126: in _load_remote_data
    response = self.session.get(url, timeout=self.load_timeout)
env/lib/python3.6/site-packages/requests/sessions.py:546: in get
    return self.request('GET', url, **kwargs)
env/lib/python3.6/site-packages/requests/sessions.py:533: in request
    resp = self.send(prep, **send_kwargs)
env/lib/python3.6/site-packages/requests/sessions.py:646: in send
    r = adapter.send(request, **kwargs)
env/lib/python3.6/site-packages/requests/adapters.py:449: in send
    timeout=timeout
env/lib/python3.6/site-packages/urllib3/connectionpool.py:600: in urlopen
    chunked=chunked)
env/lib/python3.6/site-packages/urllib3/connectionpool.py:343: in _make_request
    self._validate_conn(conn)
env/lib/python3.6/site-packages/urllib3/connectionpool.py:839: in _validate_conn
    conn.connect()
env/lib/python3.6/site-packages/urllib3/connection.py:332: in connect
    cert_reqs=resolve_cert_reqs(self.cert_reqs),
env/lib/python3.6/site-packages/urllib3/util/ssl_.py:281: in create_urllib3_context
    context.options |= options
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
    super(SSLContext, SSLContext).options.__set__(self, value)
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
    super(SSLContext, SSLContext).options.__set__(self, value)
E   RecursionError: maximum recursion depth exceeded
!!! Recursion detected (same locals & position)

I'm running this with:

platform darwin -- Python 3.6.7, pytest-4.3.0, py-1.7.0, pluggy-0.8.0
plugins: flask-0.14.0, celery-4.2.0

Internal server error on uploading same image asset twice

Hi. I upload an image assets into Google Ads test account. I noticed, that when I upload same image twice, but with different name, the second time it fails with Internal Server Error 500. It would be nice to handle the case on Google's side and return error like "image asset, which you are trying to upload, already exists with with name xxx and resource_name yyy".

My code looks like this:

asset = asset_operation.create
asset.name.value = "test"  # resp. "test 2" the second time
asset.type = asset_type_enum.IMAGE
asset.image_asset.mime_type = mime_type_enum.IMAGE_JPEG
asset.image_asset.data.value = image_data_bytes
asset_service.mutate_assets(customer_id, [asset_operation])

I guess it's related to the API itself, not specifically to this Python client, but can you check it? Thanks 👍

Example code lacks shebang line

It looks like some (all?) example code lacks the shebang line that should be at the start of the file:

#!/usr/bin/env python

Cleanup Logging Error Parsing

With the release of API v0_7 we merged this PR in order to eliminate the bugs related to logging (i.e. parsing data from error objects), as described in issues such as this.

I'd like to revisit this implementation and refactor it using Eric's feedback in the PR.

cannot retrieve display ad data from ad_group_ad

I was trying to retrieve display ad data from ad_group_ad.
I succeeded to get data before by using adwords API library.
However, I failed to get data by using new google-ads API library.

import google.ads.google_ads.client

_DEFAULT_PAGE_SIZE = 1000
CUSTOMER_ID = <XXXXXXX>


if __name__ == "__main__":
    client = google.ads.google_ads.client.GoogleAdsClient.load_from_storage()
    ga_service = client.get_service("GoogleAdsService", version="v1")
    query = "SELECT ad_group_ad.ad.type FROM ad_group_ad"

    results = ga_service.search(CUSTOMER_ID, query=query, page_size=_DEFAULT_PAGE_SIZE)

    for row in results:
       print(row)

I have questions:

  1. Is this known limitation?
  2. If so, are there any schedules to support it?

Thanks.

ListingDimensionInfo.product_offer_id appears to have been renamed to ListingDimensionInfo.product_item_id server side

We are encountering an issue where we can request every single field for an ad_group_criterion except for "ad_group_criterion.listing_group.case_value.product_offer_id.value"
If we requested this field then the requests will fail with a 400 error "InvalidArgument: 400 Request contains an invalid argument."

Below is an example of the simplest query I can create that illustrates the issue (the login-customer-id is 7917471772):

SELECT ad_group_criterion.resource_name,ad_group_criterion.listing_group.case_value.product_offer_id.value FROM ad_group_criterion WHERE ad_group_criterion.resource_name IN ('customers/7917471772/adGroupCriteria/70794914121_10000010')

Upon contacting adwordsapi-support I was told to try using product_item_id. We have confirmed this no longer causes a serverside error but now there is a client side python error as follows.

AttributeError: 'ListingDimensionInfo' object has no attribute 'product_item_id'

It looks like it may simply be a matter of updating google/ads/google_ads/v0/proto/common/criteria_pb2.py to use product_item_id instead of product_offer_id.

_descriptor.FieldDescriptor( name='product_offer_id', full_name='google.ads.googleads.v0.common.ListingDimensionInfo.product_offer_id', index=10, number=11, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR),

TypeError: __new__() missing 1 required positional argument: 'wait_for_ready'

Hello,

I keep getting this grpc error and it's not entirely clear why:

TypeError: __new__() missing 1 required positional argument: 'wait_for_ready'

I'm running:

  • Python 3.6.5
  • google-ads==0.5.0

The code to reproduce is as follows:

google_ads_client = google.ads.google_ads.client.GoogleAdsClient.load_from_storage()
ga_service = google_ads_client.get_service('GoogleAdsService')
query = 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id'
results = ga_service.search(customer_id, query=query,page_size=page_size)
for row in results:
     print(row)

The full stack trace is as follows:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/page_iterator.py", line 204, in _items_iter
    for page in self._page_iter(increment=False):
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/page_iterator.py", line 235, in _page_iter
    page = self._next_page()
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/page_iterator.py", line 526, in _next_page
    response = self._method(self._request)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 143, in __call__
    return wrapped_func(*args, **kwargs)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/retry.py", line 270, in retry_wrapped_func
    on_error=on_error,
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/retry.py", line 179, in retry_target
    return target()
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/timeout.py", line 214, in func_with_timeout
    return func(*args, **kwargs)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 57, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/grpc/_interceptor.py", line 212, in __call__
    wait_for_ready=wait_for_ready)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/grpc/_interceptor.py", line 241, in _with_call
    continuation, client_call_details, request)
  File "/Users/ryansloan/cupboard/py/reporting/env/lib/python3.6/site-packages/google/ads/google_ads/client.py", line 366, in intercept_unary_unary
    client_call_details.credentials
TypeError: __new__() missing 1 required positional argument: 'wait_for_ready'

Any help debugging would be greatly appreciated.

Thanks!

from_client_secrets_file() takes exactly 3 arguments (2 given)

I keep getting this error and I don't know why.

First I copy pasted your code from OAuth Web Application Flow :

import google.oauth2.credentials
import google_auth_oauthlib.flow
# Initialize the flow using the client ID and secret downloaded earlier.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scope=['https://www.googleapis.com/auth/adwords'])
# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required.
flow.redirect_uri = 'https://www.dintdigital.com'

After getting the error I changed it to this:

import google.oauth2.credentials
from google_auth_oauthlib.flow import Flow
# Initialize the flow using the client ID and secret downloaded earlier.
flow = Flow.from_client_secrets_file(
    'client_secret.json',
    scope=['https://www.googleapis.com/auth/adwords'],
    redirect_uri = ['https://www.dintdigital.com'])

and I keep getting the same error. I don't understand why because I am literally giving from_client_secrets_file 3 arguments, not 2 as the error says.

Please help !

TypeError: 1975955774 has type int, but expected one of: bytes, unicode

I'm trying to reproduce a basic operation to get my clients campaign:

My code looks like this:

credentials = google.oauth2.credentials.Credentials(
												None,
												refresh_token =  refresh_token,
												client_id = GOOGLE_CLIENT_ID,
												client_secret = GOOGLE_CLIENT_SECRET,
												token_uri = 'https://accounts.google.com/o/oauth2/token'
									)
credentials.refresh(google.auth.transport.requests.Request())
client = google.ads.google_ads.client.GoogleAdsClient(credentials, ADWORDS_DEV_TOKEN)

page_size = 1000
ga_service = client.get_service('GoogleAdsService')
query = ('SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id')
results = ga_service.search(customer_id, query=query,page_size=page_size)

The last line fails throwing the following error:
TypeError: 1975955774 has type int, but expected one of: bytes, unicode
this happens at site-packages/google/ads/google_ads/v0/services/google_ads_service_client.py", line 232, in search

I've tried passing page_size as a string or not passing it at all but I get always the same error.
What am I missing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.