简体   繁体   中英

How to produce SOAP request with zeep

I have a problem to produce a SOAP request using Python + Zeep. I need to produce a request like this sample SOAP request:

   <soapenv:Header>
      <typ:UserCredentials>
         <typ:Username>username</typ:Username>
         <typ:Password>password</typ:Password>
         <!--Optional:-->
         <typ:Extension>
            <!--You may enter ANY elements at this point-->
         </typ:Extension>
         <!--You may enter ANY elements at this point-->
      </typ:UserCredentials>
   </soapenv:Header>
   <soapenv:Body>
      <typ:GetChildren>
         <typ:InterplayURI>uri</typ:InterplayURI>
         <!--Optional:-->
         <typ:IncludeFolders>true</typ:IncludeFolders>
         <!--Optional:-->
         <typ:IncludeFiles>false</typ:IncludeFiles>
         <!--Optional:-->
         <typ:IncludeMOBs>false</typ:IncludeMOBs>
         <!--Optional:-->
         <!--Optional:-->
         <typ:ReturnAttributes>
            <!--Zero or more repetitions:-->
            <typ:Attribute Group="?" Name="?">?</typ:Attribute>
         </typ:ReturnAttributes>
         <!--Optional:-->
         <typ:Extension>
            <!--You may enter ANY elements at this point-->
         </typ:Extension>
         <!--You may enter ANY elements at this point-->
      </typ:GetChildren>
   </soapenv:Body>
</soapenv:Envelope>

I tested this request with SOAPUI and it works fine.

Using Zeep I am not able to produce a similar output.

I already tried to manually create elements using a dictionary and by passing elements itself. I always get errors like this:

    'Errors': {
        'Error': [
            {
                'InterplayURI': None,
                'Message': 'The username or password is incorrect',
                'Details': 'Unable to login user null to workgroup null.',
                'Extension': None,
                '_value_1': None,
                'Code': 'INVALID_CREDENTIALS',
                '_attr_1': {
            }
            }
        ]
    },
    'Results': None,
    'Extension': None,
    '_value_1': None,
    '_attr_1': None
}

The request that is produced by Zeep looks like this:

b'<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header><ns0:Username xmlns:ns0="http://avid.com/interplay/ws/assets/types">user</ns0:Username><ns1:Password xmlns:ns1="http://avid.com/interplay/ws/assets/types">password</ns1:Password></soap-env:Header><soap-env:Body><ns0:GetChildren xmlns:ns0="http://avid.com/interplay/ws/assets/types"><ns0:InterplayURI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:GetChildrenType"><ns0:InterplayURI>uri</ns0:InterplayURI></ns0:InterplayURI></ns0:GetChildren></soap-env:Body></soap-env:Envelope>'

It seems like the server is not able to understand this request because it differs from the expected request shown at the beginning.

My python code actually looks like this. It contains parts I already tried but are not actually used for the genereated output above. Some values are modified with sample data:

from zeep import Client
from zeep import xsd
from zeep.plugins import HistoryPlugin
import lxml.etree as etree

wsdl = 'http://localhost/services/Assets?wsdl'
history = HistoryPlugin()
client = Client(wsdl, plugins=[history])
credentialType = client.get_type('ns0:UserCredentialsType')
credentials = credentialType(Username='user', Password='passwortd')
credentialTest = { 'UserCredentials': { 'Username':'user', 'Password':'password'}} 
param = client.get_type('ns0:GetChildrenType')
params = param(InterplayURI='uri') 
header = xsd.ComplexType([
    xsd.Sequence([
        xsd.Element('Username', xsd.String()),
        xsd.Element('Password', xsd.String())
        ])
    ])
header_value = header(Username='user', Password='password')
response = client.create_message(client.service, 'GetChildren', params, _soapheaders=[credentials])
request = etree.tostring(response)
serverResponse = client.service.GetChildren(request)
print(request)
print(serverResponse)

In the end it seems to be a hazzle to produce this output with Zeep, because of all those nested custom types in the sample request. I also have problem with the credentials in the Soap header.

Anyone has ideas how to achieve this? Maybe it is easier to write those xml myself?

Use the history plugin to reproduce the sent message which includes the xml and http headers sent

from zeep import Client
from zeep.plugins import HistoryPlugin

history = HistoryPlugin()
client = Client('http://examples.python-zeep.org/basic.wsdl', plugins=[history])
client.service.DoSomething()

print(history.last_sent)
print(history.last_received)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM