Comments (9)
@j-walker23 @wesleybowman Thanks for coordinating with each other, and sorry for my delayed response. Is it accurate to describe the issue you're having generally as wanting to lookup the string name of an Enum field using the integer value pulled from a request object?
It looks like that's the core problem - if not, or if I'm leaving off other problems, please add on here.
The issue of doing this type of look up is definitely a major pain point. It's possible to do this a bit more easily by using the protobuf helpers, like this:
from google.protouf.json_format import MessageToDict
# e is GoogleAdsException
failure = e.failure
dict = MessageToDict(failure)
for error in dict['errors']:
error_code = error['errorCode']
if error_code['authenticationError'] == 'CUSTOMER_NOT_FOUND':
raise AdwordsPermissionError('Customer Not Found', exception)
if error_code['authorizationError'] == 'USER_PERMISSION_DENIED':
raise AdwordsPermissionError('User Permission Denied', exception)
if error_code['requestError'] == 'INVALID_CUSTOMER_ID':
raise AdwordsInvalidClientCustomerId('Invalid Client Customer ID', exception)
Admittedly it's not a whole lot better, but at least you don't need to deal with the Enum protos directly.
One caveat about this solution is that it will generate errors if you are retrieving resource fields that contain a digit following an underscore, for example: video_quartile_25_rate
. See this separate issue for more context: #30
I'm hoping to get functionality added to this library that will more easily expose the Enum field names so external helpers like MessageToDict
aren't necessary. Hopefully that will come in the near future.
Let me know if you have any additional questions or thoughts here.
from google-ads-python.
@wesleybowman Thank you for the explanation! I'm working on determining if there's a way that we can improve the interface for this. To be honest it won't be an easy change, so it might take some time. I'm going to close this issue since it's not directly related, but I'll open a new one to track progress against making Enums easier to work with.
from google-ads-python.
I expected to be able to at least used the AuthenticationErrorEnum
, but I cannot figure out how that might work either.
An example:
In [432]: exception.failure.errors[0].error_code
Out[432]: authentication_error: CUSTOMER_NOT_FOUND
In [433]: authentication_error = client.get_type('AuthenticationErrorEnum', version='v1')
In [434]: authentication_error.CUSTOMER_NOT_FOUND
Out[434]: 8
In [435]: exception.failure.errors[0].error_code == authentication_error.CUSTOMER_NOT_FOUND
Out[435]: False
from google-ads-python.
Hi @wesleybowman It looks like you're on the right track for finding the values you're trying to compare. UNAUTHENTICATED
appears like it may be an auth error coming from the OAuth endpoint and not the Ads API. Are you able to authenticate properly and make successful search queries?
from google-ads-python.
appears like it may be an auth error coming from the OAuth endpoint and not the Ads API. Are you able to authenticate properly and make successful search queries?
@BenRKarl I actually made the query crash so that I could try and compare different errors.
This isn't about the error that I am getting, it is more about the following:
We have customers that will get these different errors, and I want to send them down different code paths depending on which error they get. I think using a StatusCode
doesn't give us enough fine grain control over these errors, so I was wondering the proper way to compare the errors.
from google-ads-python.
@wesleybowman This is horrendous, but here is how i'm doing it.
Working in a python lib that has no built in interfaces or structure and instead by hidden proto files, is extremely difficult. It's been a long time since i couldn't get a single thing off of intellisense.
Pretty miserable.
But here is my crappy way.
# I don't show my helper methods, but their names are clear
# e is GoogleAdsException
code = e.failure.errors[0].error_code
# Figure out enum type and value by just using str(code) after giving up on a good way
# code eg. == request_error: INVALID_CUSTOMER_ID\n
# request_error in this case is enum type, then after colon is enum value
type_str, val = strip_all_spaces(str(code).strip()).split(':')
name = pascal_case(type_str)
type_ = client.get_type(f'{name}Enum', version='v1')
enum = getattr(type_, name)
enum_val = enum.Value(val)
# Then later in code i can do
from google.ads.google_ads.v1.services.enums import RequestErrorEnum
if RequestErrorEnum.RequestError.INVALID_CUSTOMER_ID == enum_val:
# Now i can do something based on exact error enum
from google-ads-python.
It's been a long time since i couldn't get a single thing off of intellisense.
Pretty miserable.
Agreed. It's been a difficult ride. What we ended up going with for now is the following:
client = get_google_ads_client()
authentication_error_enum = client.get_type('AuthenticationErrorEnum', version='v1')
authorization_error_enum = client.get_type('AuthorizationErrorEnum', version='v1')
request_error_enum = client.get_type('RequestErrorEnum', version='v1')
for error in exception.failure.errors:
error_code = error.error_code
if error_code.authentication_error == authentication_error_enum.CUSTOMER_NOT_FOUND:
raise AdwordsPermissionError('Customer Not Found', exception)
elif error_code.authorization_error == authorization_error_enum.USER_PERMISSION_DENIED:
raise AdwordsPermissionError('User Permission Denied', exception)
elif error_code.request_error == request_error_enum.INVALID_CUSTOMER_ID:
raise AdwordsInvalidClientCustomerId('Invalid Client Customer ID', exception)
Overall, fairly simple, but I am hoping there will be a better way in the future
from google-ads-python.
from google-ads-python.
I'm hoping to get functionality added to this library that will more easily expose the Enum field names so external helpers like
MessageToDict
aren't necessary. Hopefully, that will come in the near future.
This would be wonderful!
and sorry for my delayed response.
No worries! We know you guys are busy. Keep up the good work 👍
Admittedly it's not a whole lot better, but at least you don't need to deal with the Enum protos directly.
I would like to extend this to also include an easier way to convert the StatusEnum
into it's name instead of an int
. For example, currently, to get the status as a string, we do the following:
campaign_status_enum = client.get_type('CampaignStatusEnum', version='v1').CampaignStatus.Name
for row in results:
status: str = campaign_status_enum.CampaignStatus.Name(row.campaign.status)
IMHO, it would be nice if row.campaign.status
had a value and name that could be accessed.
from google-ads-python.
Related Issues (20)
- AIP : Naming conventation issue HOT 1
- Missing `get_all_image_assets` script HOT 1
- DNS resolution failed for googleads.googleapis.com (constant error) HOT 2
- get_ad_groups.py HOT 2
- Upgrading problem HOT 5
- Add targetted audiences to ad_group HOT 4
- StatusCode.PERMISSION_DENIED HOT 1
- Keyword Historical Metric - RESOURCE_EXHAUSTED HOT 3
- Ad Accounts Suspensions Following Campaign Pausing HOT 1
- Response is None for offline_user_data_job_service_client.add_offline_user_data_job_operations HOT 1
- PMax Listing Group Status and Asset Group ID Discrepancy HOT 2
- API GOOGLES ADS REAL-TIME HOT 1
- Adding Consent Field To OfflineUserDataJobOperation Job HOT 4
- Google Ads API: CUSTOMER_MATCH_WITH_ATTRIBUTES Job Type does not populate audience HOT 1
- Parameter to MergeFrom() must be instance of same class HOT 1
- Google Ads library version 23.1.0 has a compatibility issue with AWS lambda. HOT 1
- Get All Campaigns Based on Given Example returns Nothing HOT 2
- IsFault: True, FaultMessage: Combined audience ID is invalid HOT 1
- Google Ads API Python SDK v16 support HOT 2
- keyword ideas different results from the web interface HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from google-ads-python.