--- /dev/null
+"""Parse web services description language to get SOAP methods.
+
+Rudimentary support."""
+
+ident = '$Id: WSDL.py 1467 2008-05-16 23:32:51Z warnes $'
+from version import __version__
+
+import wstools
+import xml
+from Errors import Error
+from Client import SOAPProxy, SOAPAddress
+from Config import Config
+import urllib
+
+class Proxy:
+ """WSDL Proxy.
+
+ SOAPProxy wrapper that parses method names, namespaces, soap actions from
+ the web service description language (WSDL) file passed into the
+ constructor. The WSDL reference can be passed in as a stream, an url, a
+ file name, or a string.
+
+ Loads info into self.methods, a dictionary with methodname keys and values
+ of WSDLTools.SOAPCallinfo.
+
+ For example,
+
+ url = 'http://www.xmethods.org/sd/2001/TemperatureService.wsdl'
+ wsdl = WSDL.Proxy(url)
+ print len(wsdl.methods) # 1
+ print wsdl.methods.keys() # getTemp
+
+
+ See WSDLTools.SOAPCallinfo for more info on each method's attributes.
+ """
+
+ def __init__(self, wsdlsource, config=Config, **kw ):
+
+ reader = wstools.WSDLTools.WSDLReader()
+ self.wsdl = None
+
+ # From Mark Pilgrim's "Dive Into Python" toolkit.py--open anything.
+ if self.wsdl is None and hasattr(wsdlsource, "read"):
+ print 'stream:', wsdlsource
+ try:
+ self.wsdl = reader.loadFromStream(wsdlsource)
+ except xml.parsers.expat.ExpatError, e:
+ newstream = urllib.URLopener(key_file=config.SSL.key_file, cert_file=config.SSL.cert_file).open(wsdlsource)
+ buf = newstream.readlines()
+ raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
+ (wsdlsource, "\t".join(buf))
+
+
+ # NOT TESTED (as of April 17, 2003)
+ #if self.wsdl is None and wsdlsource == '-':
+ # import sys
+ # self.wsdl = reader.loadFromStream(sys.stdin)
+ # print 'stdin'
+
+ if self.wsdl is None:
+ try:
+ file(wsdlsource)
+ self.wsdl = reader.loadFromFile(wsdlsource)
+ #print 'file'
+ except (IOError, OSError): pass
+ except xml.parsers.expat.ExpatError, e:
+ newstream = urllib.urlopen(wsdlsource)
+ buf = newstream.readlines()
+ raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
+ (wsdlsource, "\t".join(buf))
+
+ if self.wsdl is None:
+ try:
+ stream = urllib.URLopener(key_file=config.SSL.key_file, cert_file=config.SSL.cert_file).open(wsdlsource)
+ self.wsdl = reader.loadFromStream(stream, wsdlsource)
+ except (IOError, OSError): pass
+ except xml.parsers.expat.ExpatError, e:
+ newstream = urllib.urlopen(wsdlsource)
+ buf = newstream.readlines()
+ raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
+ (wsdlsource, "\t".join(buf))
+
+ if self.wsdl is None:
+ import StringIO
+ self.wsdl = reader.loadFromString(str(wsdlsource))
+ #print 'string'
+
+ # Package wsdl info as a dictionary of remote methods, with method name
+ # as key (based on ServiceProxy.__init__ in ZSI library).
+ self.methods = {}
+ service = self.wsdl.services[0]
+ port = service.ports[0]
+ name = service.name
+ binding = port.getBinding()
+ portType = binding.getPortType()
+ for operation in portType.operations:
+ callinfo = wstools.WSDLTools.callInfoFromWSDL(port, operation.name)
+ self.methods[callinfo.methodName] = callinfo
+
+ self.soapproxy = SOAPProxy('http://localhost/dummy.webservice',
+ config=config, **kw)
+
+ def __str__(self):
+ s = ''
+ for method in self.methods.values():
+ s += str(method)
+ return s
+
+ def __getattr__(self, name):
+ """Set up environment then let parent class handle call.
+
+ Raises AttributeError is method name is not found."""
+
+ if not self.methods.has_key(name): raise AttributeError, name
+
+ callinfo = self.methods[name]
+ self.soapproxy.proxy = SOAPAddress(callinfo.location)
+ self.soapproxy.namespace = callinfo.namespace
+ self.soapproxy.soapaction = callinfo.soapAction
+ return self.soapproxy.__getattr__(name)
+
+ def show_methods(self):
+ for key in self.methods.keys():
+ method = self.methods[key]
+ print "Method Name:", key.ljust(15)
+ print
+ inps = method.inparams
+ for parm in range(len(inps)):
+ details = inps[parm]
+ print " In #%d: %s (%s)" % (parm, details.name, details.type)
+ print
+ outps = method.outparams
+ for parm in range(len(outps)):
+ details = outps[parm]
+ print " Out #%d: %s (%s)" % (parm, details.name, details.type)
+ print
+