如何使用 ZEEP 更改 SOAP 请求中的端点地址

Posted

技术标签:

【中文标题】如何使用 ZEEP 更改 SOAP 请求中的端点地址【英文标题】:How to change endpoint address in SOAP requests with ZEEP 【发布时间】:2018-04-11 19:41:29 【问题描述】:

我正在使用 ZEEP 发出 SOAP 请求,它既简单又好用。

问题在于端点 URL(在 WSDL 中)不正确。

我可以通过直接编辑 WSDL 来解决这个问题,但这不可扩展。

我查看了有关创建服务代理的 ZEEP 文档,但我不理解它并且遇到了错误。以下是 WSDL 中包含错误 URL 的部分:

</binding>
<service name="DeviceConfigurationService">
    <port name="DeviceConfigurationPort" 
binding="xrx:DeviceConfigurationBinding">
        <soap:address 
location="http://localhost/webservices/office/device_configuration/1"/>
    </port>
    </service>

位置是我需要改变的。我需要从“localhost”更改为 LAN IP 地址。此值可能会经常更改,因此我不想每次都编辑 WSDL。

有人知道如何用 Zeep 做到这一点吗?

非常感谢任何帮助!

【问题讨论】:

【参考方案1】:

我知道这个问题很老了,但我刚刚遇到了同样的问题,因为我正在使用指向错误端点的 WSDL 访问第三方 SOAP API(第三方告诉我正确的端点但没有更新他们的 WSDL)。接受的答案确实为我指明了正确的方向,但我想提供一些额外的细节,这些细节对于像我这样的新手开发人员来说并不明显。

首先注意到Zeep's documentation 表明zeep.Client.create_service() 方法有两个参数。

binding_name – 绑定的QName

address – 端点的地址

找出binding_name

选项 1 - 通读 WSDL

binding_name 来自 WSDL 中的属性 binding。问题是该属性的值通常包含对 WSDL 中其他地方的名称的引用,您必须在使用它来创建自定义服务之前手动解析该名称。

在摘录自 OP 的 WSDL 的情况下(稍微格式化并添加了 ***强调 ***)...

<service name="DeviceConfigurationService">
    <port name="DeviceConfigurationPort" ***binding="xrx:DeviceConfigurationBinding"***>
        <soap:address location="http://localhost/webservices/office/device_configuration/1"/>
    </port>
</service>

...binding 的值为"xrx:DeviceConfigurationBinding"

虽然这是 Zeep 使用的 binding_name,但您不能只是将其复制并粘贴到 create_service() 的参数中,因为它部分包含 xrx - 一个在 WSDL 中本地定义的名称。 Zeep 在最初解析 WSDL 时会自动解析这种名称的值,因此当您告诉 Zeep 将现有绑定指向不同的端点时,您必须自己解析绑定名称,以便 Zeep 知道您在谈论哪个绑定(即为什么@jeffgabhart 在他的回答中使用了https://path-to-xrx-namespace)。最后你应该得到完整的binding_nameNAMESPACEBINDING格式。

请注意,xrx 不是唯一可能的名称。对我来说,这个名字是tns,对你来说可能是不同的东西。不管是什么,您都应该能够在 WSDL 中的某处找到该名称的定义。

选项 2 - 使用 Zeep 的 WSDL 解析实用程序

另一个选项是@576i 建议的选项。运行命令python -mzeep WSDL_URL 将输出Zeep 从给定WSDL 收集的信息。一个标题应该是“绑定”,然后是binding_name 的列表(可能长度为 1)。从那里您可以复制您需要更改端点的那个。

选项 3 - 从 Zeep 客户端对象获取它

这个感觉更像是一个 hack,但list(zeep_client.wsdl.port_types) 提供了 Zeep 在用于创建 zeep_client 的 WSDL 中找到的所有绑定名称的列表。

找出address

最后,为了完整起见,address 只是您要使用的新端点,而不是 WSDL 中定义的端点。

我希望这有助于平滑某人的学习曲线!

【讨论】:

【参考方案2】:
client = Client('http://localhost/webservices/office/device_configuration/1?wsdl')

service = client.create_service(
    'http://path-to-xrx-namespaceDeviceConfigurationBinding',
    'http://127.0.0.1/webservices/office/device_configuration/1')

service.submit('something')

【讨论】:

你能解释一下你的答案中的“path-to-xrx-namespace”吗?官方 zeep 文档写道 (my-target-namespace-here - 但它到底是什么,我如何从原始 WSDL 中找到它? 看来,“path-to-xrx-namespace”是“mzeep”工具从 zeep 文档的“使用 zeep”部分返回的那个。如果您在此处输入了不正确的值,zeep 会提供带有正确选项的有用错误消息,因此如果您不完全理解,请从错误中获取值...

以上是关于如何使用 ZEEP 更改 SOAP 请求中的端点地址的主要内容,如果未能解决你的问题,请参考以下文章

Soap 请求在 Soapui 中运行良好,但在 python 中运行良好 - ZEEP - SUDS

Python Zeep SOAP 客户端模块 - 无法为元素设置属性

如何在 Apache Camel 中更改 SOAP Web 服务端点 URL 和 WSDL URL

带有zeep的python SOAP,requests.exception:403客户端错误

SOAP(C# WCF) 通过 Zeep 接收整数列表作为参数

[TimLinux] Python3 Coverity zeep/SOAP 库使用示例