pythonweb-servicessoapsuds

Trying to Parse SOAP Response in Python


I'm struggling to find a way to parse the data that I'm getting back from a SOAP response. I'm only familiar with Python (v3.4), but relatively new to it. I'm using suds-jurko to pull the data from a 3rd party SOAP server. The response comes back in the form of "ArrayOfXmlNode". I've tried using ElementTree in different ways to parse the data, but I either get no information or I get "TypeError: invalid file: (ArrayOfXmlNode)" errors. Googling how to handle the ArrayOfXMLNode type response has gotten me nowhere.

The first part of the SOAP response is:

(ArrayOfXmlNode){
   XmlNode[] = 
      (XmlNode){
         Hl = 
            (Hl){
               ID = "22437790"
               Name = "Cameron"
               SpeciesID = "1"
               Sex = "Male"
               PrimaryBreed = "German Shepherd"
               SecondaryBreed = "Mix"
               SN = ""
               Age = "35"
               OnHold = "No"
               Location = "Foster Home"
               BehaviorResult = ""
               Photo = "http://sms.petpoint.com/sms/photos/615/123.jpg"
            }
      },

I've tried iterating through the data with code similar to:

from suds.client import Client
url = 'http://qag.petpoint.com/webservices/AdoptableSearch.asmx?WSDL'
client = Client(url)


result = client.service.adoptableSearchExtended('nunya', 0, 'A', 'All', 'N')

tree = result[0]

for node in tree:
    pet_info = []
    pet_info.extend(node)    

print(pet_info)

The code above gives me the entire response in "result[0]". Below that I try to create a list from the data, but only get very last node (node being 1 set of information from ID to Photo). Attempts to modify this approach gives me either everything, nothing, or only the last node.

So then I tried to make use of ElementTree with simple code to test it out, but only get the "invalid file" errors.

import xml.etree.ElementTree as ET

from suds.client import Client
url = 'http://qag.petpoint.com/webservices/AdoptableSearch.asmx?WSDL'
client = Client(url)


result = client.service.adoptableSearchExtended('nunya', 0, 'A', 'All', 'N')

pet_info = ET.parse(result)
print(pet_info)

The result:

Traceback (most recent call last):
  File "D:\Python\Eclipse Workspace\KivyTest\src\root\nested\Parse.py", line 11, in <module>
    pet_info = ET.parse(result)
  File "D:\Programs\Python34\lib\xml\etree\ElementTree.py", line 1186, in parse
    tree.parse(source, parser)
  File "D:\Programs\Python34\lib\xml\etree\ElementTree.py", line 587, in parse
    source = open(source, "rb")
TypeError: invalid file: (ArrayOfXmlNode){
   XmlNode[] = 
      (XmlNode){
         Hl = 
            (Hl){
               ID = "20840097"
               Name = "Daisy"
               SpeciesID = "1"
               Sex = "Female"
               PrimaryBreed = "Terrier, Pit Bull"
               SecondaryBreed = ""
               SN = ""
               Age = "42"
               OnHold = "No"
               Location = "Dog Adoption"
               BehaviorResult = ""
               Photo = "http://sms.petpoint.com/sms/photos/615/40f428de-c015-4334-9101-89c707383817.jpg"
            }
      },

Can someone get me pointed in the right direction?


Solution

  • I had a similar problem parsing data from a web service using Python 3.4 and suds-jurko. I was able to solve the issue using the code in this post, https://stackoverflow.com/a/34844428/5874347. I used the fastest_object_to_dict function to convert the web service response into a dictionary. From there you can parse the data ...

    1. Add the fastest_object_to_dict function to the top of your file
    2. Make your web service call
    3. Create a new variable to save the dictionary response to

      result = client.service.adoptableSearchExtended('nunya', 0, 'A', 'All', 'N') 
      ParsedResponse = fastest_object_to_dict(result)
      

    4. Your data will now be in the form of a dictionary, you can parse the dictionary on the python side as needed or send it back to your ajax call via json, and parse it with javascript. To send it back as json

      import json
      import sys
      sys.stdout.write("content-type: text/json\r\n\r\n") 
      sys.stdout.write(json.dumps(ParsedReponse))