在我的应用程序中,我需要访问内部(公司)SOAPAPI.到目前为止,我使用的是Zeep.但现在访问必须通过代理,并且必须将API的实际地址转换为代理的虚拟地址.

创建Zeep客户端也可以正常工作,我可以访问wsdl文件.但是,在调用相应的服务时会出现问题,因为Zeep从wsdl文件中获取相应的URL,而这与代理的虚拟地址不匹配.

下面我将try 用我的具体代码来说明这个问题:

假设SOAPAPI的地址是https://original-soap/wsdl?service=<service_name>.

在代理中有一个从https://origial-soaphttp://virtual-soap的映射.

所以Zeep应该使用的地址是http://virtual-soap/wsdl?service=<service_name>.

我按如下方式初始化我的Zeep客户端:

from requests.auth import HTTPBasicAuth
from requests import Session
from zeep import Client
from zeep.transports import Transport
from zeep.helpers import serialize_object

session = Session()
session.proxies = {
    'http': 'http://<proxy_host>:<proxy_port>',
    'https': 'http://<proxy_host>:<proxy_port>',
}
proxy_header = {
    "Proxy-Authorization": "Bearer <proxy_access_token>"
}
session.headers.update(proxy_header)
session.verify = False
session.auth = HTTPBasicAuth(<soap_user>, <soap_password>)
transport = Transport(session=session)

client = Client(wsdl='http://virtual-saop/wsdl?service=<service_name>', transport=transport)

print('CLIENT INITIALIZED') # <-- This print command is executed

soap_result = client.service['<service_function_name>'](<function parameters>) # <-- Connectivity errors occur here

因此,我的问题是如何更改Zeep在调用服务时使用的URL,以便在这里也使用虚拟地址.

提前感谢您的帮助!

多亏了@Bogdan,我使用以下服务初始化代码解决了这个问题:

service = client.create_service(
    client.service._binding.name, client.service._binding_options['address'].replace('https://original-soap:443', 'http://virtual-soap:80', 1)
)

推荐答案

还有另一种创建ServiceProxy的方法可以做到这一点.

请参阅https://docs.python-zeep.org/en/master/client.html#creating-new-serviceproxy-objects处的文档

默认的ServiceProxy实例是使用wsdl中的地址创建的,但上面创建ServiceProxy的方法允许对地址进行更多控制.

{http://my-target-namespace-here}myBinding的值是您的绑定标识符.如果执行python -mzeep https://original-soap/wsdl,您应该会得到如下所示的输出(出于演示的目的,我在这里使用了一些在线示例,因为我无法访问您的WSDL):

> python -mzeep http://www.dneonline.com/calculator.asmx?WSDL

    
Prefixes:
     xsd: http://www.w3.org/2001/XMLSchema
     ns0: http://tempuri.org/

Global elements:
     ns0:Add(intA: xsd:int, intB: xsd:int)
     ns0:AddResponse(AddResult: xsd:int)
     ns0:Divide(intA: xsd:int, intB: xsd:int)
     ns0:DivideResponse(DivideResult: xsd:int)
     ns0:Multiply(intA: xsd:int, intB: xsd:int)
     ns0:MultiplyResponse(MultiplyResult: xsd:int)
     ns0:Subtract(intA: xsd:int, intB: xsd:int)
     ns0:SubtractResponse(SubtractResult: xsd:int)
     

Global types:
     xsd:anyType
     xsd:ENTITIES
     xsd:ENTITY
     xsd:ID
     xsd:IDREF
     xsd:IDREFS
     xsd:NCName
     xsd:NMTOKEN
     xsd:NMTOKENS
     xsd:NOTATION
     xsd:Name
     xsd:QName
     xsd:anySimpleType
     xsd:anyURI
     xsd:base64Binary
     xsd:boolean
     xsd:byte
     xsd:date
     xsd:dateTime
     xsd:decimal
     xsd:double
     xsd:duration
     xsd:float
     xsd:gDay
     xsd:gMonth
     xsd:gMonthDay
     xsd:gYear
     xsd:gYearMonth
     xsd:hexBinary
     xsd:int
     xsd:integer
     xsd:language
     xsd:long
     xsd:negativeInteger
     xsd:nonNegativeInteger
     xsd:nonPositiveInteger
     xsd:normalizedString
     xsd:positiveInteger
     xsd:short
     xsd:string
     xsd:time
     xsd:token
     xsd:unsignedByte
     xsd:unsignedInt
     xsd:unsignedLong
     xsd:unsignedShort

Bindings:
     Soap11Binding: {http://tempuri.org/}CalculatorSoap
     Soap12Binding: {http://tempuri.org/}CalculatorSoap12

Service: Calculator
     Port: CalculatorSoap (Soap11Binding: {http://tempuri.org/}CalculatorSoap)
         Operations:
            Add(intA: xsd:int, intB: xsd:int) -> AddResult: xsd:int
            Divide(intA: xsd:int, intB: xsd:int) -> DivideResult: xsd:int
            Multiply(intA: xsd:int, intB: xsd:int) -> MultiplyResult: xsd:int
            Subtract(intA: xsd:int, intB: xsd:int) -> SubtractResult: xsd:int

     Port: CalculatorSoap12 (Soap12Binding: {http://tempuri.org/}CalculatorSoap12)
         Operations:
            Add(intA: xsd:int, intB: xsd:int) -> AddResult: xsd:int
            Divide(intA: xsd:int, intB: xsd:int) -> DivideResult: xsd:int
            Multiply(intA: xsd:int, intB: xsd:int) -> MultiplyResult: xsd:int
            Subtract(intA: xsd:int, intB: xsd:int) -> SubtractResult: xsd:int

如果您在您的wsdl上运行该命令时查看结果,您将看到一个"绑定"部分.这就是您获得值的地方,它很可能是Soap11Binding的值(大多数服务只提供一个绑定,这个服务提供两个绑定,每个版本的SOAP协议一个).

对于文档中的http://my-endpoint.com/acceptance/,您应该替换您的新的SOAP地址(即您现在想要将服务请求发送到的新位置).从您的示例判断,这应该是http://virtual-soap/something,其中something是从原始的SOAP地址开始的原始路径,该地址在WSDL中(同样,因为我无法访问您的WSDL,所以您应该查看您需要替换地址的哪一部分,以及哪部分保持不变).

至于您想要调用什么操作,这是不会改变的.你也是这么叫的.这些方法都是相同的,因为您不需要更改服务合同,只需更改要将请求发送到的位置即可.

Python相关问答推荐

如何在Deliveryter笔记本中从同步上下文正确地安排和等待Delivercio代码中的结果?

连接两个具有不同标题的收件箱

比较2 PD.数组的令人惊讶的结果

Pandas 滚动最接近的价值

'discord.ext. commanders.cog没有属性监听器'

抓取rotowire MLB球员新闻并使用Python形成表格

运行终端命令时出现问题:pip start anonymous"

Python库:可选地支持numpy类型,而不依赖于numpy

两个pandas的平均值按元素的结果串接元素.为什么?

使用NeuralProphet绘制置信区间时出错

在Django admin中自动完成相关字段筛选

处理具有多个独立头的CSV文件

pandas:对多级列框架的列进行排序/重新排序

Flask Jinja2如果语句总是计算为false&

在输入行运行时停止代码

在Admin中显示从ManyToMany通过模型的筛选结果

基于多个数组的多个条件将值添加到numpy数组

SpaCy:Regex模式在基于规则的匹配器中不起作用

在Pandas 中以十六进制显示/打印列?

对于数组中的所有元素,Pandas SELECT行都具有值