Reputation: 83
For the past few weeks I've been learning Python and tried to send a custom XML to a public test WS. Right now I feel like i'm not making any progress. So I need help or any kind of advice for my current situation.
The Soap ws ask for the following code if you analize it with SoapUI or other methods (I tried -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>
But what the WS actualy needs is an XML like this:
<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>
Being the value on <contentFile>
,a zip file encoded on base64, containing an XML file. The WS documentation specifically ask for this field to be coded like this:
-Make an XML structure with real data. -Put it into a .zip -encode that .zip into base64 format -Finaly attach it into an XML
Up until now I got till the point of sending the custom XML to the WS. If I do it using SoapUI it works normally since it detects an invalid value I put into the XML inside the zip encoded on base64 (it returns a mapped error saying "invalid value"). But if I try to consume it using Python I get an error messsage from that WS which is not mapped on the Error List the WS provider gives.
This is my code. Which I did reading Zeep documentation and also asking for help from people on Python's 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)
I want to know if what I am doing on python is correct. I would like to get the XML response the WS will deliver when sending that test data. (my goal is to have the same error message as when sending the request usin SoapUI) The reason I decided to use Zeep was because it was the most well documented library for SOAP request I could find. As i said before I'm new at python and I really need to consume this WS. If this is a duplicated question please let me know. Or if this question can be answered with other answered questions please link me to them. Doing some research about Zeep i noticed some people say Zeep does not like attachments (its support for attachments is not good). So i would like to know if there is another library i could use. If so, please would you kindly show me an example? If not, would you recommend me another programming language and its libraries where i can succesfully do this.This is my first question on StackO ever. BTW don't worry about the usernameToken data on the pyhthon code, that's fictional data. I did a request using Requests library and got an XML saying there was a server internal error. But i just ask the provider, and their WS is functioning normal. I could confirm this by doing a request using SoapUI and getting the error i was expecting. Sorry if it was long. Thanks in advance. Jajdp
Upvotes: 4
Views: 3798
Reputation: 83
Who would've thought libraries for sending data to SOAP ws usually encode your files on base64 automatically. All of the code I did was correct but a single part. Instead of:
node = client.create_message(client.service.sendBill('20100066603-01-F001-1.zip', encoded))
it should be
node = client.create_message(client.service.sendBill('20100066603-01-F001-1.zip', bytes))
Now the Scripts works correctly!
Upvotes: 2