【问题标题】:Are there any working examples of Zolera SOAP Infrastructure (ZSI)? [closed]有没有 Zolera SOAP Infrastructure (ZSI) 的工作示例? [关闭]
【发布时间】:2011-10-17 16:05:19
【问题描述】:

我看过例子:

  1. http://pywebsvcs.svn.sourceforge.net/viewvc/pywebsvcs/trunk/wstools/
  2. http://pywebsvcs.sourceforge.net/cookbook.pdf

并用谷歌搜索,但找不到一个可用的示例。

【问题讨论】:

    标签: python soap zsi


    【解决方案1】:

    参考:(感谢 Doug Hellmann)building soap service

    Zolera Soap Infrastucture (ZSI) 是 pywebsvcs 项目的一部分。它为使用 SOAP 提供了完整的服务器和客户端库。为了使用它,开发人员编写 WSDL 文件(手动或使用 WSDL 编辑器),然后为客户端生成 Python 源代码和为服务器生成存根。 WSDL 文件中定义的数据结构被转换成 Python 类,可以在客户端和服务器代码中使用。

    我们实现了一个简单的回显服务,它将从客户端获得的任何输入都作为输出返回。清单 1 包含此服务的 ZSI 版本的手工制作的 WSDL 输入。

    清单 1

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions 
      xmlns="http://schemas.xmlsoap.org/wsdl/"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:tns="urn:ZSI"
      targetNamespace="urn:ZSI" >
    
      <types>
        <xsd:schema elementFormDefault="qualified" 
            targetNamespace="urn:ZSI">
          <xsd:element name="Echo">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:anyType"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:schema>
      </types>
    
      <message name="EchoRequest">
        <part name="parameters" element="tns:Echo" />
      </message>
      <message name="EchoResponse">
        <part name="parameters" element="tns:Echo"/>
      </message>
    
      <portType name="EchoServer">
        <operation name="Echo">
          <input message="tns:EchoRequest"/>
          <output message="tns:EchoResponse"/>
        </operation>
      </portType>
    
      <binding name="EchoServer" type="tns:EchoServer">
        <soap:binding style="document" 
                      transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="Echo">
          <soap:operation soapAction="Echo"/>
          <input>
            <soap:body use="literal"/> 
          </input>
          <output>
            <soap:body use="literal"/> 
          </output>
        </operation>
      </binding>
    
      <service name="EchoServer">
        <port name="EchoServer" binding="tns:EchoServer">
          <soap:address location="http://localhost:7000"/>
        </port>
      </service>
    
    </definitions>
    

    要从 WSDL 生成客户端和服务器代码,请将其输入 wsdl2py 程序(包含在 ZSI 中)。要添加对复杂类型的支持,请添加 -b 选项,但这个简单示例不需要它。作为响应,wsdl2py 将生成三个文件:

    清单 2

    EchoServer_client.py 是为 SimpleEcho Web 服务构建客户端所需的代码。

    ##################################################
    # file: EchoServer_client.py
    # 
    # client stubs generated by 
    # "ZSI.generate.wsdl2python.WriteServiceModule"
    # 
    ##################################################
    
    from EchoServer_types import *
    import urlparse, types
    from ZSI.TCcompound import ComplexType, Struct
    from ZSI import client
    from ZSI.schema import GED, GTD
    import ZSI
    from ZSI.generate.pyclass import pyclass_type
    
    # Locator
    class EchoServerLocator:
        EchoServer_address = "http://localhost:7000"
        def getEchoServerAddress(self):
            return EchoServerLocator.EchoServer_address
        def getEchoServer(self, url=None, **kw):
            return EchoServerSOAP(
                url or EchoServerLocator.EchoServer_address, 
                **kw)
    
    # Methods
    class EchoServerSOAP:
        def __init__(self, url, **kw):
            kw.setdefault("readerclass", None)
            kw.setdefault("writerclass", None)
            # no resource properties
            self.binding = client.Binding(url=url, **kw)
            # no ws-addressing
    
        # op: Echo
        def Echo(self, request, **kw):
            if isinstance(request, EchoRequest) is False:
                raise TypeError, "%s incorrect request type" % \
                    (request.__class__)
            # no input wsaction
            self.binding.Send(None, None, request, soapaction="Echo", **kw)
            # no output wsaction
            response = self.binding.Receive(EchoResponse.typecode)
            return response
    
    EchoRequest = GED("urn:ZSI", "Echo").pyclass
    
    EchoResponse = GED("urn:ZSI", "Echo").pyclass
    

    清单 3

    EchoServer_server.py 包含构建 SimpleEcho Web 服务服务器所需的代码。

    ##################################################
    # file: EchoServer_server.py
    #
    # skeleton generated by 
    #  "ZSI.generate.wsdl2dispatch.ServiceModuleWriter"
    #
    ##################################################
    
    from ZSI.schema import GED, GTD
    from ZSI.TCcompound import ComplexType, Struct
    from EchoServer_types import *
    from ZSI.ServiceContainer import ServiceSOAPBinding
    
    # Messages  
    EchoRequest = GED("urn:ZSI", "Echo").pyclass
    
    EchoResponse = GED("urn:ZSI", "Echo").pyclass
    
    
    # Service Skeletons
    class EchoServer(ServiceSOAPBinding):
        soapAction = {}
        root = {}
    
        def __init__(self, post='', **kw):
            ServiceSOAPBinding.__init__(self, post)
    
        def soap_Echo(self, ps, **kw):
            request = ps.Parse(EchoRequest.typecode)
            return request,EchoResponse()
    
        soapAction['Echo'] = 'soap_Echo'
        root[(EchoRequest.typecode.nspname,EchoRequest.typecode.pname)] = \
            'soap_Echo'
    

    清单 4

    EchoServer_types.py 包含客户端和服务器代码都使用的类型定义。

    ##################################################
    # file: EchoServer_types.py
    #
    # schema types generated by 
    #  "ZSI.generate.wsdl2python.WriteServiceModule"
    #
    ##################################################
    
    import ZSI
    import ZSI.TCcompound
    from ZSI.schema import (LocalElementDeclaration, ElementDeclaration, 
                            TypeDefinition, GTD, GED)
    from ZSI.generate.pyclass import pyclass_type
    
    ##############################
    # targetNamespace
    # urn:ZSI
    ##############################
    
    class ns0:
        targetNamespace = "urn:ZSI"
    
        class Echo_Dec(ZSI.TCcompound.ComplexType, ElementDeclaration):
            literal = "Echo"
            schema = "urn:ZSI"
            def __init__(self, **kw):
                ns = ns0.Echo_Dec.schema
                TClist = [ZSI.TC.AnyType(pname=(ns,"value"), 
                          aname="_value", minOccurs=1, maxOccurs=1, 
                          nillable=False, typed=False, 
                          encoded=kw.get("encoded"))]
                kw["pname"] = ("urn:ZSI","Echo")
                kw["aname"] = "_Echo"
                self.attribute_typecode_dict = {}
                ZSI.TCcompound.ComplexType.__init__(self,None,TClist,
                                                    inorder=0,**kw)
                class Holder:
                    __metaclass__ = pyclass_type
                    typecode = self
                    def __init__(self):
                        # pyclass
                        self._value = None
                        return
                Holder.__name__ = "Echo_Holder"
                self.pyclass = Holder
    
    # end class ns0 (tns: urn:ZSI)
    

    一旦生成,这些文件就不能被编辑,因为只要 WSDL 输入发生变化,它们就会作为构建过程的一部分重新生成。文件中的代码会随着更多类型和调用添加到服务定义而增长。

    服务器的实现放在一个单独的文件中,用于导入生成的代码。在示例中,实际服务位于清单 5 的第 18-25 行。@soapmethod 装饰器定义了调用的输入(一个 EchoRequest)和输出(一个 EchoResponse)。在示例中,soap_Echo() 的实现只是用请求值填充响应值,并返回请求和响应。从那里,ZSI 负责构建 SOAP 响应并将其发送回客户端。

    清单 5

    import os
    import sys
    from EchoServer_client import *
    from ZSI.twisted.wsgi import (SOAPApplication,
                                  soapmethod,
                                  SOAPHandlerChainFactory)
    
    class EchoService(SOAPApplication):
        factory = SOAPHandlerChainFactory
        wsdl_content = dict(name='Echo', 
                            targetNamespace='urn:echo', 
                            imports=(), 
                            portType='',
                            )
    
        def __call__(self, env, start_response):
            self.env = env
            return SOAPApplication.__call__(self, env, start_response)
    
        @soapmethod(EchoRequest.typecode, 
                    EchoResponse.typecode, 
                    operation='Echo', 
                    soapaction='Echo')
        def soap_Echo(self, request, response, **kw):
            # Just return what was sent
            response.Value = request.Value
            return request, response
    
    def main():
        from wsgiref.simple_server import make_server
        from ZSI.twisted.wsgi import WSGIApplication
    
        application         = WSGIApplication()
        httpd               = make_server('', 7000, application)
        application['echo'] = EchoService()
        print "listening..."
        httpd.serve_forever()
    
    if __name__ == '__main__':
        main()
    

    清单 6 包含如何使用 ZSI 客户端库从客户端访问服务器的示例。所需要做的就是创建 EchoServer Web 服务的句柄,构建 EchoRequest,将其发送到 Web 服务,然后读取响应。

    from EchoServer_client import *
    import sys, time
    
    loc  = EchoServerLocator()
    port = loc.getEchoServer(url='http://localhost:7000/echo')
    
    print "Echo: ", 
    msg = EchoRequest()
    msg.Value = "Is there an echo in here?"
    rsp = port.Echo(msg)
    print rsp.Value
    

    【讨论】:

      猜你喜欢
      • 2015-07-27
      • 2011-08-19
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 1970-01-01
      相关资源
      最近更新 更多