googleads / googleads-python-lib

The Python client library for Google's Ads APIs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"argument should be integer or bytes-like object, not 'str'"

Edmondpoon opened this issue · comments

I've been trying to follow the examples and documentation for the python ad_manager library for the google ads API, but I haven't been able to complete a successful request. I currently have my developer token, client_id, client_secret, and refresh_token in my google ads YAML file, but I'm constantly getting the error "argument should be integer or bytes-like object, not 'str'" when calling the function WaitForReport following the example code below. I was wondering if anyone had any advice on how I could tackle this issue.

import tempfile

# Import appropriate modules from the client library.
from googleads import ad_manager
from googleads import errors


def main(client):
  # Initialize a DataDownloader.
  report_downloader = client.GetDataDownloader(version='v202111')

  # Create report job.
  report_job = {
      'reportQuery': {
          'dimensions': ['COUNTRY_NAME', 'LINE_ITEM_ID', 'LINE_ITEM_NAME'],
          'columns': ['UNIQUE_REACH_FREQUENCY', 'UNIQUE_REACH_IMPRESSIONS',
                      'UNIQUE_REACH'],
          'dateRangeType': 'REACH_LIFETIME'
      }
  }

  try:
    # Run the report and wait for it to finish.
    report_job_id = report_downloader.WaitForReport(report_job)
  except errors.AdManagerReportError as e:
    print('Failed to generate report. Error was: %s' % e)

  # Change to your preferred export format.
  export_format = 'CSV_DUMP'

  report_file = tempfile.NamedTemporaryFile(suffix='.csv.gz', delete=False)

  # Download report data.
  report_downloader.DownloadReportToFile(
      report_job_id, export_format, report_file)

  report_file.close()

  # Display results.
  print('Report job with id "%s" downloaded to:\n%s' % (
      report_job_id, report_file.name))


if __name__ == '__main__':
  # Initialize client object.
  ad_manager_client = ad_manager.AdManagerClient.LoadFromStorage()
  main(ad_manager_client)

Below is the stack trace:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/common.py", line 984, in MakeSoapRequest
    return soap_service_method(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/proxy.py", line 46, in __call__
    return self._proxy._binding.send(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 135, in send
    return self.process_reply(client, operation_obj, response)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 229, in process_reply
    return self.process_error(doc, operation)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 317, in process_error
    raise Fault(
zeep.exceptions.Fault: Unknown fault occured

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "google_ads.py", line 72, in <module>
    main(ad_manager_client)
  File "google_ads.py", line 33, in main1
    report_job_id = report_downloader.WaitForReport(report_job)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/ad_manager.py", line 784, in WaitForReport
    report_job_id = service.runReportJob(report_job)['id']
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/common.py", line 989, in MakeSoapRequest
    underlying_exception = e.detail.find(
TypeError: argument should be integer or bytes-like object, not 'str'

Hello, thanks for the report! While I was not able to reproduce your issue, a quick look shows that this is being raised by Zeep when processing an error in the API response. It seems like the "Unknown fault occurred" message is specified when Zeep can't parse the error response to find the Fault information.

Other error messages are correctly parsed, but it seems like the specific one you're encountering is not, which of course makes it more difficult to determine what caused the API call to fail. Given that, I don't think there's much we can do here on the client library side–I recommend reaching out to the Ad Manager support forum to:

  1. Determine why your API call really failed.
  2. Report that the fault message for that particular error case doesn't appear to be parseable.

Regards,
Mark

Hi. I've encountered the same problem with googleads==38.0.0.

It fails on this line:

underlying_exception = e.detail.find(
    '{%s}ApiExceptionFault' % self._GetBindingNamespace())

e.detail contains a byte string

b'<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<HTML>\n<HEAD>\n<TITLE>Unauthorized</TITLE>\n</HEAD>\n<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n<H1>Unauthorized</H1>\n<H2>Error 401</H2>\n</BODY>\n</HTML>'

Python documentation contains the following information:

The subsequence to search for may be any bytes-like object or an integer in the range 0 to 255.

https://docs.python.org/3/library/stdtypes.html?highlight=find#bytes.find

Duplicate of #451