如何将 SOAP 标头传递到未在 WSDL 文件中定义的 python SUDS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2469988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass SOAP headers into python SUDS that are not defined in WSDL file
提问by chrissygormley
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.
我的网络上有一个摄像头,我试图用 suds 连接它,但 suds 没有发送所有需要的信息。我需要添加未在 WSDL 文件中定义的额外soap标头,以便相机可以理解该消息。所有的头都包含在一个 SOAP 信封中,然后 suds 命令应该在消息的正文中。
I have checked the suds websiteand 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)
我检查了 suds网站,它说要像这样传入标题:(这将元素作为标题传入,但我有一个信封,所以我不确定如何输入)
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 pass a valid SOAP message to the targeted service?
使用这个或类似的例子有谁知道我将如何将有效的 SOAP 消息传递给目标服务?
Thanks
谢谢
回答by chrissygormley
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:
我已经研究出如何在 suds 中输入新的标题和命名空间。如上所述,您创建了一个元素并将其作为soapheader 传入,如下所示:
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.
但是如果你想添加一个命名空间,我发现添加一个前缀似乎可以解决问题。因此,当您创建您添加的元素之一时addPrefix
。我不确定这是否是它打算完成的方式,但它确实有效。
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.
该p = 'SOAP-ENC'
可以是任何前缀eg. wsa
和u = http://address
是命名空间的地址。
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:
您可以在此脚本中添加日志记录,以便您检查发送的 xml 命令,这很方便:
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.
如果该位置不在 wsdl 文件中,则可以将该位置作为一个选项放入脚本中。