hzrari
hzrari

Reputation: 1933

Create SoapRequest without sending them with Suds/Python

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

Upvotes: 0

Views: 860

Answers (2)

hzrari
hzrari

Reputation: 1933

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,

Upvotes: 0

nofinator
nofinator

Reputation: 3023

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.

Upvotes: 1

Related Questions