2

There is an external SOAP server that I'm trying to connect and make requests using the python-django framework with the zeep library.

The WSDL dump is as follows:

Prefixes:
 xsd: http://www.w3.org/2001/XMLSchema
 ns0: http://tempuri.org/

Global elements:
 ns0:GetJobCards(key: xsd:string, technicianID: xsd:string, jobCardNumber: xsd:string, jobcards: ns0:ArrayOfJobCardsEnt, message: xsd:string)
 ns0:GetJobCardsResponse(GetJobCardsResult: xsd:boolean, jobcards:ns0:ArrayOfJobCardsEnt, message: xsd:string)

Global types:
  xsd:anyType
  ns0:ArrayOfJobCardsEnt(JobCardsEnt: {schema: , _value_1: ANY}[])
  xsd:ID
  xsd:IDREF
  xsd:IDREFS
  xsd:NCName
  xsd:NMTOKEN
  xsd:NMTOKENS
  xsd:NOTATION
  xsd:Name
  xsd:QName
  xsd:anySimpleType
  xsd:anyURI
  xsd:base64Binary
  xsd:boolean
  xsd:byte
  xsd:date
  xsd:dateTime
  xsd:decimal
  xsd:double
  xsd:duration
  xsd:float
  xsd:gDay
  xsd:gMonth
  xsd:gMonthDay
  xsd:gYear
  xsd:gYearMonth
  xsd:hexBinary
  xsd:int
  xsd:integer
  xsd:language
  ....


  Bindings:
   Soap11Binding: {http://tempuri.org/}CallSoap
   Soap12Binding: {http://tempuri.org/}CallSoap12

  Service: Call
   Port: CallSoap (Soap11Binding: {http://tempuri.org/}CallSoap)
   Operations:
      GetJobCards(key: xsd:string, technicianID: xsd:string, 
      jobCardNumber: xsd:string, jobcards: ns0:ArrayOfJobCardsEnt, 
      message: xsd:string) -> GetJobCardsResult: xsd:boolean, 
      jobcards: ns0:ArrayOfJobCardsEnt, message: xsd:string

  ....(some other operations)

One of the calls is to get a list of jobCards with the following schema

<s:element name="GetJobCards">
 <s:complexType>
  <s:sequence>
   <s:element minOccurs="0" maxOccurs="1" name="key" type="s:string"/>
   <s:element minOccurs="0" maxOccurs="1" name="technicianID" type="s:string"/>
   <s:element minOccurs="0" maxOccurs="1" name="jobCardNumber" type="s:string"/>
   <s:element minOccurs="0" maxOccurs="1" name="jobcards" type="tns:ArrayOfJobCardsEnt"/>
   <s:element minOccurs="0" maxOccurs="1" name="message" type="s:string"/>
  </s:sequence>
 </s:complexType>
</s:element>

<s:complexType name="ArrayOfJobCardsEnt">
 <s:sequence>
  <s:element minOccurs="0" maxOccurs="unbounded" name="JobCardsEnt" nillable="true">
   <s:complexType>
    <s:sequence>
     <s:element ref="s:schema"/>
     <s:any/>
    </s:sequence>
   </s:complexType>
  </s:element>
 </s:sequence>
</s:complexType>

When I make the call using Postman I send the following request and it works:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
     <GetJobCards xmlns="http://tempuri.org/">
        <key>some_valid_key</key>
        <technicianID>some_technician_id</technicianID>
        <jobCardNumber></jobCardNumber>
        <jobcards></jobcards>
        <message>""</message>
    </GetJobCards>
</soap:Body>

Please note that the values for "jobCardNumber" and "jobcards" need to be empty to get all the jobCards. But I cannot seem to replicate this same call using the zeep library.

Here is what I have tried.

1 - tried adding xsd.SkipValue for the empty values

request_data = {
  'key': some_valid_key,
  'technicianID': some_technician_ID,
  'jobCardNumber': xsd.SkipValue,
  'jobcards': xsd.SkipValue,
  'message': ''
}
response_body = client.service.GetJobCards(**request_data)

2 - setting the values to Nil

from zeep.xsd import Nil

jobCardEnt = client.get_type('ns0:ArrayOfJobCardsEnt')
jobCardEnt = jobCardEnt()
request_data = {
  'key': some_valid_key,
  'technicianID': some_technician_ID,
  'jobCardNumber': Nil,
  'jobcards': Nil,
  'message': ''
}
response_body = client.service.GetJobCards(**request_data)

None of these seems to works and I'm not sure how to get it to work.

Can someone please guide me on this?

Thanks in advance!

Emad
  • 346
  • 1
  • 6
  • 17
  • Can you share me the result of client.wsdl.dump()? – theone1one Dec 09 '19 at 11:40
  • @theone1one I have edited my question to include the dump – Emad Dec 09 '19 at 12:10
  • Is there global type of "JobCardsEnt" similar to "ns0:ArrayOfJobCardsEnt(JobCardsEnt: {schema: , _value_1: ANY}[])"? – theone1one Dec 09 '19 at 13:35
  • Also, do you list of technicianIDs? If you have, you have to loop over technicianIDs to get the list of jobCardEnt. – theone1one Dec 09 '19 at 13:38
  • @theone1one So no there isnt any global type of "JobCardsEnt" . And no there arent any list of technicianIDs. So I dont understan why postman works fine when I set the `````` to be empty like that I get the results back from the server – Emad Dec 09 '19 at 14:33
  • @theone1one this info might also help...there was another developer that developed the same system in c#/.net and he has a ```public class JobCardsEnt : IXmlSerializable``` with a bunch of attributes defined, and for this same call he just instantiates a list of ```JobCardsEnt``` like ```JobCardsCollection col = new JobCardsCollection()``` and he passes that same empty varaible ```col``` in the ```getJobCards``` call .... I hope I make sense – Emad Dec 09 '19 at 14:38
  • @theone1one thaks for your help, I see you have answered questions on Zeep before and I would appreciate if you could help me cos Im a super noob in SOAP and zeep. I've been stuck on this for the past few days and driving me crazy :( – Emad Dec 09 '19 at 14:40
  • You can get python requests code from postman and can check what is the difference between your request code and postman code. – Tamoor Salah-U-Din Dec 10 '19 at 10:18

1 Answers1

1

Here is how I got it working

with self.client.settings(strict=False):
        response_body = self.client.service.GetJobCards(
            key=some_valid_key,
            technicianID=some_technician_id,
            message=''
        )

And omitted the values for 'jobCardNumber' and 'jobcards'

Emad
  • 346
  • 1
  • 6
  • 17
  • What is strict=False? – theone1one Dec 10 '19 at 17:21
  • @theone1one strict – boolean to indicate if the lxml should be parsed a ‘strict’. If false then the recover mode is enabled which tries to parse invalid XML as best as it can. – Emad Dec 11 '19 at 08:56