SOAPpy: Expected to find node type 'Element' with name 'CountriesFetchingRequest'; Found node type 'Element' with name 'FetchCountries'

ldanielburr at gmail.com ldanielburr at gmail.com
Tue Sep 23 21:47:02 CEST 2014


On Sunday, September 21, 2014 9:31:46 PM UTC-5, vek.... at gmail.com wrote:
> I'm messing with SOAP, trying to write a small library to handle stuff I buy from Aramex (shipper). I'm learning XML/SOAP and I'm familiar with RPC from C (Stevens) but no other relevant experience. If this is incredibly dumb just ignore it since I'll probably figure it out eventually.
> 
> 
> 
> I'm trying to get a list of countries by calling the CoutriesFetchingRequest method - this is documented here:
> 
> http://www.aramex.com/developers/aramex-apis/47442/Location-Services-API
> 
> http://www.aramex.com/content/uploads/109/232/46790/aramex-location-api-manual.pdf
> 
> 
> 
> It takes as its arguments a 'ClientInfo' data-structure and 'Code' which is a string.
> 
> 
> 
> There is also a 'FetchCountries' method with an 'input' and 'output' something.
> 
> However python was more clear, print server.show_methods():
> 
> 
> 
> Method Name: FetchCountries 
> 
>    In #0: parameters  ((u'http://ws.aramex.net/ShippingAPI/v1/', u'CountriesFetchingRequest'))
> 
> <SNIP>
> 
> 
> 
> The trouble is I don't understand how to call 'CoutriesFetchingRequest' or pass it to FetchCountries. Could someone clarify?
> 
> 
> 
> 
> 
> The WSDL for Aramex has this:
> 
> http://www.aramex.com/content/uploads/109/232/46790/location-api-wsdl.zip
> 
>     <wsdl:operation name="FetchCountries">
> 
>       <wsdl:input wsaw:Action="http://ws.aramex.net/ShippingAPI/v1/Service_1_0/FetchCountries" name="CountriesFetchingRequest" message="tns:CountriesFetchingRequest" />
> 
>       <wsdl:output wsaw:Action="http://ws.aramex.net/ShippingAPI/v1/Service_1_0/FetchCountriesResponse" name="CountriesFetchingResponse" message="tns:CountriesFetchingResponse" />
> 
>     </wsdl:operation>
> 
> 
> 
> 
> 
>       <wsdl:input name="CountriesFetchingRequest">
> 
>         <soap:body use="literal" />
> 
>       </wsdl:input>
> 
> 
> 
> My python code:
> 
> #!/usr/bin/python
> 
> import xml, fpconst, logging
> 
> from SOAPpy import WSDL
> 
> from suds.client import Client
> 
> 
> 
> logging.basicConfig(level=logging.INFO)
> 
> logging.getLogger('suds.client').setLevel(logging.DEBUG)
> 
> 
> 
> foo = { 'AccountCountryCode' : 'JO', 'AccountEntity' : 'AMM', 'AccountNumber' : '20016', 'AccountPin' : '331421', 'UserName' : 'testingxxx at aramex.com', 'Password' : 'R123456789$r', 'Version' : 'v1.0', 'Source' : '', 'Transaction' :  { 'Reference1' : '001', 'Reference2' : '002', 'Reference3' : '003', 'Reference4' : '004', 'Reference5' : '005' } }
> 
> 
> 
> wsdl_file = '/home/veek/location-api-wsdl/Location-API-WSDL.wsdl'
> 
> 
> 
> server = WSDL.Proxy(wsdl_file)
> 
> print server.methods.keys()
> 
> print dir(server)
> 
> print server.show_methods()
> 
> callInfo = server.methods['FetchCountries']
> 
> print type(callInfo)
> 
> print dir(callInfo)
> 
> 
> 
> for arg in callInfo.inparams:
> 
>     print arg.name.ljust(15), arg.type
> 
> server.namespace = 'http://ws.aramex.net/ShippingAPI/v1/'
> 
> x = server.FetchCountries.CountriesFetchingRequest(foo)
> 
> 
> 
> The output i get is:
> 
> [u'FetchCountries', u'FetchCountry', u'ValidateAddress', u'FetchCities', u'FetchOffices']
> 
> ['__doc__', '__getattr__', '__init__', '__module__', '__str__', 'methods', 'show_methods', 'soapproxy', 'wsdl']
> 
> Method Name: FetchCountries 
> 
> 
> 
>    In #0: parameters  ((u'http://ws.aramex.net/ShippingAPI/v1/', u'CountriesFetchingRequest'))
> 
> 
> 
>    Out #0: parameters  ((u'http://ws.aramex.net/ShippingAPI/v1/', u'CountriesFetchingResponse'))
> 
> 
> 
> <SNIP>
> 
> 
> 
> None
> 
> <type 'instance'>
> 
> ['__doc__', '__init__', '__module__', 'addInHeaderInfo', 'addInParameter', 'addOutHeaderInfo', 'addOutParameter', 'documentation', 'encodingStyle', 'getInHeaders', 'getInParameters', 'getOutHeaders', 'getOutParameters', 'getReturnParameter', 'inheaders', 'inparams', 'location', 'methodName', 'namespace', 'outheaders', 'outparams', 'retval', 'setReturnParameter', 'soapAction', 'style', 'transport', 'use']
> 
> parameters      (u'http://ws.aramex.net/ShippingAPI/v1/', u'CountriesFetchingRequest')
> 
> 
> 
> <SNIP>
> 
> 
> 
> SOAPpy.Types.faultType: <Fault a:InternalServiceFault: Error in deserializing body of request message for operation 'FetchCountries'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'CountriesFetchingRequest' and namespace 'http://ws.aramex.net/ShippingAPI/v1/'. Found node type 'Element' with name 'FetchCountries.CountriesFetchingRequest' and namespace '': 
> 
> <SNIP>

Give pysimplesoap a try; you can point it at the wsdl endpoint, and it will provide you a client that lets you call methods in about as obvious a manner as you can reasonably hope for, given the mess that is SOAP.

See https://code.google.com/p/pysimplesoap/wiki/SoapClient for some examples.



More information about the Python-list mailing list