简体   繁体   中英

How to handle complexType arguments in python soap module zeep?

Zeep documentation example :

from zeep import Client

client = Client('http://my-enterprise-endpoint.com')
client.service.submit_order(user_id=1, order={
    'number': '1234',
    'price': 99,
})

My use case :

I want to call a webservice that needs a parameter 'findCriteria'

Example :

findcriteria =  {
        'Criteria' : [{
                        'ColumnName' : 'Closed',
                        'Value' : 0
                },
                {
                        'ColumnName' : 'AssignToQueueID',
                        'Value' : queueid
                },
                {
                        'ColumnName' : 'SupportCallType',
                        'Value' : 'I'
                }
                ]
        }

Calling the service :

print client.service.GetCount(findCriteria = findcriteria)

This is the XML that is created:

<soap-env:Body>
    <ns1:GetCount>
      <ns1:findCriteria/>
    </ns1:GetCount>
  </soap-env:Body>
</soap-env:Envelope>

Problem:

Although the service returns the count, the criteria are not applied.

When I feed the service a raw XML payload the results are OK.

The problem is in the <ns1:findCriteria/> part.

For each column there should be created a Criteria element.

Results of grep GetCount on WSDL:

<s:element name="GetCount">
      <s:element name="GetCountResponse">
            <s:element minOccurs="1" maxOccurs="1" name="GetCountResult" type="s:int" />
  <wsdl:message name="GetCountSoapIn">
    <wsdl:part name="parameters" element="tns:GetCount" />
  <wsdl:message name="GetCountSoapOut">
    <wsdl:part name="parameters" element="tns:GetCountResponse" />
    <wsdl:operation name="GetCount">
      <wsdl:input message="tns:GetCountSoapIn" />
      <wsdl:output message="tns:GetCountSoapOut" />
    <wsdl:operation name="GetCount">
      <soap:operation soapAction="http://<server>/webservices/SupportCall/GetCount" style="document" />
    <wsdl:operation name="GetCount">
      <soap12:operation soapAction="http://<server>/webservices/SupportCall/GetCount" style="document" />

I had a similar problem and I managed to solve it, but to help you I need either a sample correct XML (how it should look like) or at least a default request generated using SoapUI.

In the meantime, perhaps the code below might help you: Here the complex argument was credentials and it consisted of 2 login items, the login and the domain.

<soap-env:Envelope xmlns:ns1="http://xml.kamsoft.pl/ws/kaas/login_types" 
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Body>
    <ns1:login>
      <ns1:credentials>
        <ns1:item>
          <ns1:name>login</ns1:name>
          <ns1:value>
             <ns1:stringValue>login_here</ns1:stringValue>
          </ns1:value>
        </ns1:item>
        <ns1:item>
           <ns1:name>domain</ns1:name>
           <ns1:value>
             <ns1:stringValue>domain_here</ns1:stringValue>
           </ns1:value>
        </ns1:item>
      </ns1:credentials>
      <ns1:password>password_here</ns1:password>
    </ns1:login>
  </soap-env:Body>
</soap-env:Envelope>

And here is the code that generated this XML:

domain = "domain_here"
login = "login_here"
password = "password_here"
credentials = {"item": [{"name": "login", 'value': {"stringValue": login}},
                        {"name": "domain", 'value': {"stringValue": domain}}]}
client.service.login(credentials=credentials, password=password)

Inspect your wsdl with following command: python -mzeep <wsdl>

You will find details of your service in the output: ns1:GetCount(FindCriteria:findCriteria)

Sample code based on above inspection output:

find_criteria_type = client.get_type('ns1:findCriteria')
find_criteria = find_criteria_type()
client.service.GetCount(FindCriteria=find_criteria)

If you XML is something like this:

<soap-env:Body>
  <ns1:GetCount>
     <ns1:findCriteria>
       <ns1:param1>val1</ns1:param1>
       <ns1:param2>val2</ns1:param1>
     </ns1:findCriteria>
  </ns1:GetCount>
</soap-env:Body>

you need to pass the params when creating the obj:

find_criteria = find_criteria_type(param1=val1, param2=val2)

When I run the following commands:

GET_TYPE_PutPropDataMappings=CPRManager_url.get_type('ns1:PropDataMapperSetup')
print(GET_TYPE_PutPropDataMappings)
SET_Values_PutPropDataMappings=GET_TYPE_PutPropDataMappings(ActingUserId='388153')
print(SET_Values_PutPropDataMappings)

The result is :-

PropDataMapperSetup({http://www.ABCd.com/CPR/Manager}PropDataMapperSetup(ActingUserId: xsd:int, Mappings: {http://www.ABCd.com/CPR/Manager}ArrayOfPropDataMapping, UserCompanyId: xsd:int))
{
    'ActingUserId': '388153',
    'Mappings': None,
    'UserCompanyId': None
}

Which looks correct. However, when I run the request to fetch the values, with the following command:

Response_PutPropDataMappings=CPRManager_url.service.PutPropDataMappings(propDataMapperSetup=SET_Values_PutPropDataMappings)
print(Response_PutPropDataMappings)

I Get:-

{
    'ErrorCodes': None,
    'ErrorMessages': {
        'string': [
            'Invalid acting userid :0'
        ]
    },
    'WarningMessages': None,
    'WasSuccessful': None
}

which is same as passing :-

Response_PutPropDataMappings=CPRManager_url.service.PutPropDataMappings(propDataMapperSetup)
print(Response_PutPropDataMappings)

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