如何将 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:43:50  来源:igfitidea点击:

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

pythonxmlwsdlsudssoapheader

提问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. wsaand the u = http://addressis the address of the namespace.

p = 'SOAP-ENC'可以是任何前缀eg. wsau = 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 文件中,则可以将该位置作为一个选项放入脚本中。