bundled SOAPpy-0.12.5
[p2pool.git] / SOAPpy / WSDL.py
diff --git a/SOAPpy/WSDL.py b/SOAPpy/WSDL.py
new file mode 100644 (file)
index 0000000..84f7d3f
--- /dev/null
@@ -0,0 +1,137 @@
+"""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
+