Как использовать сгенерированные wsdl2py сложные типы для отправки ответов от веб-службы в Python - PullRequest
1 голос
/ 15 сентября 2011

Я использую ZSI 2.1 и работаю из файла wsdl, в котором указано сообщение «postAppStatusResponse» типа «appStatusResponse», которое определяется как:

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

и «webServiceResponse» выглядит следующим образом:

<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>

Чтобы отправить сообщение postAppStatusResponse, мне, очевидно, нужно заполнить его структурами webServiceResponse и appStatusResponse. Тем не менее, класс, созданный для сообщения postAppStatusResponse, не содержит ничего, чтобы поддержать это. Файл сгенерированных wsdl2py типов включает в себя классы appStatusResponse_Def и webServiceResponse_Def, но я не смог понять, как их использовать для генерации того, что мне нужно.

Сгенерированное сообщение postAppStatusResponse выглядит так:

_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

dir () для postAppStatusResponse:

['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']

и dir () для postAppStatusResponse._postAppStatusResponse:

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

Я сгенерировал файлы, используя "wsdl2py --complexType", и смог использовать включенные функции "get_element _..." для извлечения данных сообщения запроса без каких-либо проблем. Я также написал другие веб-сервисы ZSI, которые без проблем возвращают более простые сообщения. Но этот ... Я перепробовал много разных подходов к отправке этого сообщения и не нашел того, который работает.

Конечно, ZSI существует, чтобы упростить подобные вещи? Может ли кто-нибудь помочь мне с тем, что мне здесь не хватает? (Я пытался избавить вас от лишних данных из длинных XML-файлов и списков кодов, но, конечно, могу предоставить их по запросу.)

Ответы [ 2 ]

1 голос
/ 12 февраля 2013

У меня может быть какой-то код, чтобы помочь вам. Я работал с аналогичной проблемой, пытаясь сгенерировать код Python из WSDL и связаться с шлюзом Outlook OMS SMS. Сообщения, которые ссылаются на сложные типы, получат конструктор new_complexType, который вы должны вызвать. Однако, если WSDL по какой-то причине не ссылается на него, как, например, он сериализуется как строка в вызове, он не будет автоматически генерировать новые конструкторы. Сложный тип все еще может быть создан. Проверьте следующий пример кода, полный исходный код на 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)

Итак, как вы можете видеть в этой строке, вы можете создать держатель xmsData следующим образом:

xmsData = ns0.xmsData_Dec().pyclass()
0 голосов
/ 15 сентября 2011

Я думаю, что у меня это есть;это был просто вопрос создания структуры класса Python, соответствующей структуре ответного сообщения, записи значений в члены класса и установки response._postAppStatusResponse = myMsg, где myMsg - новая структура класса.

...