使用Python将带有附件的XML发送到SOAP Web服务

4

最近几周我一直在学习Python,并尝试向公共测试WS发送自定义XML。现在感觉好像没有任何进展。因此,我需要帮助或任何关于当前情况的建议。

如果您使用SoapUI或其他方法进行分析,该Soap ws会要求以下代码(我尝试了-mzeep)。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.sunat.gob.pe">    <soapenv:Header/>    <soapenv:Body>
      <ser:sendBill>
         <!--Optional:-->
         <fileName>?</fileName>
         <!--Optional:-->
         <contentFile>?</contentFile>
         <!--Optional:-->
         <partyType>?</partyType>
      </ser:sendBill>    </soapenv:Body> </soapenv:Envelope>

但是WS实际需要的是像这样的XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.sunat.gob.pe" xmlns:wsse="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <soapenv:Header>
        <wsse:Security>
            <wsse:UsernameToken>
                <wsse:Username>?</wsse:Username>
                <wsse:Password>?</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <ser:sendBill>
            <fileName>?</fileName>
            <contentFile>?</contentFile>
        </ser:sendBill>
    </soapenv:Body>
</soapenv:Envelope>

作为<contentFile>的值,一个以base64编码的zip文件,其中包含一个XML文件。WS文档特别要求将此字段编码为如下形式:
- 创建一个带有真实数据的XML结构。 - 将其放入.zip文件中。 - 将该.zip文件编码为base64格式。 - 最后将其附加到XML中。
到目前为止,我已经将自定义XML发送到WS的点上。如果我使用SoapUI进行操作,它会正常工作,因为它会检测到我在base64编码的zip文件中放入了无效的值(它会返回一个映射错误,显示“无效的值”)。但是,如果我尝试使用Python消耗它,我会从WS那里收到一个错误消息,该错误消息没有被WS提供程序列出在错误列表中。
这是我的代码。我已经阅读了Zeep文档,并向Python的Discord上的人寻求了帮助。
from zeep import Client, Settings
from zeep.wsse.username import UsernameToken

import base64

with open("20100066603-01-F001-1.zip", "rb") as f:
    bytes = f.read()
    encoded = base64.b64encode(bytes)


settings = Settings(strict=False, xml_huge_tree=True)
wsdl = 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService?wsdl'
client = Client(wsdl=wsdl, wsse=UsernameToken('20100066603MODDATOS', 'moddatos'), settings=settings)

node = client.create_message(client.service.sendBill('20100066603-01-F001-1.zip', encoded))

# response = client.service.sendBill('20100066603-01-F001-1.zip', b'bytes')
# print(client.service.sendBill('20100066603-01-F001-1.zip', b'encoded'))
# print(client.service.sendBill('20100066603-01-F001-1.zip', encoded))
# print(encoded.decode())
print(node)

我想知道我在Python做的是否正确。我想获取WS发送测试数据时所提供的XML响应。(我的目标是在使用SoapUI发送请求时获得相同的错误消息)我决定使用Zeep,因为它是我能找到的最好文档化的SOAP请求库。正如我之前所说,我对Python很新,我真的需要使用这个WS。如果这是一个重复的问题,请让我知道。或者如果这个问题可以用其他已回答的问题来回答,请给我提供链接。通过对Zeep进行一些研究,我注意到有些人说Zeep不喜欢附件(它对附件的支持不好)。所以我想知道是否有另一个库可以使用。如果有,请问您可以向我展示一个例子吗?如果没有,您会推荐我使用另一种编程语言及其库来成功完成此操作吗?这是我在StackO上的第一个问题。顺便说一下,不要担心pyhthon代码中的usernameToken数据,那是虚构的数据。
我使用Requests库发出了请求,得到一个XML,说有服务器内部错误。但我刚刚问过提供商,他们的WS正常运行。我可以通过使用SoapUI发出请求并得到我期望的错误来确认这一点。抱歉长度有点长。提前谢谢。Jajdp
1个回答

2

谁会想到用于将数据发送到SOAP ws的库通常会自动对您的文件进行base64编码。

我所做的所有代码都是正确的,但只有一个部分。与其是:

node = client.create_message(client.service.sendBill('20100066603-01-F001-1.zip', encoded))

应该是这样的

node = client.create_message(client.service.sendBill('20100066603-01-F001-1.zip', bytes))

现在脚本可以正常工作了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接