cackharot / suds-py3

Mirror of http://svn.fedorahosted.org/svn/suds/trunk/ supporting Python3
GNU Lesser General Public License v3.0
132 stars 63 forks source link

How to pass XML string to SOAP call using Suds for Python3 #52

Open gcobr opened 4 years ago

gcobr commented 4 years ago

Using suds-py3.

When loading the following WSDL:

https://clientdev.inteflow.com.au/inteport/DecisionGateway.asmx?WSDL

I get:

(DecisionWebGatewaySoap12)
         Methods (38):
            [...]
            ExecuteXMLRequest(_sRequestXML _sRequestXML, )

The types list contains all this, but nothing called _sRequestXML (which should be treated as a string, I reckon):

   Types (141):
      AccessGroup
      Address
      ns3:AddressInformation
      Applicant
      ns2:Array
      ArrayOfAccessGroup
      ArrayOfApplicant
      ns3:ArrayOfAttachment
      ArrayOfCriteria
      ns3:ArrayOfCustomField
      ns3:ArrayOfDocumentPDF
      ns3:ArrayOfDocumentStatus
      ns3:ArrayOfFormDataXfdfField
      ArrayOfMerchantCommission
      ArrayOfMerchantOperator
      ArrayOfMerchantParameter
      ArrayOfMerchantProductGroup
      ArrayOfMerchantProductv2
      ArrayOfOperatorAccessGroup
      ArrayOfOperatorMerchant
      ArrayOfOperatorProductGroup
      ns3:ArrayOfRecipientStatus
      ArrayOfString
      ns3:ArrayOfString
      ns3:ArrayOfTabStatus
      ArrayOfURL
      ns3:Attachment
      Authentication
      ns3:AuthenticationStatus
      BasicInsuranceProduct
      BasicMerchant
      BasicMerchantOperator
      BasicOperator
      CompanyDetails
      Contact
      CreateInsuranceProductResponseData
      CreateMerchantResponseData
      Criteria
      ns3:CustomField
      ns3:CustomFieldType
      ns3:CustomTabType
      ns3:DOBInformation
      DateFormat
      DefaultValue
      ns3:DeliveryMethod
      ns3:DocuSignEnvelopeInformation
      ns3:DocumentPDF
      ns3:DocumentStatus
      ns3:DocumentType
      ns2:ENTITIES
      ns2:ENTITY
      ns3:EnvelopeStatus
      ns3:EnvelopeStatusCode
      ns3:EventResult
      ns3:EventStatusCode
      ExecuteResponse
      FinanceRequest
      Financial
      ns3:FormData
      ns3:FormDataXfdf
      ns3:FormDataXfdfField
      ns2:ID
      ns3:IDCheckInformation
      ns2:IDREF
      ns2:IDREFS
      IndividualDetails
      LimitedLoginResponseData
      Merchant
      MerchantCommission
      MerchantDetails
      MerchantOperator
      MerchantParameter
      MerchantProductGroup
      MerchantProductv2
      ns2:NCName
      ns2:NMTOKEN
      ns2:NMTOKENS
      ns2:NOTATION
      ns2:Name
      Operator
      OperatorAccessGroup
      OperatorDetails
      OperatorFlag
      OperatorMerchant
      OperatorProductGroup
      Options
      Payload
      PayloadSubmit
      ns2:QName
      ns3:RecipientStatus
      ns3:RecipientStatusCode
      ns3:RecipientStatusEsignAgreementInformation
      ns3:RecipientTypeCode
      RequestData
      RequestResponseData
      ResponseData
      ns3:SSN4Information
      SecondaryLogin
      ns3:SigningLocationCode
      StatusCheck
      ns1:StringArray
      ns2:Struct
      ns3:TabStatus
      ns3:TabTypeCode
      URL
      ns3:VaultingDetails
      ns2:anyURI
      ns2:arrayCoordinate
      ns2:base64
      ns2:base64Binary
      ns2:boolean
      ns2:byte
      ns2:date
      ns2:dateTime
      ns2:decimal
      ns2:double
      ns2:duration
      ns2:float
      ns2:gDay
      ns2:gMonth
      ns2:gMonthDay
      ns2:gYear
      ns2:gYearMonth
      ns2:hexBinary
      ns2:int
      ns2:integer
      ns2:language
      ns2:long
      ns2:negativeInteger
      ns2:nonNegativeInteger
      ns2:nonPositiveInteger
      ns2:normalizedString
      ns2:positiveInteger
      ns2:short
      ns2:string
      ns2:time
      ns2:token
      ns2:unsignedByte
      ns2:unsignedInt
      ns2:unsignedLong
      ns2:unsignedShort

Then, when I do:

v = client.service.ExecuteXMLRequest("<inteflow><something>value</something></inteflow>")

The SOAP string I passed to ExecuteXMLRequest is not set as the value of ns1:ExecuteXMLRequest. Instead, the element is empty:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://decisionintellect.com/inteport/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:ExecuteXMLRequest/>
   </ns0:Body>
</SOAP-ENV:Envelope>

I need Suds to produce an envelope like this instead:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://decisionintellect.com/inteport/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:ExecuteXMLRequest>
            <ns1:_sRequestXML>
                  <inteflow><something>value</something></inteflow>
            </ns1:_sRequestXML>
      </ns1:ExecuteXMLRequest>
   </ns0:Body>
</SOAP-ENV:Envelope>

Is there a problem with the WSDL? Should I pass the parameter in some other way?

Full example:

import ssl

from suds.client import Client

if hasattr(ssl, '_create_unverified_context'):
    ssl._create_default_https_context = ssl._create_unverified_context

url = 'https://clientdev.inteflow.com.au/inteport/DecisionGateway.asmx?WSDL'
client = Client(url)
client.set_options(port='DecisionWebGatewaySoap12')

print(client)

v = client.service.ExecuteXMLRequest("<inteflow><something>value</something></inteflow>")
print(client.last_sent())

print(v)
andreabisello commented 4 years ago

if you need to call a method not listed in the client , consider using requests.post sending raw xml to the endpoint. i used sometime when client is not able to understand how the schema works. you need to add the SOAPAction method, so i suggest you to add the wsdl to the SOAPUI client, make the call works and then copy-paste the generated call.

this is only a workaround but working with soap is so buggy that sometime you will need to do it.