1
votes

I am using python 2.7 with zeep as SOAP Client to retrieve some information. I noticed that the response of client.service.ServiceName returns a python data structure, e.i a list, but its items are not a python data structure instead, these are lxml.etree._Element. Could you please tell me if there is a way to make zeep return nested python dictionaries as opposed to xml.

Here is the code:

# python 2.7
import zeep
from lxml import etree
print zeep.__version__    # '0.23.0'
history = zeep.plugins.HistoryPlugin()
client = zeep.Client(wsdl=wsdl, 
                     wsse=UsernameToken(username, password), 
                     plugins=[history])
projectId, cardUniqueId, cardType, userLoginId = ('3', '111', 'XXX', 'myuser')
cards = client.service.getCard(projectId, cardUniqueId, cardType, userLoginId)
print(type(cards))   # <type 'list'>
print(cards)         # [<Element {http://kanbancard.webservices.kanban.app.digite.com/}fields at 0x7f706d69e640>]
print(type(cards[0]))    # <type 'lxml.etree._Element'>

Response of client.service.getCard is:

print(etree.tounicode(history.last_received['envelope'], pretty_print=True))

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <ns:getCardResponse xmlns:ns="http://kanbancard.webservices.kanban.app.digite.com/">
      <ns:fields>
        <ns:field ns:name="cardNumber">XYZ</ns:field>
        <ns:field ns:name="name">foobar</ns:field>
        <ns:field ns:name="description">foobar</ns:field>
        <ns:field ns:name="priority">High</ns:field>
        <ns:field ns:name="classOfService">Standard Class</ns:field>
        <ns:field ns:name="cardSize">1</ns:field>
        <ns:field ns:name="dateIdentified">2017-01-19T04:07:53Z</ns:field>
        <ns:field ns:name="ExternalCardId">XYZ</ns:field>
        <ns:field ns:name="currentSwimId">1632088</ns:field>
        <ns:field ns:name="currentQueueId">2322634</ns:field>
      </ns:fields>
    </ns:getCardResponse>
  </soapenv:Body>
</soapenv:Envelope>

WSLD:

<wsdl:operation name="getCard">
  <wsdl:input message="axis2:getCardRequestMessage">
</wsdl:input>
  <wsdl:output message="axis2:getCardResponseMessage">
</wsdl:output>
</wsdl:operation>
        <xs:element name="getCardRequest">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="projectId" nillable="false" type="xs:string"/>
                    <xs:element name="cardUniqueId" nillable="false" type="xs:string"/>
                    <xs:element name="cardType" nillable="false" type="xs:string"/>
                    <xs:element name="userLoginId" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:element name="getCardResponse">
            <xs:complexType>
                <xs:sequence>
                    <xs:any maxOccurs="unbounded" minOccurs="0"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
  <wsdl:message name="getCardResponseMessage">
    <wsdl:part name="part1" element="axis2:getCardResponse">
  </wsdl:part>
  <wsdl:message name="getCardRequestMessage">
    <wsdl:part name="part1" element="axis2:getCardRequest">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getCardResponseMessage">
    <wsdl:part name="part1" element="axis2:getCardResponse">
    </wsdl:part>
  </wsdl:message>
1
Have you found any solution for this? I'm struggling with the same issue. - Oliver

1 Answers

0
votes

In short zeep doesn't understand this schema, so it just returns xml

Best way is to use history

https://github.com/mvantellingen/python-zeep/issues/311