From c42b63b29ca6e9f1d90d92eef3cc138d7b68369a Mon Sep 17 00:00:00 2001 From: jortel Date: Fri, 15 Oct 2010 13:29:37 +0000 Subject: Add 'nosend' option that causes the SoapClient to return a RequestContext instead of sending the soap envelope. It is intended that the caller use another transport such as Twisted to send the envelope. The RequestContext provides re-entry points to process the reply (succeeded() & failed()). Also, fix ticket #361 by UTF-8 encoding the soap action that is added to the http headers. --- suds/__init__.py | 4 ++-- suds/client.py | 27 ++++++++++++++++++++++++++- suds/options.py | 6 ++++++ tests/axis1.py | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/suds/__init__.py b/suds/__init__.py index 166a206..84c6e1d 100644 --- a/suds/__init__.py +++ b/suds/__init__.py @@ -26,8 +26,8 @@ import sys # Project properties # -__version__ = '0.4' -__build__="GA R699-20100913" +__version__ = '0.4.1' +__build__="GA R699-20101015" # # Exceptions diff --git a/suds/client.py b/suds/client.py index 5a74097..e242e44 100644 --- a/suds/client.py +++ b/suds/client.py @@ -620,6 +620,7 @@ class SoapClient: binding = self.method.binding.input transport = self.options.transport retxml = self.options.retxml + nosend = self.options.nosend prettyxml = self.options.prettyxml log.debug('sending to (%s)\nmessage:\n%s', location, soapenv) try: @@ -631,7 +632,10 @@ class SoapClient: else: soapenv = soapenv.plain() soapenv = soapenv.encode('utf-8') - plugins.message.sending(envelope=soapenv) + ctx = plugins.message.sending(envelope=soapenv) + soapenv = ctx.envelope + if nosend: + return RequestContext(self, binding, soapenv) request = Request(location, soapenv) request.headers = self.headers() reply = transport.send(request) @@ -656,6 +660,8 @@ class SoapClient: @rtype: dict """ action = self.method.soap.action + if isinstance(action, unicode): + action = action.encode('utf-8') stock = { 'Content-Type' : 'text/xml; charset=utf-8', 'SOAPAction': action } result = dict(stock, **self.options.headers) log.debug('headers = %s', result) @@ -783,3 +789,22 @@ class SimClient(SoapClient): return (500, p) else: return (500, None) + + +class RequestContext: + + def __init__(self, client, binding, sent): + self.client = client + self.binding = binding + self.sent = sent + + def succeeded(self, reply): + options = self.client.options + plugins = PluginContainer(options.plugins) + ctx = plugins.message.received(reply=reply) + reply = ctx.reply + return self.client.succeeded(self.binding, reply) + + def failed(self, error): + return self.client.failed(self.binding, error) + \ No newline at end of file diff --git a/suds/options.py b/suds/options.py index 86ea245..dabd770 100644 --- a/suds/options.py +++ b/suds/options.py @@ -99,6 +99,11 @@ class Options(Skin): - default: 0 - B{plugins} - A plugin container. - type: I{list} + - B{nosend} - Create the soap envelope but don't send. + When specified, method invocation returns a I{RequestContext} + instead of sending it. + - type: I{bool} + - default: False """ def __init__(self, **kwargs): domain = __name__ @@ -119,5 +124,6 @@ class Options(Skin): Definition('autoblend', bool, False), Definition('cachingpolicy', int, 0), Definition('plugins', (list, tuple), []), + Definition('nosend', bool, False), ] Skin.__init__(self, domain, definitions, kwargs) diff --git a/tests/axis1.py b/tests/axis1.py index e221fae..5c72867 100644 --- a/tests/axis1.py +++ b/tests/axis1.py @@ -137,6 +137,20 @@ try: print 'addPersion()' result = client.service.addPerson(person) print '\nreply(\n%s\n)\n' % str(result) + + # + # Async + # + client.options.nosend=True + reply = 'person (jeffӒ,ortel) at age 43 with phone numbers (410-555-5138,919-555-4406,205-777-1212, and pets (Chance,) - added.' + request = client.service.addPerson(person) + result = request.succeeded(reply) + error = Object() + error.httpcode = '500' + client.options.nosend=False +# request.failed(error) + + # # # create a new name object used to update the person # -- cgit v1.2.1