I'd like to pass "Complex" Header to a SOAP service with zeep library
Here's what it should look like
<soapenv:Header>
<something:myVar1>FOO</something:myVar1>
<something:myVar2>JAM</something:myVar2>
</soapenv:Header>
I guess that I succeed in sending a header this way
header = xsd.Element(
'{http://urlofthews}Header',
xsd.ComplexType([
xsd.Element(
'{http://urlofthews}myVar1',
xsd.String()),
xsd.Element(
'{http://urlofthews}myVar2',
xsd.String())
])
)
header_value = header(myVar1='FOO',myVar2='JAM')
print (header_value)
datasoap=client.service.UserRessourcesCatalog(requete,_soapheaders=[header_value])
But I don't get how to declare and pass the namespace "something" in my Header with the XSD.
Any Help ?
Thx by advance.
Best Regards
As mentionned in the documentation
http://docs.python-zeep.org/en/master/headers.html
"Another option is to pass an lxml Element object. This is generally useful if the wsdl doesn’t define a soap header but the server does expect it."
which is my case so I tried
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
ET.register_namespace('something', 'http://urlofthews')
headerXML = ET.Element("soapenv:Header")
var1 = ET.SubElement(headerXML, "something:myVar1")
var1.text = "FOO"
var2 = ET.SubElement(headerXML, "something:myVar2")
var2.text = "JAM"
headerDict=xmltodict.parse(ET.tostring(headerXML))
print (json.dumps(headerDict))
datasoap=client.service.UserRessourcesCatalog(requete,_soapheaders=headerDict)
But I get : ComplexType() got an unexpected keyword argument u'soapenv:Header'. Signature: ``
You can populate a SOAP header in the following ways: Define the SOAP header in the WSDL definition as part of the SOAP binding. You indicate these headers by using a <soap:header> tag in the <wsdl:input> and <wsdl:output> elements in the WSDL file.
The SOAP <Header> is an optional element in a SOAP message. It is used to pass application-related information that is to be processed by SOAP nodes along the message path. The immediate child elements of the <Header> element are called header blocks.
Quick Introduction. Zeep inspects the WSDL document and generates the corresponding code to use the services and types in the document. This provides an easy to use programmatic interface to a SOAP server. The emphasis is on SOAP 1.1 and SOAP 1.2, however Zeep also offers support for HTTP Get and Post bindings.
Working with SOAP based web services can sometimes be a time taking task when you have to write the complete XML for making API requests and then parse the response xml to fetch the desired results. That’s a headache right? Well, that’s when zeep comes into play. Zeep is a pure-python module.
The first thing that you’ll need to do is, install the zeep python library as: Now, in your python code, you’ll need to import Client from zeep and then instantiate the same by passing the wsdl url in it as shown below: You can also pass user autherntication details (username and passowrd) in case the wsdl is password protected.
Now, you need to set the header element with method_url and service_url. Now, initialize a zeep client with the WSDL URL. All the setup is done, now you just need to call the zeep service with the service name, here the service name is CountryIntPhoneCode.
To know the format, simply visit the SOAP URL and click on CountryISOCode link and format the XML accordingly. Then you simply prepare the headers and make the POST call. Now that we have seen how to make SOAP calls with requests, we are going to see how easy it is to make it through Zeep.
I recently encountered this problem, and here is how I solved it.
Say you have a 'Security' header that looks as follows...
<env:Header>
<Security>
<UsernameToken>
<Username>__USERNAME__</Username>
<Password>__PWD__</Password>
</UsernameToken>
<ServiceAccessToken>
<AccessLicenseNumber>__KEY__</AccessLicenseNumber>
</ServiceAccessToken>
</Security>
</env:Header>
In order to send this header in the zeep client's request, you would need to do the following:
header = zeep.xsd.Element(
'Security',
zeep.xsd.ComplexType([
zeep.xsd.Element(
'UsernameToken',
zeep.xsd.ComplexType([
zeep.xsd.Element('Username',zeep.xsd.String()),
zeep.xsd.Element('Password',zeep.xsd.String()),
])
),
zeep.xsd.Element(
'ServiceAccessToken',
zeep.xsd.ComplexType([
zeep.xsd.Element('AccessLicenseNumber',zeep.xsd.String()),
])
),
])
)
header_value = header(UsernameToken={'Username':'test_user','Password':'testing'},UPSServiceAccessToken={'AccessLicenseNumber':'test_pwd'})
client.service.method_name_goes_here(
_soapheaders=[header_value],#other method data goes here
)
Thx Oblivion02.
I finally use a raw method
headers = {'content-type': 'text/xml'}
body = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://blablabla">
<soapenv:Header>
<something:myVar1>FOO</something:myVar1>
<something:myVar2>JAM</something:myVar2>
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>"""
response = requests.post(wsdl,data=body,headers=headers)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With