zoukankan      html  css  js  c++  java
  • Python 开发与测试 Webservice(SOAP)

    WebService是一种跨编程语言和跨操作系统平台的远程调用技术。

    理解WebService

    1.从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过Web来调用这个应用程序。我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。

    2.从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。 

    Python 库选择

    服务端开发:

    针对Python的WebService开发,开发者讨论最多的库是soaplib(官方地址:http://soaplib.github.io/soaplib/2_0/index.html),但从其官网可知,其最新版本“soaplib-2.0.0-beta2”从2011年3月发布后就不再进行更新了。通过阅读soaplib的官方文档,可知其不再维护后已经转向了一个新的项目:rpclib(官方地址:http://github.com/arskom/rpclib)进行后续开发,但在rpclib的readme中,介绍了rpclib已经更名为spyne,并将持续进行更新,so,那就选用spyne进行开发了。

    spyne 官方文档:http://spyne.io/docs/2.10/index.html

    spyne github:https://github.com/arskom/spyne

    • spyne 安装
    pip install spyne
    
    • lxml 安装:

    下载与python匹配的版本安装包  https://pypi.python.org/pypi/lxml/3.6.0 进行安装,如 lxml-3.6.0.win-amd64-py2.7.exe (md5)

    客户端开发:

    客户端调用WebService一般应用suds库。

    使用参考文档:https://fedorahosted.org/suds/wiki/Documentation

    • suds 安装:
    pip install suds

    Spyne Introduction

    Protocols:协议
      Protocols define the rules for transmission of structured data
    Transports:传输
      Transports, also protocols themselves, encapsulate protocol data in their free-form data sections.
    Models:模式
      Types like Unicode, Integer or ByteArray are all models. They reside in the spyne.model package.
    Interface Documents:接口文档
      Interface documents provide a machine-readable description of the expected input and output of the exposed method calls. 
    Serializers:序列化对象
      Serializers are currently not distinguished in Spyne code. They are the protocol-specific representations of a serialized Python object.

    How your code is wrapped?

    step1:Your code is inside @rpc-wrapped methods in ServiceBase subclasses.

    step2:The ServiceBase subclasses in turn are wrapped by an Application instance.

             The Application instantiation is used to assign input and output protocols to the exposed methods.

    step3:The Application instance is finally wrapped by a client or server transport that takes the responsibility of moving the bits around.

    step4:Deploying the service using Soap via Wsgi

    服务端代码实例(HelloWorld)

    #!/usr/bin/env python 
    # -*- coding: utf-8 -*-
    
    """
    preference:
        http://spyne.io/docs/2.10/index.html
        https://github.com/arskom/spyne/blob/master/examples/helloworld_soap.py
    
    This is a simple HelloWorld example to show the basics of writing
    a webservice using spyne, starting a server, and creating a service
    client.
    Here's how to call it using suds:
    
    #>>> from suds.client import Client
    #>>> hello_client = Client('http://localhost:8000/?wsdl')
    #>>> hello_client.service.say_hello('punk', 5)
    (stringArray){
       string[] =
          "Hello, punk",
          "Hello, punk",
          "Hello, punk",
          "Hello, punk",
          "Hello, punk",
     }
    #>>>
    
    """
    # Application is the glue between one or more service definitions, interface and protocol choices.
    from spyne import Application
    # @rpc decorator exposes methods as remote procedure calls
    # and declares the data types it accepts and returns
    from spyne import rpc
    # spyne.service.ServiceBase is the base class for all service definitions.
    from spyne import ServiceBase
    # The names of the needed types for implementing this service should be self-explanatory.
    from spyne import Iterable, Integer, Unicode
    
    from spyne.protocol.soap import Soap11
    # Our server is going to use HTTP as transport, It’s going to wrap the Application instance.
    from spyne.server.wsgi import WsgiApplication
    
    
    # step1: Defining a Spyne Service
    class HelloWorldService(ServiceBase):
        @rpc(Unicode, Integer, _returns=Iterable(Unicode))
        def say_hello(self, name, times):
            """Docstrings for service methods appear as documentation in the wsdl.
            <b>What fun!</b>
            @param name: the name to say hello to
            @param times: the number of times to say hello
            @return  When returning an iterable, you can use any type of python iterable. Here, we chose to use generators.
            """
    
            for i in range(times):
                yield u'Hello, %s' % name
    
    
    # step2: Glue the service definition, input and output protocols
    soap_app = Application([HelloWorldService], 'spyne.examples.hello.soap',
                           in_protocol=Soap11(validator='lxml'),
                           out_protocol=Soap11())
    
    # step3: Wrap the Spyne application with its wsgi wrapper
    wsgi_app = WsgiApplication(soap_app)
    
    if __name__ == '__main__':
        import logging
    
        from wsgiref.simple_server import make_server
    
        # configure the python logger to show debugging output
        logging.basicConfig(level=logging.DEBUG)
        logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
    
        logging.info("listening to http://127.0.0.1:8000")
        logging.info("wsdl is at: http://localhost:8000/?wsdl")
    
        # step4:Deploying the service using Soap via Wsgi
        # register the WSGI application as the handler to the wsgi server, and run the http server
        server = make_server('127.0.0.1', 8000, wsgi_app)
        server.serve_forever()

    服务端运行后,

    访问浏览器检查服务  http://localhost:8000/?wsdl

    浏览器中输出wsdl文件:

     客户端调用(代码实例)

    #!/usr/bin/env python 
    # -*- coding: utf-8 -*-
    
    from suds.client import Client  # 导入suds.client 模块下的Client类
    
    wsdl_url = "http://localhost:8000/?wsdl"
    
    
    def say_hello_test(url, name, times):
        client = Client(url)                    # 创建一个webservice接口对象
        client.service.say_hello(name, times)   # 调用这个接口下的getMobileCodeInfo方法,并传入参数
        req = str(client.last_sent())           # 保存请求报文,因为返回的是一个实例,所以要转换成str
        response = str(client.last_received())  # 保存返回报文,返回的也是一个实例
        print req       # 打印请求报文
        print response  # 打印返回报文
    
    if __name__ == '__main__':
        say_hello_test(wsdl_url, 'Milton', 2)

    客户端运行后,

    查看客户端控制台可见输出:


    ***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***
  • 相关阅读:
    [LeetCode] 617. Merge Two Binary Trees
    [LeetCode] 738. Monotone Increasing Digits
    289. Game of Life
    305. Number of Islands II
    288. Unique Word Abbreviation
    271. Encode and Decode Strings
    393. UTF-8 Validation
    317. Shortest Distance from All Buildings
    286. Walls and Gates
    296. Best Meeting Point
  • 原文地址:https://www.cnblogs.com/guanfuchang/p/5985070.html
Copyright © 2011-2022 走看看