您的位置:首页 > 编程语言 > Python开发

How to pass SOAP headers into python SUDS that are not defined in WSDL file

2014-05-14 17:09 701 查看
I have a camera on my network which I am trying to connect to with suds but suds doesn't send all the information needed. I need to put extra soap headers not defined in the WSDL file so the camera can understand the message. All the headers are contained in
a SOAP envelope and then the suds command should be in the body of the message.

I have checked the suds website and
it says to pass in the headers like so: (This passes in the element as a header but I have an envelope so I'm not sure how to input this)
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)


Now, I am not sure how I would implement this. Say for example, I have the below header:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP
ENC="http://www.w3.org/2003/05/soap-encoding"
<wsa:MessageID SOAP-ENV:mustUnderstand="true">urn:uuid:43268c01-f09c6</wsa:MessageID>
<SOAP-ENV:Header>


Using this or a similar example does anyone know how I would get this passed into the soap command so my camera understands?

Thanks

python xml wsdl suds soapheader
share|improve
this question
edited Aug
13 '12 at 19:25




Joshua Burns

2,6471328

asked Mar 18 '10 at 13:08




chrissygormley

2,928114174

add
comment


1 Answer

activeoldestvotes

up
vote11down
voteaccepted
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[/code] is the address of the namespace.

A complete script that would run could be:
#!/usr/local/bin/python2.6

import suds
#import logging
from suds.client import Client
from suds.sax.element import Element
from suds.sax.attribute import Attribute
from suds.xsd.sxbasic import Import

def 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 e

if __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 logging
logging.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.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐