In the following code below the eval
call is successful:
from zeep import Client
from zeep import xsd
from zeep.plugins import HistoryPlugin
class TrainAPI:
def __init__(self,LDB_TOKEN):
if LDB_TOKEN == '':
raise Exception("Please configure your OpenLDBWS token")
WSDL = 'http://lite.realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01'
history = HistoryPlugin()
self.client = Client(wsdl=WSDL, plugins=[history])
header = xsd.Element(
'{http://thalesgroup.com/RTTI/2013-11-28/Token/types}AccessToken',
xsd.ComplexType([
xsd.Element(
'{http://thalesgroup.com/RTTI/2013-11-28/Token/types}TokenValue',
xsd.String()),
])
)
self.header_value = header(TokenValue=LDB_TOKEN)
self.token = LDB_TOKEN
return
def __getattr__(self, action):
def method(*args,**kwargs):
print(action,args,kwargs)
print(self)
return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
return method
However, if the print(self)
line is removed, then the following error is thrown:
File "C:/Users/-/Documents/-/main.py", line 32, in method
return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
File "<string>", line 1, in <module>
NameError: name 'self' is not defined
Sorry if I am missing something obvious, but my question is: why is self
not defined unless I call something that refers to it (such as print(self)
) beforehand within the method
function?
Seems complex since the traceback finally refers to line 1 of <string>
...
Edit: trying this also returns an error:
def __getattr__(self, action):
def method(*args,**kwargs):
print(action,args,kwargs)
print(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
return method
Maybe I don't understand how scopes or format strings work.
The reason goes a bit deep into how python works, and I can tell you if you really want, but to solve your actual problem the answer is to avoid eval whenever possible as there is usually a better way. In this case:
method = getattr(self.client.service, action)
return method(*args,**kwargs, _soapheaders=[self.header_value])