views:

240

answers:

3

Hi,

I am trying to talk to a SOAP web service using SUDS and Python. After lots of messing around learning Python (yes I am new to this) and working out how to use SUDS I have come across a problem.

The signature of the web method I am calling, according to suds, is

(FWTCaseCreate){
ClassificationEventCode = None
Priority = None
Title = None
Description = None
Queue = None
DueDate = None
AssociatedObject = 
  (FWTObjectBriefDetails){
     ObjectID = 
        (FWTObjectID){
           ObjectType = None
           ObjectReference[] = <empty>
        }
     ObjectDescription = None
     Details = None
     Category = None
  }
Form = 
  (FWTCaseForm){
     FormField[] = <empty>
     FormName = None
     FormKey = None
  }
Internal = None
InteractionID = None
XCoord = None
YCoord = None
}

So I use SUDS to create the classes that I want and send it to the method. However I get an error. So I turned logging on and I can see that the XML that is being sent is not correct which is causing a deserialize error. The SOAP package looks like the following

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://www.CRM.com/wsdl/FLTypes"    xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
<SOAP-ENV:Header>
   <wsse:Security>
      <wsse:BinarySecurityToken>eaadf1ddff99a8</wsse:BinarySecurityToken>
   </wsse:Security>
</SOAP-ENV:Header>
<ns1:Body>
   <ns0:FWTCaseCreate>
      <ClassificationEventCode>
         <ClassificationEventCode>2000023</ClassificationEventCode>
         <Priority>1</Priority>
         <Title>testing</Title>
         <Description>testing</Description>
         <Queue/>
         <Internal>True</Internal>
         <XCoord>356570</XCoord>
         <YCoord>168708</YCoord>
      </ClassificationEventCode>
   </ns0:FWTCaseCreate>
</ns1:Body>

As you can see there is a 'ClassificationEventCode' element around all the other elements, this should not be there. If I cut and paste this xml into SOAPUI and first remove this element and then post it directly to the web service it works successfully.

Here is the code I am using to make the call

client = Client(url)

#Add a header for the security
ssnns = ('wsse', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd')

ssn = Element('BinarySecurityToken', ns=ssnns).setText(binaryKey)

ssn1 = Element('Security',ns=ssnns)

ssn1.append(ssn)

client.set_options(soapheaders=ssn1) 

newCase = client.factory.create('ns1:FWTCaseCreate')

classEventCode = client.factory.create('ns1:FWTEventCode')
classEventCode.value = 2000023

newCase.ClassificationEventCode = classEventCode
newCase.Priority = 1
#optional
newCase.AssociatedObject = None
#optional
newCase.Form = None
#optional
newCase.Internal = None
#optional
newCase.InteractionID =  None
#optional
newCase.DueDate = None
#optional
newCase.Queue = None

newCase.Title = 'Title'

newCase.Description = 'description'

newCase.XCoord = '356570'

newCase.YCoord = '168708'

caseID = client.service.createCase(newCase)

Does anyone have any ideas why this is happening? I guess SUDS thinks that it should be there based on the WSDL.

Thanks.

A: 

Are you going to be using this as a config file, or to store infomation. Or is this to send data across the web?

Okay then, if this is so then why not use json or json-rpc, they are said to be much faster, easier to parse and far easier to read. XML is a horible data type and I personally can't wait till it dies, if your looking for data sending it would be well worth using the json's.

Taos
This is to send data across the web.
The Abbott of Monkseaton
I agree that XML is horrible, but the SOAP web service is provided by a third party vendor and as such I have not control over how they implement the interface into their product. How can I use the JSON-rpc to call a SOAP web service?
The Abbott of Monkseaton
What does your program need to do and what is the third party vendor, if your third party vendor supports soap, it will support probably support json.
Taos
I'm afraid that it does not support JSON, so SOAP is the only supported way to interface with it.
The Abbott of Monkseaton
A: 

Your creating the element twice. Remove this:

classEventCode = client.factory.create('ns1:FWTEventCode') 
classEventCode.value = 2000023 

And change this:

newcase.ClassificationEventCode = 2000023

This should remove that extra tag.

chrissygormley
This does not make any difference. The command classEventCode = client.factory.create('ns1:FWTEventCode') is simply creating a new object based on the wsdl I then assign it to the object that I am passing to the web method.But this is not adding it twice.Thanks for the suggestion.
The Abbott of Monkseaton
@Abbott -- I have nothing to test this agianst, but read this document http://jortel.fedorapeople.org/suds/doc/suds.sax.element.Element-class.html, the detach option maybe useful. Not sure though, you may have already read this.
chrissygormley
A: 

I'm was getting exactly the same problem. The sequence of parameters in my SOAP request is being wrapped in an element with the same name as the first parameter. e.g.

....
   <ns0:Body>
      <ns1:CreationReq>
         <ReqType>
            <ReqType>1</ReqType>
            <Title>Mr</Title>
            ....
         </ReqType>
      </ns1:CreationReq>
   </ns0:Body>
....

I've checked the WSDL over to make sure there is no problem with it.

The problem it seems is because I created a CreationReq object using the client.factory.create method. Checking the client by printing it shows that the method I am calling does not take that object as a parameter. Rather it takes a list of named args.

So my code was:

req = client.factory.create('CreationReq')
req.ReqType = 1
req.Title = 'Mr'
resp = client.service.Create(req)

Now it is:

req = {}
req['ReqType'] = 1
req['Title'] = 'Mr'
resp = client.service.Create(**req)
Robin Elvin