How to pass SOAP headers into python SUDS that are not defined in WSDL file
I have worked out how to enter in new headers and namespaces in suds.As stated above you create an Element and pass it in as a soapheader as so:
from suds.sax.element import Element client = client(url) ssnns = ('ssn', 'http://namespaces/sessionid') ssn = Element('SessionID', ns=ssnns).setText('123') client.set_options(soapheaders=ssn) result = client.service.addPerson(person)
But if you would like to add a namespace I have found adding a prefix seem's to do the trick. So when you create one of the elements you add addPrefix
. I'm not sure if this was the way it was intended to be done but it work's.
ssn = Element('SessionID', ns=ssnns).setText('123').addPrefix(p='SOAP-ENC', u='http://www.w3.org/2003/05/soap-encoding')
The p = 'SOAP-ENC'
can be any prefix eg. wsa
and the u = http://address
is the address of the namespace.
A complete script that would run could be:
#!/usr/local/bin/python2.6import suds#import loggingfrom suds.client import Clientfrom suds.sax.element import Elementfrom suds.sax.attribute import Attributefrom suds.xsd.sxbasic import Importdef absoluteMove(): # connects to WSDL file and stores location in variable 'client' client = Client('http://10.10.10.10/p.wsdl') client.options.location = 'http://10.10.10.10:32963' # Create the header wsans = ('wsa', 'http://schemas.xmlsoap.org/ws/2004/08/addressing') mustAttribute = Attribute('SOAP-ENV:mustUnderstand', 'true') n1s = ('SOAP-ENC', 'http://www.w3.org/2003/05/soap-encoding') msgId = Element('Element').addPrefix(p='SOAP-ENC', u='http://www.w3.org/2003/05/soap-encoding') msgId2 = Element('Address', ns=wsans).setText('http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous') msgId1 = Element('ReplyTo', ns=wsans).insert(msgId2) msgId1.append(mustAttribute) msgId3 = Element('To', ns=wsans).setText('http://10.10.10.10:32954') msgId3.append(mustAttribute) client.set_options(soapheaders=[msgId, msgId1, msgId3, msgId2]) # Create 'token' object to pass as an argument using the 'factory' namespace token = client.factory.create('ns4:ReferenceToken') # Create 'dest' object to pass as an argument and values passed to this object dest = client.factory.create('ns4:PTZVector') dest.PanTilt._x=1 dest.PanTilt._y=4.9 dest.Zoom._x=1 # Create 'speed' object to pass as an argument and values passed to this object speed = client.factory.create('ns4:PTZSpeed') speed.PanTilt._x=0 speed.PanTilt._y=0 speed.Zoom._x=1 # 'AbsoluteMove' method invoked passing in the new values entered in the above objects try: result = client.service.AbsoluteMove(token, dest, speed) print "absoluteMove result ", result return result except suds.WebFault, e: print "suds.WebFaults caught: " print eif __name__ == '__main__': result = absoluteMove()
This moves the camera. To change the type of soap-envelope check my next question.
You can add logging into this script whci allow's you to check what xml command you have sent which is handy:
import logginglogging.basicConfig(level=logging.INFO)logging.getLogger('suds.client').setLevel(logging.DEBUG)
The location can be put into the script as an option if the location is not in the wsdl file.