Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML SOAP POST error, what am I doing wrong?

So I am trying to do an API call via a XML SOAP POST the error I am getting is: "Object reference not set to an instance of an object"

site = 'https://webservices.autotask.net/atservices/1.5/atws.asmx'
data = """<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <queryxml>
      <entity>contact</entity>
        <query>
          <field>firstname<expression op="equals">George</expression>
          </field>
        </query>
    </queryxml>
  </soap:Body>
</soap:Envelope>"""

headers = {
    'Content-Type': 'application/soap+xml; charset=utf-8',
    'Host': 'webservices.autotask.net',
    'Content-Type': 'text/xml; charset=utf-8',
    'Content-Length': len(data),
    'SOAPAction': "http://autotask.net/ATWS/v1_5/query"
    } 
site = 'https://webservices.autotask.net/atservices/1.5/atws.asmx'
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='webservices.autotask.net',
                          uri=site,
                          user='user,
                          passwd='pw')
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
page = urllib2.urlopen(site)
print(data)
req = urllib2.Request(site, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
print(the_page)

The auth works and I have done succesfull calls with this code, the only thing that is diffrent now is the data XML SOAP POST. I will try suds.

No Traceback only web server error:

Print out of the XML SOAP POST that I am sending:

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <queryxml> <entity>contact</entity> <query> <field>firstname<expression op="equals">George</expression> </field> </query> </queryxml> </soap:Body> </soap:Envelope>

The response:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><queryResponse xmlns="http://autotask.net/ATWS/v1_5/"><queryResult><ReturnCode>-1</ReturnCode><EntityResults /><EntityResultType /><Errors><ATWSError><Message>Object reference not set to an instance of an object.</Message></ATWSError><ATWSError><Message>Error reading in Query XML.</Message></ATWSError></Errors><EntityReturnInfoResults /></queryResult></queryResponse></soap:Body></soap:Envelope>

Any ideas?

George

like image 267
George Avatar asked Feb 24 '23 21:02

George


2 Answers

Autotask has an ancient API on IIS 6... to deal with the microsoft crapstack you have to escape the XML you push over there as CDATA. Here's what worked for me as the soap body, within the

<ins0:query> 

tags:

<ins0:sXML>
<![CDATA[<queryxml>
<entity>contact</entity>
<query>
<field>phone<expression op='equals'>#{phone}</expression></field>
</query>
</queryxml>]]>
</ins0:sXML>
like image 119
Eskim0 Avatar answered Feb 27 '23 15:02

Eskim0


George, here is an example of calling one of the test web services on webservicex.net:

import suds
url = 'http://www.webservicex.net/stockquote.asmx?WSDL'
client = suds.client.Client(url=url)
print client.service.GetQuote('IBM')

<StockQuotes>
  <Stock>
     <Symbol>IBM</Symbol>
     <Last>159.93</Last><Date>3/7/2011</Date><Time>4:00pm</Time>
     <Change>-1.90</Change><Open>161.60</Open><High>162.98</High>
     <Low>158.85</Low><Volume>5318064</Volume>
     <MktCap>195.0B</MktCap><PreviousClose>161.83</PreviousClose>
     <PercentageChange>-1.17%</PercentageChange>
     <AnnRange>116.00 - 166.25</AnnRange>
     <Earns>11.52</Earns><P-E>14.05</P-E>
     <Name>International Bus</Name>
  </Stock>
</StockQuotes>

You should be able to do HTTP basic authentication by passing in username and password on the constructor:

client = suds.client.Client(url=url, username='user', password='pw')

Good luck with suds!

like image 39
samplebias Avatar answered Feb 27 '23 14:02

samplebias