From 43e2ed2fc7209a942a98b7cd5dbabe73aa5aa63d Mon Sep 17 00:00:00 2001 From: Nicola Gramola Date: Thu, 19 Apr 2018 08:57:25 +0200 Subject: [PATCH] Modify dispacher for differente response element name --- .../examples/controllers/soap_examples.py | 20 +++++++++++++ applications/welcome/languages/it.py | 5 ++++ gluon/contrib/pysimplesoap/__init__.py | 2 +- gluon/contrib/pysimplesoap/client.py | 2 +- gluon/contrib/pysimplesoap/server.py | 28 +++++++++---------- gluon/tools.py | 8 +++--- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/applications/examples/controllers/soap_examples.py b/applications/examples/controllers/soap_examples.py index 2d091e80..170fe720 100644 --- a/applications/examples/controllers/soap_examples.py +++ b/applications/examples/controllers/soap_examples.py @@ -25,6 +25,9 @@ def division(a, b): "Divide two values " return a / b +@service.soap('DummyCustomElement', returns={'out0': str}, args={'in0': str}, response_element_name='customResponseTag') +def dummy(in0): + return in0 # expose the soap methods @@ -51,3 +54,20 @@ def test_soap_sub(): xml_response=client.xml_response, result=result) +def test_custom_response_element_name(): + from gluon.contrib.pysimplesoap.client import SoapClient, SoapFault + # build the url to the WSDL (web service description) + # like "http://localhost:8000/webservices/sample/call/soap?WSDL" + url = URL(f="call/soap", vars={"WSDL": ""}, scheme=True) + # create a SOAP client + client = SoapClient(wsdl=url) + # call the SOAP remote method + try: + ret = client.DummyCustomElement(in0="Hello World!") + result = ret['out0'] + except SoapFault as sf: + result = sf + response.view = "soap_examples/generic.html" + return dict(xml_request=client.xml_request, + xml_response=client.xml_response, + result=result) diff --git a/applications/welcome/languages/it.py b/applications/welcome/languages/it.py index f145075e..2b123998 100755 --- a/applications/welcome/languages/it.py +++ b/applications/welcome/languages/it.py @@ -34,6 +34,7 @@ 'An error occured, please %s the page': 'È stato rilevato un errore, prego %s la pagina', 'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', 'And': 'E', +'API Example': 'API Example', 'appadmin is disabled because insecure channel': 'Amministrazione (appadmin) disabilitata: comunicazione non sicura', 'Are you sure you want to delete this object?': 'Sicuro di voler cancellare questo oggetto ?', 'Available Databases and Tables': 'Database e tabelle disponibili', @@ -99,6 +100,7 @@ 'Email and SMS': 'Email e SMS', 'Email non valida': 'Email non valida', 'enter a number between %(min)g and %(max)g': 'enter a number between %(min)g and %(max)g', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', 'enter an integer between %(min)g and %(max)g': 'inserisci un intero tra %(min)g e %(max)g', 'Errors': 'Errori', 'Errors in form, please check it out.': 'Errori nel form, ricontrollalo', @@ -110,6 +112,7 @@ 'Forms and Validators': 'Forms and Validators', 'Free Applications': 'Free Applications', 'Graph Model': 'Graph Model', +'Grid Example': 'Grid Example', 'Group %(group_id)s created': 'Group %(group_id)s created', 'Group ID': 'ID Gruppo', 'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s', @@ -226,6 +229,7 @@ 'Semantic': 'Semantic', 'Services': 'Servizi', 'Sign Up': 'Sign Up', +'Sign up': 'Sign up', 'Size of cache:': 'Size of cache:', 'starts with': 'comincia con', 'state': 'stato', @@ -273,6 +277,7 @@ 'Welcome to web2py': 'Benvenuto su web2py', 'Welcome to web2py!': 'Benvenuto in web2py!', 'Which called the function %s located in the file %s': 'che ha chiamato la funzione %s presente nel file %s', +'Wiki Example': 'Wiki Example', 'Working...': 'Working...', 'XML': 'XML', 'You are successfully running web2py': 'Stai eseguendo web2py con successo', diff --git a/gluon/contrib/pysimplesoap/__init__.py b/gluon/contrib/pysimplesoap/__init__.py index f62376dc..a00e0f93 100644 --- a/gluon/contrib/pysimplesoap/__init__.py +++ b/gluon/contrib/pysimplesoap/__init__.py @@ -8,7 +8,7 @@ __author__ = "Mariano Reingart" __author_email__ = "reingart@gmail.com" __copyright__ = "Copyright (C) 2013 Mariano Reingart" __license__ = "LGPL 3.0" -__version__ = "1.16" +__version__ = "1.16.2" TIMEOUT = 60 diff --git a/gluon/contrib/pysimplesoap/client.py b/gluon/contrib/pysimplesoap/client.py index 2518bcab..48eefad2 100755 --- a/gluon/contrib/pysimplesoap/client.py +++ b/gluon/contrib/pysimplesoap/client.py @@ -300,7 +300,7 @@ class SoapClient(object): } if self.action is not None: - headers['SOAPAction'] = soap_action + headers['SOAPAction'] = '"' + soap_action + '"' headers.update(self.http_headers) log.info("POST %s" % location) diff --git a/gluon/contrib/pysimplesoap/server.py b/gluon/contrib/pysimplesoap/server.py index 4f92b506..ede39082 100644 --- a/gluon/contrib/pysimplesoap/server.py +++ b/gluon/contrib/pysimplesoap/server.py @@ -119,11 +119,11 @@ class SoapDispatcher(object): xml = xml.replace('/>', ' ' + _ns_str + '/>') return xml - def register_function(self, name, fn, returns=None, args=None, doc=None): - self.methods[name] = fn, returns, args, doc or getattr(fn, "__doc__", "") + def register_function(self, name, fn, returns=None, args=None, doc=None, response_element_name=None): + self.methods[name] = fn, returns, args, doc or getattr(fn, "__doc__", ""), response_element_name or '%sResponse' % name def response_element_name(self, method): - return '%sResponse' % method + return self.methods[method][4] def dispatch(self, xml, action=None, fault=None): """Receive and process SOAP call, returns the xml""" @@ -179,7 +179,7 @@ class SoapDispatcher(object): prefix = method.get_prefix() log.debug('dispatch method: %s', name) - function, returns_types, args_types, doc = self.methods[name] + function, returns_types, args_types, doc, response_element_name = self.methods[name] log.debug('returns_types %s', returns_types) # de-serialize parameters (if type definitions given) @@ -286,11 +286,11 @@ class SoapDispatcher(object): def list_methods(self): """Return a list of aregistered operations""" - return [(method, doc) for method, (function, returns, args, doc) in self.methods.items()] + return [(method, doc) for method, (function, returns, args, doc, response_element_name) in self.methods.items()] def help(self, method=None): """Generate sample request and response messages""" - (function, returns, args, doc) = self.methods[method] + (function, returns, args, doc, response_element_name) = self.methods[method] xml = """ <%(method)s xmlns="%(namespace)s"/> @@ -307,8 +307,8 @@ class SoapDispatcher(object): xml = """ -<%(method)sResponse xmlns="%(namespace)s"/> -""" % {'method': method, 'namespace': self.namespace} +<%(response_element_name)s xmlns="%(namespace)s"/> +""" % {'response_element_name': response_element_name, 'namespace': self.namespace} response = SimpleXMLElement(xml, namespace=self.namespace, prefix=self.prefix) if returns: items = returns.items() @@ -317,7 +317,7 @@ class SoapDispatcher(object): else: items = [] for k, v in items: - response('%sResponse' % method).marshall(k, v, add_comments=True, ns=False) + response(response_element_name).marshall(k, v, add_comments=True, ns=False) return request.as_xml(pretty=True), response.as_xml(pretty=True), doc @@ -343,7 +343,7 @@ class SoapDispatcher(object): """ % {'namespace': self.namespace, 'name': self.name, 'documentation': self.documentation} wsdl = SimpleXMLElement(xml) - for method, (function, returns, args, doc) in self.methods.items(): + for method, (function, returns, args, doc, response_element_name) in self.methods.items(): # create elements: def parse_element(name, values, array=False, complex=False): @@ -389,20 +389,20 @@ class SoapDispatcher(object): e.add_attribute('type', t) parse_element("%s" % method, args and args.items()) - parse_element("%sResponse" % method, returns and returns.items()) + parse_element(response_element_name, returns and returns.items()) # create messages: - for m, e in ('Input', ''), ('Output', 'Response'): + for m, e in ('Input', method), ('Output', response_element_name): message = wsdl.add_child('wsdl:message') message['name'] = "%s%s" % (method, m) part = message.add_child("wsdl:part") part[:] = {'name': 'parameters', - 'element': 'tns:%s%s' % (method, e)} + 'element': 'tns:%s' % e} # create ports portType = wsdl.add_child('wsdl:portType') portType['name'] = "%sPortType" % self.name - for method, (function, returns, args, doc) in self.methods.items(): + for method, (function, returns, args, doc, response_element_name) in self.methods.items(): op = portType.add_child('wsdl:operation') op['name'] = method if doc: diff --git a/gluon/tools.py b/gluon/tools.py index 656917e3..f5c13f5e 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -5070,7 +5070,7 @@ class Service(object): return f return _amfrpc3 - def soap(self, name=None, returns=None, args=None, doc=None): + def soap(self, name=None, returns=None, args=None, doc=None, response_element_name=None): """ Example: Use as:: @@ -5094,7 +5094,7 @@ class Service(object): """ def _soap(f): - self.soap_procedures[name or f.__name__] = f, returns, args, doc + self.soap_procedures[name or f.__name__] = f, returns, args, doc, response_element_name return f return _soap @@ -5400,8 +5400,8 @@ class Service(object): prefix='pys', documentation=documentation, ns=True) - for method, (function, returns, args, doc) in iteritems(procedures): - dispatcher.register_function(method, function, returns, args, doc) + for method, (function, returns, args, doc, resp_elem_name) in iteritems(procedures): + dispatcher.register_function(method, function, returns, args, doc, resp_elem_name) if request.env.request_method == 'POST': fault = {} # Process normal Soap Operation