--- Logging error ---
Traceback (most recent call last):
File "/usr/local/lib/python3.6/logging/__init__.py", line 994, in emit
msg = self.format(record)
File "/usr/local/lib/python3.6/logging/__init__.py", line 840, in format
return fmt.format(record)
File "get_ga_accounts.py", line 15, in format
str(current_arg) for current_arg in record.args
File "get_ga_accounts.py", line 15, in <genexpr>
str(current_arg) for current_arg in record.args
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/types/complex.py", line 73, in __str__
return "%s(%s)" % (self.__class__.__name__, self.signature())
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/types/complex.py", line 475, in signature
part = element.signature(schema, standalone=False)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/elements/indicators.py", line 255, in signature
value = element.signature(schema, standalone=False)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/elements/element.py", line 309, in signature
if self.type.is_global or (not standalone and self.is_global):
AttributeError: 'UnresolvedType' object has no attribute 'is_global'
Call stack:
File "get_ga_accounts.py", line 73, in <module>
main(adwords_client)
File "get_ga_accounts.py", line 33, in main
'ManagedCustomerService', version='v201809')
File "/usr/local/lib/python3.6/site-packages/googleads/adwords.py", line 315, in GetService
cache=self.cache)
File "/usr/local/lib/python3.6/site-packages/googleads/common.py", line 774, in __init__
endpoint, transport=transport, plugins=plugins)
File "/usr/local/lib/python3.6/site-packages/zeep/client.py", line 68, in __init__
self.wsdl = Document(wsdl, self.transport, settings=self.settings)
File "/usr/local/lib/python3.6/site-packages/zeep/wsdl/wsdl.py", line 82, in __init__
root_definitions = Definition(self, document, self.location)
File "/usr/local/lib/python3.6/site-packages/zeep/wsdl/wsdl.py", line 184, in __init__
self.parse_types(doc)
File "/usr/local/lib/python3.6/site-packages/zeep/wsdl/wsdl.py", line 316, in parse_types
self.types.add_documents(schema_nodes, self.location)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/schema.py", line 113, in add_documents
document = self.create_new_document(node, location)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/schema.py", line 213, in create_new_document
schema.load(self, node)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/schema.py", line 440, in load
visitor.visit_schema(node)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/visitor.py", line 160, in visit_schema
self.process(child, parent=node)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/visitor.py", line 88, in process
result = visit_func(self, node, parent)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/visitor.py", line 635, in visit_complex_type
self.register_type(qname, xsd_type)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/visitor.py", line 73, in register_type
self.document.register_type(qname, instance)
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/schema.py", line 499, in register_type
self._add_component(qname, value, self._types, "type")
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/schema.py", line 580, in _add_component
logger.debug("register_%s(%r, %r)", item_name, name, value)
Message: 'register_%s(%r, %r)'
Arguments: ('type', '{https://adwords.google.com/api/adwords/mcm/v201809}AccountLabel', <zeep.xsd.dynamic_types.AccountLabel object at 0x7fb17908fb70>)
Basically the problem seems to come from 2 things:
A logger forces the arguments passed when logging a message to be stringified
UnresolvedType class in zeep/xsd/types/unresolved.py isn't calling it's parent init, causing the is_global attribute to not be defined.
The combination of those two, means that this line:
logger.debug("register_%s(%r, %r)", item_name, name, value)
in zeep/xsd/schema.py, line 580
is calling a logger, which when forcing the arguments to be stringified, is calling the element signature, where it is expecting the type attribute to have the attribute is_global. While if we don't pass through str, but through repr (default behaviour with the default formatter from python), it is fine as it doesn't try to access the is_global attribute on the type.
I have tried by updating UnresolvedType init to call the parent and it resolved the problem.
Would it be possible to find a solution to resolve it, please?
By the way, I am not controlling the logging formatter, I am using a framework called airflow, which has its own logger formatter which is responsible for forcing the arguments to be transformed into string instances.
Script
A simple version, could be something like that:
#!/usr/bin/env python
#
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This example gets the account hierarchy under the current account.
The LoadFromStorage method is pulling credentials and properties from a
"googleads.yaml" file. By default, it looks for this file in your home
directory. For more information, see the "Caching authentication information"
section of our README.
"""
import logging
from googleads import adwords
PAGE_SIZE = 500
class FormatterForcingStrMagicMethodInsteadOfReprMagicMethod(logging.Formatter):
"""
Define a formatter that forces the arguments to be stringify instead of letting the repr
be used by the logger by default.
"""
def format(self, record):
if isinstance(record.args, (tuple, list)):
record.args = tuple(
str(current_arg) for current_arg in record.args
)
As you will see this depends on the python library from google: https://github.com/googleads/googleads-python-lib and will require to have an account to actually get the credentials to run the script.
Hello,
I have encountered the following issue:
Basically the problem seems to come from 2 things:
The combination of those two, means that this line: logger.debug("register_%s(%r, %r)", item_name, name, value) in zeep/xsd/schema.py, line 580 is calling a logger, which when forcing the arguments to be stringified, is calling the element signature, where it is expecting the type attribute to have the attribute is_global. While if we don't pass through str, but through repr (default behaviour with the default formatter from python), it is fine as it doesn't try to access the is_global attribute on the type.
I have tried by updating UnresolvedType init to call the parent and it resolved the problem.
Would it be possible to find a solution to resolve it, please?
By the way, I am not controlling the logging formatter, I am using a framework called airflow, which has its own logger formatter which is responsible for forcing the arguments to be transformed into string instances.
Versions python 3.6 zeep==3.4.0 googleads==22.0.*
The wsdl https://adwords.google.com/api/adwords/mcm/v201809/ManagedCustomerService?wsdl
Script A simple version, could be something like that:
"""This example gets the account hierarchy under the current account. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ import logging from googleads import adwords
PAGE_SIZE = 500
class FormatterForcingStrMagicMethodInsteadOfReprMagicMethod(logging.Formatter): """ Define a formatter that forces the arguments to be stringify instead of letting the repr be used by the logger by default. """ def format(self, record): if isinstance(record.args, (tuple, list)): record.args = tuple( str(current_arg) for current_arg in record.args )
logging.getLogger('zeep.xsd.schema').setLevel(logging.DEBUG) handler = logging.StreamHandler() formatter = FormatterForcingStrMagicMethodInsteadOfReprMagicMethod( '[%(asctime)s] %(levelname)s - %(name)s: %(message)s' ) handler.setFormatter(formatter) logging.getLogger('zeep.xsd.schema').addHandler(handler)
def main(client):
Initialize appropriate service.
if name == 'main':
Initialize client object.
adwords: #############################################################################
Required Fields
############################################################################# developer_token: INSERT_DEVELOPER_TOKEN_HERE #############################################################################
Optional Fields
#############################################################################
client_customer_id: INSERT_CLIENT_CUSTOMER_ID_HERE
user_agent: INSERT_USER_AGENT_HERE
partial_failure: True
validate_only: True
#############################################################################
OAuth2 Configuration
Below you may provide credentials for either the installed application or
service account flows. Remove or comment the lines for the flow you're
not using.
#############################################################################
The following values configure the client for the installed application
flow.
client_id: INSERT_OAUTH_2_CLIENT_ID_HERE client_secret: INSERT_CLIENT_SECRET_HERE refresh_token: INSERT_REFRESH_TOKEN_HERE """ adwords_client = adwords.AdWordsClient.LoadFromString(data) main(adwords_client)