0

Is there anyway to get suds returning the SoapRequest (in XML) without sending it?

The idea is that the upper levels of my program can call my API with an additional boolean argument (simulation).

If simulation == false then process the other params and send the request via suds
If simulation == false then process the other params, create the XML using suds (or any other way) and return it to the caller without sending it to the host.

I already implemented a MessagePlugin follwing https://fedorahosted.org/suds/wiki/Documentation#MessagePlugin, but I am not able to get the XML, stop the request and send back the XML to the caller...

Regards

hzrari
  • 1,803
  • 1
  • 15
  • 26

2 Answers2

1

suds uses a "transport" class called HttpAuthenticated by default. That is where the actual send occurs. So theoretically you could try subclassing that:

from suds.client import Client
from suds.transport import Reply
from suds.transport.https import HttpAuthenticated

class HttpAuthenticatedWithSimulation(HttpAuthenticated):

    def send(self, request):
        is_simulation = request.headers.pop('simulation', False)
        if is_simulation:
            # don't actually send the SOAP request, just return its XML
            return Reply(200, request.headers.dict, request.msg)

        return HttpAuthenticated(request)

...
sim_transport = HttpAuthenticatedWithSimulation()
client = Client(url, transport=sim_transport,
                headers={'simulation': is_simulation})

It's a little hacky. (For example, this relies on HTTP headers to pass the boolean simulation option down to the transport level.) But I hope this illustrates the idea.

nofinator
  • 2,906
  • 21
  • 25
  • Hi Thanks for your response. I am already using another HttpTransport class to perform an Ssl mutual authentication http://stackoverflow.com/questions/6277027/suds-over-https-with-cert. In theory if I just declare the send method with your sample it should work? I will give it a try tomorrow – hzrari Sep 24 '14 at 18:58
  • your suggestion worked perfectly for me. I have just done some small modification. I will edit my post with the solution – hzrari Sep 25 '14 at 11:14
0

The solution that I implemented is:

class CustomTransportClass(HttpTransport):
def __init__(self, *args, **kwargs):
    HttpTransport.__init__(self, *args, **kwargs)
    self.opener = MutualSSLHandler() # I use a special opener to  enable a mutual SSL authentication

def send(self,request):
    print "===================== 1-* request is going ===================="
    is_simulation = request.headers['simulation']
    if is_simulation == "true":
        # don't actually send the SOAP request, just return its XML
        print "This is a simulation :"
        print request.message
        return Reply(200, request.headers, request.message )

    return HttpTransport.send(self,request)


sim_transport = CustomTransportClass()
client = Client(url, transport=sim_transport,
            headers={'simulation': is_simulation})

Thanks for your help,

hzrari
  • 1,803
  • 1
  • 15
  • 26