increased maximum difficulty multiplier to 30
[p2pool.git] / SOAPpy / WSDL.py
1 """Parse web services description language to get SOAP methods.
2
3 Rudimentary support."""
4
5 ident = '$Id: WSDL.py 1467 2008-05-16 23:32:51Z warnes $'
6 from version import __version__
7
8 import wstools
9 import xml
10 from Errors import Error
11 from Client import SOAPProxy, SOAPAddress
12 from Config import Config
13 import urllib
14
15 class Proxy:
16     """WSDL Proxy.
17     
18     SOAPProxy wrapper that parses method names, namespaces, soap actions from
19     the web service description language (WSDL) file passed into the
20     constructor.  The WSDL reference can be passed in as a stream, an url, a
21     file name, or a string.
22
23     Loads info into self.methods, a dictionary with methodname keys and values
24     of WSDLTools.SOAPCallinfo.
25
26     For example,
27     
28         url = 'http://www.xmethods.org/sd/2001/TemperatureService.wsdl'
29         wsdl = WSDL.Proxy(url)
30         print len(wsdl.methods)          # 1
31         print wsdl.methods.keys()        # getTemp
32
33
34     See WSDLTools.SOAPCallinfo for more info on each method's attributes.
35     """
36
37     def __init__(self, wsdlsource, config=Config, **kw ):
38
39         reader = wstools.WSDLTools.WSDLReader()
40         self.wsdl = None
41
42         # From Mark Pilgrim's "Dive Into Python" toolkit.py--open anything.
43         if self.wsdl is None and hasattr(wsdlsource, "read"):
44             print 'stream:', wsdlsource
45             try:
46                 self.wsdl = reader.loadFromStream(wsdlsource)
47             except xml.parsers.expat.ExpatError, e:
48                 newstream = urllib.URLopener(key_file=config.SSL.key_file, cert_file=config.SSL.cert_file).open(wsdlsource)
49                 buf = newstream.readlines()
50                 raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
51                       (wsdlsource, "\t".join(buf))
52                 
53
54         # NOT TESTED (as of April 17, 2003)
55         #if self.wsdl is None and wsdlsource == '-':
56         #    import sys
57         #    self.wsdl = reader.loadFromStream(sys.stdin)
58         #    print 'stdin'
59
60         if self.wsdl is None:
61             try: 
62                 file(wsdlsource)
63                 self.wsdl = reader.loadFromFile(wsdlsource)
64                 #print 'file'
65             except (IOError, OSError): pass
66             except xml.parsers.expat.ExpatError, e:
67                 newstream = urllib.urlopen(wsdlsource)
68                 buf = newstream.readlines()
69                 raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
70                       (wsdlsource, "\t".join(buf))
71             
72         if self.wsdl is None:
73             try:
74                 stream = urllib.URLopener(key_file=config.SSL.key_file, cert_file=config.SSL.cert_file).open(wsdlsource)
75                 self.wsdl = reader.loadFromStream(stream, wsdlsource)
76             except (IOError, OSError): pass
77             except xml.parsers.expat.ExpatError, e:
78                 newstream = urllib.urlopen(wsdlsource)
79                 buf = newstream.readlines()
80                 raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
81                       (wsdlsource, "\t".join(buf))
82             
83         if self.wsdl is None:
84             import StringIO
85             self.wsdl = reader.loadFromString(str(wsdlsource))
86             #print 'string'
87
88         # Package wsdl info as a dictionary of remote methods, with method name
89         # as key (based on ServiceProxy.__init__ in ZSI library).
90         self.methods = {}
91         service = self.wsdl.services[0]
92         port = service.ports[0]
93         name = service.name
94         binding = port.getBinding()
95         portType = binding.getPortType()
96         for operation in portType.operations:
97             callinfo = wstools.WSDLTools.callInfoFromWSDL(port, operation.name)
98             self.methods[callinfo.methodName] = callinfo
99
100         self.soapproxy = SOAPProxy('http://localhost/dummy.webservice',
101                                    config=config, **kw)
102
103     def __str__(self): 
104         s = ''
105         for method in self.methods.values():
106             s += str(method)
107         return s
108
109     def __getattr__(self, name):
110         """Set up environment then let parent class handle call.
111
112         Raises AttributeError is method name is not found."""
113
114         if not self.methods.has_key(name): raise AttributeError, name
115
116         callinfo = self.methods[name]
117         self.soapproxy.proxy = SOAPAddress(callinfo.location)
118         self.soapproxy.namespace = callinfo.namespace
119         self.soapproxy.soapaction = callinfo.soapAction
120         return self.soapproxy.__getattr__(name)
121
122     def show_methods(self):
123         for key in self.methods.keys():
124             method = self.methods[key]
125             print "Method Name:", key.ljust(15)
126             print
127             inps = method.inparams
128             for parm in range(len(inps)):
129                 details = inps[parm]
130                 print "   In #%d: %s  (%s)" % (parm, details.name, details.type)
131             print
132             outps = method.outparams
133             for parm in range(len(outps)):
134                 details = outps[parm]
135                 print "   Out #%d: %s  (%s)" % (parm, details.name, details.type)
136             print
137