开发者

how to use wsdl2py generated complex types to send responses from web service in python

I'm using ZSI 2.1 and working from a wsdl file that spe开发者_C百科cifies a 'postAppStatusResponse' message of type 'appStatusResponse', which is defined as:

<xsd:complexType name="appStatusResponse">
    <xsd:sequence>
        <xsd:element name="response" type="tns:webServiceResponse" minOccurs="1" maxOccurs="1" />
    </xsd:sequence>
</xsd:complexType>

and "webServiceResponse" appears as follows:

<xsd:complexType name="webServiceResponse">
    <xsd:sequence>
        <xsd:element name="responseCode" type="xsd:long"/>
        <xsd:element name="responseMessage" type="xsd:string"/>
        <xsd:element name="exceptionCode" type="xsd:long"/>
        <xsd:element name="exceptionMessage" type="xsd:string" nillable="true" />
        <xsd:element name="transactionIdentifier" type="xsd:long"/>
        <xsd:element name="traceIdentifier" type="xsd:string"/>
        <xsd:element name="transactionTimestamp" type="xsd:dateTime" nillable="true" />
    </xsd:sequence>
</xsd:complexType>

To send the postAppStatusResponse message, I evidently need to populate it with the webServiceResponse and appStatusResponse structures. However, the class generated for the postAppStatusResponse message contains nothing to support this. The wsdl2py-generated types file includes appStatusResponse_Def and webServiceResponse_Def classes, but I've been unable to figure out how to use these to generate what I need.

The generated postAppStatusResponse message looks like this:

_postAppStatusResponseTypecode = Struct(pname=("http://cig.jpmchase.net/20110218/card/acq/","postAppStatusResponse"), ofwhat=[ns0.appStatusResponse_Def(pname="postAppStatusResponse", aname="_postAppStatusResponse", typed=False, encoded=None, minOccurs=1, maxOccurs=1, nillable=True)], pyclass=None, encoded="http://cig.jpmchase.net/20110218/card/acq/")
class postAppStatusResponse:
    typecode = _postAppStatusResponseTypecode
    __metaclass__ = pyclass_type
    def __init__(self, **kw):
        """Keyword parameters:
        postAppStatusResponse -- part postAppStatusResponse
        """
        self._postAppStatusResponse =  kw.get("postAppStatusResponse")
postAppStatusResponse.typecode.pyclass = postAppStatusResponse

The dir() of postAppStatusResponse is:

['PostAppStatusResponse', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_postAppStatusResponse', 'get_element_postAppStatusResponse', 'new_postAppStatusResponse', 'set_element_postAppStatusResponse', 'typecode']

and the dir() of postAppStatusResponse._postAppStatusResponse is:

['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

I generated the files using "wsdl2py --complexType", and have been able to use the included "get_element_..." functions to extract the request message data without any trouble. I have also written other ZSI web services that return simpler messages without any trouble. But this one... I have tried many many different approaches to sending this message, and have not found one that works.

Surely ZSI exists to make this sort of thing simpler? Can anyone help me with whatever I'm missing here? (I've tried to spare you the extraneous data from long xml files and code listings, but of course can supply them on request.)


I might have some code to help you out. I was working with a similar issue in trying to generate python code from a WSDL and contact an Outlook OMS SMS Gateway. Messages that reference complex types will get a new_complexType constructor that you should call. However, if the WSDL doesn't reference it for some reason, like it get serialized as a string in an call, it won't auto-generate the new constructors. The complex type can still be instantiated. Check the following code example, full source at Phonero SMS:

import sys
import uuid
from OMSService_client import *

loc = OMSServiceLocator()
kw = { 'tracefile' : sys.stdout }
port = loc.getOMSServiceSoap(**kw)

deliverXmsMsg = DeliverXmsSoapIn()

xmsData = ns0.xmsData_Dec().pyclass()
xmsData.set_attribute_client('Python SMS Client 1.0')

user = xmsData.new_user()
user.UserId = ''
user.Password = ''
user.ReplyPhone = ''
user.CustomData = ''
xmsData.User = user

xmsHead = xmsData.new_xmsHead()
xmsHead.To = xmsHead.new_to()
xmsHead.To.Recipient = ['']
xmsHead.SourceType = 'other'
xmsHead.RequiredService = xmsHead.new_requiredService('SMS_SENDER')
xmsData.XmsHead = xmsHead

xmsBody = xmsData.new_xmsBody()
xmsBody.set_attribute_format('SMS')
content = xmsBody.new_content('Hello, World!')
content.set_attribute_contentType('text/plain')
content.set_attribute_contentId(str(uuid.uuid4()))
content.set_attribute_contentLocation('1.txt')
xmsBody.Content.append(content)
xmsData.XmsBody = xmsBody

writer = ZSI.SoapWriter(envelope=0)
deliverXmsMsg.XmsData = writer.serialize(xmsData)

rsp = port.DeliverXms(deliverXmsMsg)

So as you can see on this line you can I construct an xmsData Holder this way:

xmsData = ns0.xmsData_Dec().pyclass()


I think I've got it; it was 'simply' a matter of creating a Python class structure matching the response message structure, writing values to the class members, and setting response._postAppStatusResponse = myMsg, where myMsg is the new class structure.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜