caratpine
caratpine

Reputation: 43

How to use zeep to make SOAP requests in python

here is my xml:

<?xml version="1.0"?>
<soapenv:Envelope>
  <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>USERNAME</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">1234</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <root xmlns="http://xmlns.oracle.com/Enterprise/tools/schema/InfoRtRequest.v1">
      <EMAIL>david</EMAIL>
    </root>
  </soapenv:Body>
</soapenv:Envelope>

here is my demo:

wsdl = ''

client = Client(
    wsdl,
    wsse=UsernameToken('USERNAME', '1234'))

response = client.service.get_method(
    EMAIL='david')

it raised VadlidationError:

ValidationError: Missing element OPRID (root.OPRID)

I don't know why, please give me some help, thanks.

Upvotes: 2

Views: 8915

Answers (1)

Srikanth Reddy
Srikanth Reddy

Reputation: 31

zeep is advanced library to handle SOAP communications in python. You should provide wsdl file, so that your issue can be better analyzed.

But by looking into the xml request you have provided, it seems the authentication is been done using headers and data is been sent in body. Similar to the usecase i have recently fixed. Refer my xml request of my use case below.

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header>
        <ns0:myheaders xmlns:ns0="xxxxxx_stackoverflow_mask_xxxxxx">
            <ns0:username>xxxxxx_stackoverflow_mask_xxxxxx</ns0:username>
            <ns0:password>xxxxxx_stackoverflow_mask_xxxxxx</ns0:password>
        </ns0:myheaders>
    </soap-env:Header>
    <soap-env:Body>
        <ns0:Search02c xmlns:ns0="xxxxxx_stackoverflow_mask_xxxxxx">
            <ns0:name>
                <ns0:title>Mr</ns0:title>
                <ns0:forename>Srikanth</ns0:forename>
                <ns0:surname>Badveli</ns0:surname>
            </ns0:name>
        </ns0:Search02c>
    </soap-env:Body>
</soap-env:Envelope>

For the above xml, the code is as follows

from zeep import Client
header_credentials = {'username':'xxxxx','password':'xxxxx'}
tac_data = {'name': {'title':'xxxxx','forename':'xxxxx','surname':'xxxxx'}}

client = Client(wsdl=wsdl)
response = client.service.Search02c(tac_data, _soapheaders={'callcreditheaders':header_credentials})

In the above code, "Search02c" is the operation name for the service. Operation name can be found while inspecting the wsdl file. In my usecase "Search02c" accepts 2 arguments which are body and header."tac_data" is the dictionary of the xml body(not header) and "header_credentials" is the dictionary of the credentials. Your use case might accept single argument clubbing header and body. The arguments structure can be found after operation name in the inspected wsdl file.

You can find the operation name and its structure in the end of the output by running this in your command prompt.

python -mzeep wsdl_file_path.wsdl

The operation for my wsdl file is below.

Operations:
    Search02c(searchDefinition: tac_data, _soapheaders={'headers': header_credentials}) -> outputResult: ns1:output

Remember, zeep only accepts dictionary as input data and provides dictionary as output. If you like to receive response as xml, use raw_response=True in the client settings.

For more information, please refer zeep documentation

Upvotes: 2

Related Questions