Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Zeep SOAP Complex Header

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: ``

like image 806
CaramuchoDotCom Avatar asked Mar 22 '17 21:03

CaramuchoDotCom


People also ask

How do I add a SOAP header in WSDL?

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.

Is header optional in SOAP?

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.

What is Zeep library in Python?

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.

What is ZEEP in Python?

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.

How to create a Zep client in Python?

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.

How to set the header element of ZEEP service?

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.

How to make soap calls with requests in ZEEP?

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.


2 Answers

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
                )
like image 81
oblivion02 Avatar answered Nov 09 '22 09:11

oblivion02


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)
like image 26
CaramuchoDotCom Avatar answered Nov 09 '22 10:11

CaramuchoDotCom