From: <bov...@us...> - 2007-06-29 22:50:58
|
Revision: 1400 http://svn.sourceforge.net/pywebsvcs/?rev=1400&view=rev Author: boverhof Date: 2007-06-29 15:50:57 -0700 (Fri, 29 Jun 2007) Log Message: ----------- M test/test_t8.py M test/wsdl2py/servers/BasicServer.py M test/wsdl2py/servers/DateService.py M test/wsdl2py/servers/SquareService.py M test/wsdl2py/servers/EchoWSAddr200403Server.py M test/wsdl2py/servers/EchoServer.py M test/wsdl2py/servers/FinancialService.py M test/wsdl2py/servers/WhiteMesa.py M ZSI/twisted/wsgi.py M ZSI/dispatch.py M ZSI/__init__.py M ZSI/ServiceProxy.py M ZSI/ServiceContainer.py M ZSI/generate/wsdl2dispatch.py M ZSI/generate/commands.py M ZSI/TC.py M ZSI/client.py -- update server to return request,response making some changes so can use ~same generated code for ServiceContainer, WSGI, twisted, etc -- added UNICODE_ENCODING="utf-8" that use, changed TC.String to encode all parsed strings to expected encoding. Should be no issues, except maybe expected type (unicode vs. string), since utf-8 is superset of ascii the default codec Modified Paths: -------------- trunk/zsi/ZSI/ServiceContainer.py trunk/zsi/ZSI/ServiceProxy.py trunk/zsi/ZSI/TC.py trunk/zsi/ZSI/__init__.py trunk/zsi/ZSI/client.py trunk/zsi/ZSI/dispatch.py trunk/zsi/ZSI/generate/commands.py trunk/zsi/ZSI/generate/wsdl2dispatch.py trunk/zsi/ZSI/twisted/wsgi.py trunk/zsi/test/test_t8.py trunk/zsi/test/wsdl2py/servers/BasicServer.py trunk/zsi/test/wsdl2py/servers/DateService.py trunk/zsi/test/wsdl2py/servers/EchoServer.py trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py trunk/zsi/test/wsdl2py/servers/FinancialService.py trunk/zsi/test/wsdl2py/servers/SquareService.py trunk/zsi/test/wsdl2py/servers/WhiteMesa.py Modified: trunk/zsi/ZSI/ServiceContainer.py =================================================================== --- trunk/zsi/ZSI/ServiceContainer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/ServiceContainer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -103,9 +103,9 @@ try: if isWSResource is True: - result = method(ps, address) + request,result = method(ps, address) else: - result = method(ps) + request,result = method(ps) except Exception, e: return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw) Modified: trunk/zsi/ZSI/ServiceProxy.py =================================================================== --- trunk/zsi/ZSI/ServiceProxy.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/ServiceProxy.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -30,32 +30,31 @@ service that is described with WSDL. The proxy exposes methods that reflect the methods of the remote web service.""" - def __init__(self, wsdl, url=None, service=None, port=None, tracefile=None, - nsdict=None, transport=None, transdict=None, + def __init__(self, wsdl, url=None, service=None, port=None, cachedir=os.path.join(os.path.expanduser('~'), '.zsi_service_proxy_dir'), - asdict=True): + asdict=True, lazy=False, pyclass=False, force=False, **kw): """ Parameters: wsdl -- URL of WSDL. url -- override WSDL SOAP address location service -- service name or index port -- port name or index - tracefile -- - nsdict -- key prefix to namespace mappings for serialization - in SOAP Envelope. - transport -- override default transports. - transdict -- arguments to pass into HTTPConnection constructor. cachedir -- where to store generated files asdict -- use dicts, else use generated pyclass + lazy -- use lazy typecode evaluation + pyclass -- use pyclass_type metaclass adds properties, "new_", "set_, + "get_" methods for schema element and attribute declarations. + force -- regenerate all WSDL code, write over cache. + + NOTE: all other **kw will be passed to the underlying + ZSI.client._Binding constructor. + """ self._asdict = asdict # client._Binding - self._tracefile = tracefile - self._nsdict = nsdict or {} - self._transdict = transdict - self._transport = transport self._url = url + self._kw = kw # WSDL self._wsdl = wstools.WSDLTools.WSDLReader().loadFromURL(wsdl) @@ -65,6 +64,9 @@ self._name = self._service.name self._methods = {} self._cachedir = cachedir + self._lazy = lazy + self._pyclass = pyclass + self._force = force # Set up rpc methods for service/port port = self._port @@ -102,13 +104,19 @@ del cp; cp = None option = location.replace(':', '-') # colons seem to screw up option - if (cp is not None and cp.has_section(section) and + if (not self._force and cp is not None and cp.has_section(section) and cp.has_option(section, option)): types = cp.get(section, option) else: # dont do anything to anames - containers.ContainerBase.func_aname = lambda instnc,n: str(n) - files = commands.wsdl2py(['-o', cachedir, location]) + if not self._pyclass: + containers.ContainerBase.func_aname = lambda instnc,n: str(n) + + args = ['-o', cachedir, location] + if self._lazy: args.insert(0, '-l') + if self._pyclass: args.insert(0, '-b') + files = commands.wsdl2py(args) + if cp is None: cp = ConfigParser() if not cp.has_section(section): cp.add_section(section) types = filter(lambda f: f.endswith('_types.py'), files)[0] @@ -144,10 +152,10 @@ types = cp.get(section, option) else: # dont do anything to anames - containers.ContainerBase.func_aname = lambda instnc,n: str(n) + if not self._pyclass: + containers.ContainerBase.func_aname = lambda instnc,n: str(n) + from ZSI.wstools import XMLSchema - - reader = XMLSchema.SchemaReader(base_url=location) if xml is not None and isinstance(xml, basestring): schema = reader.loadFromString(xml) @@ -164,6 +172,9 @@ schema = True simple_naming = False address = False + lazy = self._lazy + complexType = self._pyclass + schema.location = location files = commands._wsdl2py(options, schema) if cp is None: cp = ConfigParser() @@ -205,10 +216,9 @@ if len(method.callinfo.inparams) == len(kwargs): callinfo = method.callinfo - binding = _Binding(tracefile=self._tracefile, - url=self._url or callinfo.location, - nsdict=self._nsdict, - soapaction=callinfo.soapAction) + binding = _Binding(url=self._url or callinfo.location, + soapaction=callinfo.soapAction, + **self._kw) kw = dict(unique=True) if callinfo.use == 'encoded': Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/TC.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -8,7 +8,7 @@ _find_arraytype, _find_default_namespace, _find_href, _find_encstyle, \ _resolve_prefix, _find_xsi_attr, _find_type, \ _find_xmlns_prefix, _get_element_nsuri_name, _get_idstr, \ - _Node, EvaluateException, \ + _Node, EvaluateException, UNICODE_ENCODING, \ _valid_encoding, ParseException from ZSI.wstools.Namespaces import SCHEMA, SOAP @@ -708,16 +708,19 @@ def text_to_data(self, text, elt, ps): '''convert text into typecode specific data. + Encode all strings as UTF-8, which will be type 'str' + not 'unicode' ''' if self.strip: text = text.strip() if self.pyclass is not None: - return self.pyclass(text) - return text + return self.pyclass(text.encode(UNICODE_ENCODING)) + return text.encode(UNICODE_ENCODING) def get_formatted_content(self, pyobj): if type(pyobj) not in _stringtypes: pyobj = str(pyobj) - if type(pyobj) == types.UnicodeType: pyobj = pyobj.encode('utf-8') + if type(pyobj) == unicode: + return pyobj.encode(UNICODE_ENCODING) return pyobj Modified: trunk/zsi/ZSI/__init__.py =================================================================== --- trunk/zsi/ZSI/__init__.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/__init__.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -150,8 +150,8 @@ ## ## Public constants. from ZSI.wstools.Namespaces import ZSI_SCHEMA_URI +UNICODE_ENCODING = 'utf-8' - ## ## Not public constants. _inttypes = [ _types.IntType, _types.LongType ] Modified: trunk/zsi/ZSI/client.py =================================================================== --- trunk/zsi/ZSI/client.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/client.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -5,7 +5,8 @@ from ZSI import _copyright, _seqtypes, ParsedSoap, SoapWriter, TC, ZSI_SCHEMA_URI,\ EvaluateException, FaultFromFaultMessage, _child_elements, _attrs, _find_arraytype,\ - _find_type, _get_idstr, _get_postvalue_from_absoluteURI, FaultException, WSActionException + _find_type, _get_idstr, _get_postvalue_from_absoluteURI, FaultException, WSActionException,\ + UNICODE_ENCODING from ZSI.auth import AUTH from ZSI.TC import AnyElement, AnyType, String, TypeCode, _get_global_element_declaration,\ _get_type_definition @@ -300,7 +301,7 @@ request_uri = _get_postvalue_from_absoluteURI(url) self.h.putrequest("POST", request_uri) self.h.putheader("Content-Length", "%d" % len(soapdata)) - self.h.putheader("Content-Type", 'text/xml; charset=utf-8') + self.h.putheader("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) self.__addcookies() for header,value in headers.items(): Modified: trunk/zsi/ZSI/dispatch.py =================================================================== --- trunk/zsi/ZSI/dispatch.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/dispatch.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -169,13 +169,13 @@ def _JonPySendXML(text, code=200, **kw): req = kw['request'] - req.set_header("Content-Type", 'text/xml; charset="utf-8"') + req.set_header("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) req.set_header("Content-Length", str(len(text))) req.write(text) def _CGISendXML(text, code=200, **kw): print 'Status: %d' % code - print 'Content-Type: text/xml; charset="utf-8"' + print 'Content-Type: text/xml; charset="%s"' %UNICODE_ENCODING print 'Content-Length: %d' % len(text) print '' print text @@ -195,7 +195,7 @@ self.send_response(code) if text: - self.send_header('Content-type', 'text/xml; charset="utf-8"') + self.send_header('Content-type', 'text/xml; charset="%s"' %UNICODE_ENCODING) self.send_header('Content-Length', str(len(text))) self.end_headers() Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/generate/commands.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -16,9 +16,7 @@ from ZSI.generate import containers, utility from ZSI.generate.utility import NCName_to_ClassName as NC_to_CN, TextProtect from ZSI.generate.wsdl2dispatch import ServiceModuleWriter as ServiceDescription -from ZSI.generate.wsdl2dispatch import DelAuthServiceModuleWriter as DelAuthServiceDescription from ZSI.generate.wsdl2dispatch import WSAServiceModuleWriter as ServiceDescriptionWSA -from ZSI.generate.wsdl2dispatch import DelAuthWSAServiceModuleWriter as DelAuthServiceDescriptionWSA warnings.filterwarnings('ignore', '', exceptions.UserWarning) Modified: trunk/zsi/ZSI/generate/wsdl2dispatch.py =================================================================== --- trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -4,7 +4,8 @@ from ZSI.wstools import WSDLTools from ZSI.generate.wsdl2python import WriteServiceModule, MessageTypecodeContainer from ZSI.ServiceContainer import ServiceSOAPBinding, SimpleWSResource, WSAResource -from ZSI.generate.utility import TextProtect, GetModuleBaseNameFromWSDL, NCName_to_ClassName, GetPartsSubNames, TextProtectAttributeName +from ZSI.generate.utility import TextProtect, GetModuleBaseNameFromWSDL, \ + NCName_to_ClassName, GetPartsSubNames, TextProtectAttributeName from ZSI.generate import WsdlGeneratorError, Wsdl2PythonError from ZSI.generate.wsdl2python import SchemaDescription @@ -14,6 +15,7 @@ if sys.version_info[0:2] == (2, 4, 0, 'final', 0)[0:2]: rsplit = lambda x,sep,: x.rsplit(sep, 1) + class SOAPService: def __init__(self, service): self.classdef = StringIO() @@ -27,6 +29,7 @@ self.methods.append(StringIO()) return self.methods[-1] + class ServiceModuleWriter: '''Creates a skeleton for a SOAP service instance. ''' @@ -34,12 +37,14 @@ server_module_suffix = '_server' func_aname = TextProtectAttributeName func_aname = staticmethod(func_aname) - separate_messages = False # Whether to write message definitions into a separate file. + separate_messages = False - def __init__(self, base=ServiceSOAPBinding, prefix='soap', service_class=SOAPService, do_extended=False): + def __init__(self, base=ServiceSOAPBinding, prefix='soap', + service_class=SOAPService): ''' parameters: - base -- either a class definition, or a str representing a qualified class name. + base -- either a class definition, or a str representing a qualified + class name. prefix -- method prefix. ''' self.wsdl = None @@ -53,16 +58,12 @@ self.client_module_path = None self.client_module_name = None self.messages_module_name = None - self.do_extended = do_extended - def reset(self): - self.header = StringIO() - self.imports = StringIO() - self._services = {} - def _getBaseClassName(self): '''return base class name, do not override. ''' + if self.base_class is None: + return if type(self.base_class) is types.ClassType: return self.base_class.__name__ return rsplit(self.base_class, '.')[-1] @@ -70,12 +71,19 @@ def _getBaseClassModule(self): '''return base class module, do not override. ''' + if self.base_class is None: + return if type(self.base_class) is types.ClassType: return self.base_class.__module__ if self.base_class.find('.') >= 0: return rsplit(self.base_class, '.')[0] - return None + return + def reset(self): + self.header = StringIO() + self.imports = StringIO() + self._services = {} + def getIndent(self, level=1): '''return indent. ''' @@ -102,7 +110,7 @@ if self.client_module_name is not None: return self.client_module_name - wsm = WriteServiceModule(self.wsdl, do_extended=self.do_extended) + wsm = WriteServiceModule(self.wsdl) return wsm.getClientModuleName() def getMessagesModuleName(self): @@ -112,7 +120,7 @@ if self.messages_module_name is not None: return self.messages_module_name - wsm = WriteServiceModule(self.wsdl, do_extended=self.do_extended) + wsm = WriteServiceModule(self.wsdl) return wsm.getMessagesModuleName() def getServiceModuleName(self): @@ -142,11 +150,15 @@ 'expecting WSDLTools.Service instance.' s = self._services[service.name].classdef - print >>s, 'class %s(%s):' %(self.getClassName(service.name), self._getBaseClassName()) + base = self._getBaseClassName() + if base is None: + print >>s, 'class %s:' %(self.getClassName(service.name)) + else: + print >>s, 'class %s(%s):' %(self.getClassName(service.name), base) + print >>s, '%ssoapAction = {}' % self.getIndent(level=1) print >>s, '%sroot = {}' % self.getIndent(level=1) - print >>s, "%s_wsdl = \"\"\"%s\"\"\"" % (self.getIndent(level=1), self.raw_wsdl) - + def setUpImports(self): '''set import statements ''' @@ -165,7 +177,9 @@ mod = self._getBaseClassModule() name = self._getBaseClassName() - if mod is None: + if mod is None and name is None: + pass + elif mod is None: print >>i, 'import %s' %name else: print >>i, 'from %s import %s' %(mod, name) @@ -173,7 +187,9 @@ def setUpInitDef(self, service): '''set __init__ function ''' - assert isinstance(service, WSDLTools.Service), 'expecting WSDLTools.Service instance.' + assert isinstance(service, WSDLTools.Service), \ + 'expecting WSDLTools.Service instance.' + sd = self._services[service.name] d = sd.initdef @@ -183,9 +199,10 @@ else: print >>d, '%sdef __init__(self, post, **kw):' %self.getIndent(level=1) - print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2),self._getBaseClassName()) + base = self._getBaseClassName() + if base is not None: + print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2), base) - def mangle(self, name): return TextProtect(name) @@ -230,81 +247,17 @@ m = sd.newMethod() print >>m, '%sdef %s(self, ps):' %(self.getIndent(level=1), method_name) if msgin is not None: - print >>m, '%sself.request = ps.Parse(%s.typecode)' %(self.getIndent(level=2), msgin_name) + print >>m, '%srequest = ps.Parse(%s.typecode)' %(self.getIndent(level=2), msgin_name) else: print >>m, '%s# NO input' %self.getIndent(level=2) msgout = op.getOutputMessage() - - if self.do_extended: - input_args = msgin.parts.values() - iargs = ["%s" % x.name for x in input_args] - if msgout is not None: - output_args = msgout.parts.values() - else: - output_args = [] - oargs = ["%s" % x.name for x in output_args] - if output_args: - if len(output_args) > 1: - print "Message has more than one return value (Bad Design)." - output_args = "(%s)" % output_args - else: - output_args = "" - # Get arg list - iSubNames = GetPartsSubNames(msgin.parts.values(), self.wsdl) - for i in range( len(iargs) ): # should only be one part to messages here anyway - argSubNames = iSubNames[i] - if len(argSubNames) > 0: - subNamesStr = "self.request." + ", self.request.".join(map(self.getAttributeName, argSubNames)) - if len(argSubNames) > 1: - subNamesStr = "(" + subNamesStr + ")" - print >>m, "%s%s = %s" % (self.getIndent(level=2), iargs[i], subNamesStr) - - print >>m, "\n%s# If we have an implementation object use it" % (self.getIndent(level=2)) - print >>m, "%sif hasattr(self,'impl'):" % (self.getIndent(level=2)) - - iargsStrList = [] - for arg in iargs: - argSubNames = iSubNames[i] - if len(argSubNames) > 0: - if len(argSubNames) > 1: - for i in range(len(argSubNames)): - iargsStrList.append( arg + "[%i]" % i ) - else: - iargsStrList.append( arg ) - iargsStr = ",".join(iargsStrList) - oargsStr = ", ".join(oargs) - if len(oargsStr) > 0: - oargsStr += " = " - print >>m, "%s%sself.impl.%s(%s)" % (self.getIndent(level=3), oargsStr, op.name, iargsStr) - if msgout is not None: msgout_name = TextProtect(msgout.name) - if self.do_extended: - print >>m, '\n%sresult = %s()' %(self.getIndent(level=2), msgout_name) - oSubNames = GetPartsSubNames(msgout.parts.values(), self.wsdl) - if (len(oSubNames) > 0) and (len(oSubNames[0]) > 0): - print >>m, "%s# If we have an implementation object, copy the result " % (self.getIndent(level=2)) - print >>m, "%sif hasattr(self,'impl'):" % (self.getIndent(level=2)) - # copy result's members - for i in range( len(oargs) ): # should only be one part messages here anyway - oargSubNames = oSubNames[i] - if len(oargSubNames) > 1: - print >>m, '%s# Should have a tuple of %i args' %(self.getIndent(level=3), len(oargSubNames)) - for j in range(len(oargSubNames)): - oargSubName = oargSubNames[j] - print >>m, '%sresult.%s = %s[%i]' %(self.getIndent(level=3), self.getAttributeName(oargSubName), oargs[i], j) - elif len(oargSubNames) == 1: - oargSubName = oargSubNames[0] - print >>m, '%sresult.%s = %s' %(self.getIndent(level=3), self.getAttributeName(oargSubName), oargs[i]) - else: - raise Exception("The subnames within message " + msgout_name + "'s part were not found. Message is the output of operation " + op.name) - print >>m, '%sreturn result' %(self.getIndent(level=2)) - else: - print >>m, '%sreturn %s()' %(self.getIndent(level=2), msgout_name) + print >>m, '%sreturn request,%s()' %(self.getIndent(level=2), msgout_name) else: print >>m, '%s# NO output' % self.getIndent(level=2) - print >>m, '%sreturn None' % self.getIndent(level=2) + print >>m, '%sreturn request,None' % self.getIndent(level=2) print >>m, '' print >>m, '%ssoapAction[\'%s\'] = \'%s\'' %(self.getIndent(level=1), action_in, method_name) @@ -343,7 +296,6 @@ self.reset() self.wsdl = wsdl - self.raw_wsdl = wsdl.document.toxml().replace("\"", "\\\"") self.setUpHeader() self.setUpImports() for service in wsdl.services: @@ -364,7 +316,8 @@ class WSAServiceModuleWriter(ServiceModuleWriter): '''Creates a skeleton for a WS-Address service instance. ''' - def __init__(self, base=WSAResource, prefix='wsa', service_class=SOAPService, strict=True): + def __init__(self, base=WSAResource, prefix='wsa', service_class=SOAPService, + strict=True): ''' Parameters: strict -- check that soapAction and input ws-action do not collide. @@ -379,12 +332,12 @@ ''' body = [] if msgInName is not None: - body.append('self.request = ps.Parse(%s.typecode)' %msgInName) + body.append('request = ps.Parse(%s.typecode)' %msgInName) if msgOutName is not None: - body.append('return %s()' %msgOutName) + body.append('return request,%s()' %msgOutName) else: - body.append('return None') + body.append('return request,None') return tuple(body) createMethodBody = staticmethod(createMethodBody) @@ -465,68 +418,3 @@ print >>m, '%sroot[(%s.typecode.nspname,%s.typecode.pname)] = \'%s\'' \ %(self.getIndent(level=1), msgin_name, msgin_name, method_name) - -class DelAuthServiceModuleWriter(ServiceModuleWriter): - ''' Includes the generation of lines to call an authorization method on the server side - if an authorization function has been defined. - ''' - def __init__(self, base=ServiceSOAPBinding, prefix='soap', service_class=SOAPService, do_extended=False): - ServiceModuleWriter.__init__(self, base=base, prefix=prefix, service_class=service_class, do_extended=do_extended) - - def fromWSDL(self, wsdl): - ServiceModuleWriter.fromWSDL(self, wsdl) - for service in wsdl.services: - self.setUpAuthDef(service) - - def setUpInitDef(self, service): - ServiceModuleWriter.setUpInitDef(self, service) - sd = self._services[service.name] - d = sd.initdef - print >>d, '%sif kw.has_key(\'impl\'):' % self.getIndent(level=2) - print >>d, '%sself.impl = kw[\'impl\']' % self.getIndent(level=3) - - print >>d, '%sself.auth_method_name = None' % self.getIndent(level=2) - print >>d, '%sif kw.has_key(\'auth_method_name\'):' % self.getIndent(level=2) - print >>d, '%sself.auth_method_name = kw[\'auth_method_name\']' % self.getIndent(level=3) - - def setUpAuthDef(self, service): - '''set __auth__ function - ''' - sd = self._services[service.name] - e = sd.initdef - print >>e, "%sdef authorize(self, auth_info, post, action):" % self.getIndent(level=1) - print >>e, "%sif self.auth_method_name and hasattr(self.impl, self.auth_method_name):" % self.getIndent(level=2) - print >>e, "%sreturn getattr(self.impl, self.auth_method_name)(auth_info, post, action)" % self.getIndent(level=3) - print >>e, "%selse:" % self.getIndent(level=2) - print >>e, "%sreturn 1" % self.getIndent(level=3) - -class DelAuthWSAServiceModuleWriter(WSAServiceModuleWriter): - def __init__(self, base=SimpleWSResource, prefix='wsa', service_class=SOAPService, strict=True): - WSAServiceModuleWriter.__init__(self, base=base, prefix=prefix, service_class=service_class, strict=strict) - - def fromWSDL(self, wsdl): - WSAServiceModuleWriter.fromWSDL(self, wsdl) - for service in wsdl.services: - self.setUpAuthDef(service) - - def setUpInitDef(self, service): - WSAServiceModuleWriter.setUpInitDef(self, service) - sd = self._services[service.name] - d = sd.initdef - print >>d, '%sif kw.has_key(\'impl\'):' % self.getIndent(level=2) - print >>d, '%sself.impl = kw[\'impl\']' % self.getIndent(level=3) - - print >>d, '%sif kw.has_key(\'auth_method_name\'):' % self.getIndent(level=2) - print >>d, '%sself.auth_method_name = kw[\'auth_method_name\']' % self.getIndent(level=3) - - def setUpAuthDef(self, service): - '''set __auth__ function - ''' - sd = self._services[service.name] - e = sd.initdef - print >>e, "%sdef authorize(self, auth_info, post, action):" % self.getIndent(level=1) - print >>e, "%sif self.auth_method_name and hasattr(self.impl, self.auth_method_name):" % self.getIndent(level=2) - print >>e, "%sreturn getattr(self.impl, self.auth_method_name)(auth_info, post, action)" % self.getIndent(level=3) - print >>e, "%selse:" % self.getIndent(level=2) - print >>e, "%sreturn 1" % self.getIndent(level=3) - Modified: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -3,38 +3,44 @@ # See Copyright for copyright notice! # $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ ########################################################################### -import os, sys, warnings +import os, sys, types from StringIO import StringIO # twisted & related imports from zope.interface import classProvides, implements, Interface -from twisted.python import log, failure -#from twisted.web.error import NoResource -#from twisted.web.server import NOT_DONE_YET -#import twisted.web.http -#import twisted.web.resource # ZSI imports -from ZSI import _get_element_nsuri_name, EvaluateException, ParseException -from ZSI import fault, ParsedSoap, SoapWriter +from ZSI import _get_element_nsuri_name, EvaluateException, ParseException,\ + fault, ParsedSoap, SoapWriter +from ZSI.twisted.reverse import DataHandler, ReverseHandlerChain,\ + HandlerChainInterface -# WS-Address related imports -from ZSI.address import Address +def soapmethod(requesttypecode, responsetypecode, soapaction='', + operation=None, **kw): + """@soapmethod + decorator function for soap methods + """ + def _closure(func_cb): + func_cb.root = (requesttypecode.nspname,requesttypecode.pname) + func_cb.action = soapaction + func_cb.requesttypecode = requesttypecode + func_cb.responsetypecode = responsetypecode + func_cb.soapmethod = True + func_cb.operation = None + return func_cb + return _closure -class WSAddressException(Exception): + +class SOAPCallbackHandler: + """ ps --> pyobj, pyobj --> sw + class variables: + writerClass -- ElementProxy implementation to use for SoapWriter instances. """ - """ + classProvides(HandlerChainInterface) + writerClass = None -from ZSI.twisted.interfaces import HandlerChainInterface, CallbackChainInterface,\ - DataHandler, CheckInputArgs, DefaultHandlerChain - - - -class DefaultCallbackHandler: - classProvides(CallbackChainInterface) - @classmethod def processRequest(cls, ps, **kw): """invokes callback that should return a (request,response) tuple. @@ -42,35 +48,47 @@ ps -- ParsedSoap instance representing HTTP Body. request -- twisted.web.server.Request """ - #env = kw['env'] - #start_response = kw['start_response'] resource = kw['resource'] - #request = kw['request'] - method = getattr(resource, 'soap_%s' % - _get_element_nsuri_name(ps.body_root)[-1]) - + request = kw['request'] + + root = _get_element_nsuri_name(ps.body_root) + for key,method in resource.__dict__: + if (callable(method) and + getattr(method, 'soapmethod', False) and + method.root == root): + break + else: + raise RuntimeError, 'Missing soap callback method for root "%s"' %root + try: - req_pyobj,rsp_pyobj = method(ps) - except TypeError, ex: - log.err( - 'ERROR: service %s is broken, method MUST return request, response'\ - % cls.__name__ - ) + req = ps.Parse(method.requesttypecode) + except Exception, ex: raise + try: + rsp = method.responsetypecode.pyclass() except Exception, ex: - log.err('failure when calling bound method') raise - return rsp_pyobj + try: + req,rsp = method(req, rsp) + except Exception, ex: + raise + + return rsp + + @classmethod + def processResponse(cls, output, **kw): + sw = SoapWriter(outputclass=cls.writerClass) + sw.serialize(output) + return sw -class DefaultHandlerChainFactory: - protocol = DefaultHandlerChain - +class SOAPHandlerChainFactory: + protocol = ReverseHandlerChain + @classmethod def newInstance(cls): - return cls.protocol(DefaultCallbackHandler, DataHandler) - + return cls.protocol(DataHandler, SOAPCallbackHandler) class WSGIApplication(dict): @@ -104,8 +122,6 @@ """ """ factory = DefaultHandlerChainFactory - soapAction = {} - root = {} def __init__(self, **kw): dict.__init__(self, **kw) @@ -130,7 +146,8 @@ def _handle_GET(self, env, start_response): if env['QUERY_STRING'].lower() == 'wsdl': start_response("200 OK", [('Content-Type','text/plain')]) - return ['NO WSDL YET'] + r = self.delegate or self + return _resourceToWSDL(r) start_response("404 ERROR", [('Content-Type','text/plain')]) return ['NO RESOURCE FOR GET'] @@ -168,7 +185,6 @@ def test(app, port=8080, host="localhost"): """ """ - import sys from twisted.internet import reactor from twisted.python import log from twisted.web2.channel import HTTPFactory @@ -183,4 +199,77 @@ reactor.run() +def _issoapmethod(f): + return type(f) is types.MethodType and getattr(f, 'soapmethod', False) +def _resourceToWSDL(resource): + from xml.etree import ElementTree + from xml.etree.ElementTree import Element, QName + from ZSI.wstools.Namespaces import WSDL + + r = resource + methods = filter(_issoapmethod, map(lambda i: getattr(r, i), dir(r))) + tns = '' + + #tree = ElementTree() + defs = Element("{%s}definitions" %WSDL.BASE) + defs.attrib['name'] = 'SampleDefs' + defs.attrib['targetNamespace'] = tns + #tree.append(defs) + + porttype = Element("{%s}portType" %WSDL) + porttype.attrib['name'] = QName("{%s}SamplePortType" %tns) + + binding = Element("{%s}binding" %WSDL) + defs.append(binding) + binding.attrib['name'] = QName("{%s}SampleBinding" %tns) + binding.attrib['type'] = porttype.get('name') + + for m in methods: + m.action + + service = Element("{%s}service" %WSDL.BASE) + defs.append(service) + service.attrib['name'] = 'SampleService' + + port = Element("{%s}port" %WSDL.BASE) + service.append(port) + port.attrib['name'] = "SamplePort" + port.attrib['binding'] = binding.get('name') + + soapaddress = Element("{%s}address" %WSDL.BIND_SOAP) + soapaddress.attrib['location'] = 'http://localhost/bla' + port.append(soapaddress) + + return [ElementTree.tostring(defs)] + + + +""" +<?xml version="1.0" encoding="UTF-8"?> +<wsdl:definitions name="Counter" targetNamespace="http://counter.com/bindings" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:porttype="http://counter.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> + <wsdl:import namespace="http://counter.com" location="counter_flattened.wsdl"/> + <wsdl:binding name="CounterPortTypeSOAPBinding" type="porttype:CounterPortType"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="createCounter"> + <soap:operation soapAction="http://counter.com/CounterPortType/createCounterRequest"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + + +<wsdl:definitions name="Counter" targetNamespace="http://counter.com/service" +xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:binding="http://counter.com/bindings"> + <wsdl:import namespace="http://counter.com/bindings" location="counter_bindings.wsdl"/> + <wsdl:service name="CounterService"> + <wsdl:port name="CounterPortTypePort" binding="binding:CounterPortTypeSOAPBinding"> + <soap:address location="http://localhost:8080/wsrf/services/"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> +""" + Modified: trunk/zsi/test/test_t8.py =================================================================== --- trunk/zsi/test/test_t8.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/test_t8.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -73,7 +73,7 @@ self.assertEqual(type(myInt), type(parsed[0])) self.assertEqual(type(myLong), type(parsed[1])) - self.assertEqual(type(myStr), type(parsed[2])) + self.assertEqual(str, type(parsed[2])) self.assertEqual(tuple, type(parsed[3])) self.assertEqual(type(myFloat), type(parsed[4])) Modified: trunk/zsi/test/wsdl2py/servers/BasicServer.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/BasicServer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/BasicServer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -14,17 +14,17 @@ class Service(BasicServer): def soap_Basic(self, ps): - response = BasicServer.soap_Basic(self, ps) - response._BasicResult = self.request._BasicIn - return response + request,response = BasicServer.soap_Basic(self, ps) + response._BasicResult = request._BasicIn + return request,response def soap_BasicOneWay(self, ps): - response = BasicServer.soap_BasicOneWay(self, ps) - if self.request._BasicIn == 'fault': + request,response = BasicServer.soap_BasicOneWay(self, ps) + if request._BasicIn == 'fault': # return a soap:fault raise RuntimeError, 'you wanted a fault?' - return response + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/DateService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/DateService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/DateService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -9,18 +9,18 @@ class Service(_DateService): def soap_getCurrentDate(self, ps): - response = _DateService.soap_getCurrentDate(self, ps) + request,response = _DateService.soap_getCurrentDate(self, ps) response.Today = today = response.new_today() - self.request._input + request._input _SetCurrentDate(today) - return response + return request,response def soap_getDate(self, ps): - response = _DateService.soap_getDate(self, ps) + request,response = _DateService.soap_getDate(self, ps) response.Day = day = response.new_day() - _SetDay(day, offset=self.request.Offset, - date=self.request.Someday) - return response + _SetDay(day, offset=request.Offset, + date=request.Someday) + return request,response ## ADDED WORKER CODE Modified: trunk/zsi/test/wsdl2py/servers/EchoServer.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -17,9 +17,9 @@ class Service(EchoServer): def soap_Echo(self, ps): - response = EchoServer.soap_Echo(self, ps) - response.EchoResult = self.request.EchoIn - return response + request,response = EchoServer.soap_Echo(self, ps) + response.EchoResult = request.EchoIn + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -20,8 +20,8 @@ class WSAService(EchoServer): def wsa_Echo(self, ps, addr): - response = EchoServer.wsa_Echo(self, ps, addr) - response.EchoResult = self.request.EchoIn + request,response = EchoServer.wsa_Echo(self, ps, addr) + response.EchoResult = request.EchoIn if isinstance(response.EchoResult, EndpointReferenceType): addr1 = response.EchoResult @@ -29,7 +29,7 @@ if a not in addr1.ReferenceProperties.Any: raise RuntimeError, 'EPRs dont match' - return response + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/FinancialService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/FinancialService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/FinancialService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -10,8 +10,8 @@ class Service(FinancialService): def soap_getPV(self, ps): - reponse = FinancialService.soap_getPV(self, ps) - args = self.request + request,response = FinancialService.soap_getPV(self, ps) + args = request # Worker code: Actual present value calculation t = 0 @@ -27,8 +27,8 @@ # WARNING specify value eg. SimpleTypeWrapper(1) #response = SimpleTypeWrapper(PV) - response = reponse.__class__(PV) - return response + response = response.__class__(PV) + return request,response Modified: trunk/zsi/test/wsdl2py/servers/SquareService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/SquareService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/SquareService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -10,9 +10,9 @@ class Service(Square.SquareService): def soap_getSquare(self, ps): - response = Square.SquareService.soap_getSquare(self, ps) - response._return = self.getSquare(self.request._x) - return response + request,response = Square.SquareService.soap_getSquare(self, ps) + response._return = self.getSquare(request._x) + return request,response def getSquare(self, x): return x**2 Modified: trunk/zsi/test/wsdl2py/servers/WhiteMesa.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/WhiteMesa.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/WhiteMesa.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -15,36 +15,36 @@ class Service(WhiteMesa): def soap_echoStruct(self, ps): - response = WhiteMesa.soap_echoStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoStruct(self, ps) + return request,response def soap_echoStructArray(self, ps): - response = WhiteMesa.soap_echoStructArray(self, ps) - return response + request,response = WhiteMesa.soap_echoStructArray(self, ps) + return request,response def soap_echoStructAsSimpleTypes(self, ps): - response = WhiteMesa.soap_echoStructAsSimpleTypes(self, ps) - return response + request,response = WhiteMesa.soap_echoStructAsSimpleTypes(self, ps) + return request,response def soap_echoSimpleTypesAsStruct(self, ps): - response = WhiteMesa.soap_echoSimpleTypesAsStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoSimpleTypesAsStruct(self, ps) + return request,response def soap_echoNestedStruct(self, ps): - response = WhiteMesa.soap_echoNestedStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoNestedStruct(self, ps) + return request,response def soap_echoNestedArray(self, ps): - response = WhiteMesa.soap_echoNestedArray(self, ps) - return response + request,response = WhiteMesa.soap_echoNestedArray(self, ps) + return request,response def soap_echoStringArray(self, ps): - response = WhiteMesa.soap_echoStringArray(self, ps) - return response + request,response = WhiteMesa.soap_echoStringArray(self, ps) + return request,response def soap_echoIntegerArray(self, ps): - response = WhiteMesa.soap_echoIntegerArray(self, ps) - return response + request,response = WhiteMesa.soap_echoIntegerArray(self, ps) + return request,response def soap_echoBoolean(self, ps): - response = WhiteMesa.soap_echoBoolean(self, ps) - response._return = self.request._inputBoolean - return response + request,response = WhiteMesa.soap_echoBoolean(self, ps) + response._return = request._inputBoolean + return request,response def soap_echoString(self, ps): - response = WhiteMesa.soap_echoString(self, ps) - return response + request,response = WhiteMesa.soap_echoString(self, ps) + return request,response if __name__ == "__main__" : port = int(sys.argv[1]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |