--- client.py.orig 2010-05-02 23:41:58 +0200 +++ client.py 2010-05-03 09:45:02 +0200 @@ -19,6 +19,7 @@ See I{README.txt} """ +import cStringIO import suds import suds.metrics as metrics from cookielib import CookieJar @@ -537,6 +538,26 @@ return (500, e) else: return client.invoke(args, kwargs) + + # DRo + # process a reply offline + def processreply(self, reply, **kwargs): + """ + Process a reply asynchrounously + @param reply: A reply object + @type: suds.transport.Reply + @return: processed reply delivering the same results as if the method was called synchrounoulsy + including exceptions if HTTP responses other than 200 are passed to the method + """ + clientclass = self.clientclass(kwargs) + client = clientclass(self.client, self.method) + if not self.faults(): + try: + return client.processreply(reply) + except WebFault, e: + return (500, e) + else: + return client.processreply(reply) def faults(self): """ get faults option """ @@ -601,7 +622,7 @@ "method '%s' invoked: %s", self.method.name, timer) return result - + def send(self, msg): """ Send soap message. @@ -620,17 +641,64 @@ self.last_sent(Document(msg)) request = Request(location, str(msg)) request.headers = self.headers() + # DRo - Begin + # return the request if asked to do so + # It will be sent by the user who will later give back the reply + # to be processed + if self.options.async == True: + return request + # DRo - End reply = transport.send(request) + result = self.processreply(reply) + except TransportError, e: + log.error(self.last_sent()) + result = self.processtransporterror(e) + return result + + # DRo + # Process errors (exceptions) during transport + def processtransporterror(self, e): + """ + Processes a transport error, be it generated by the transport or simulated + during the processing of an async reply + @param e: A transport error object + @type: TransportError + @return: None or the return value from self.failed + """ + if e.httpcode in (202,204): + result = None + else: + result = self.failed(binding, e) + + return result + + # DRo + # Process the reply + def processreply(self, reply): + """ + Process a reply asynchrounously + @param reply: A reply object + @type: suds.transport.Reply + @return: processed reply delivering the same results as if the method was called synchrounoulsy + including exceptions if HTTP responses other than 200 are passed to the method + """ + + result = None + binding = self.method.binding.input + retxml = self.options.retxml + + log.debug('Processing asynchronous reply:\n%s', reply) + + if reply.code == 200: if retxml: result = reply.message else: result = self.succeeded(binding, reply.message) - except TransportError, e: - if e.httpcode in (202,204): - result = None - else: - log.error(self.last_sent()) - result = self.failed(binding, e) + else: + log.error('Transport error detected when processing the asynchronous reply') + e = TransportError('', reply.code, cStringIO.StringIO(reply.message)) + result = self.processtransporterror(e) + return result def headers(self): @@ -701,7 +769,10 @@ if d is None: return messages.get(key) else: - messages[key] = d + # DRo + # Storing the last_sent has no meaning in asynchronous mode + if self.options.async == False: + messages[key] = d def last_received(self, d=None): key = 'rx' @@ -709,7 +780,10 @@ if d is None: return messages.get(key) else: - messages[key] = d + # DRo + # Storing the last_received has no meaning in asynchronous mode + if self.options.async == False: + messages[key] = d class SimClient(SoapClient):