现如今面向服务(SOA)的架构设计已经成为主流,把公用的服务打包成一个个webservice供各方调用是一种非常常用的做法,而应用最广泛的则是基于SOAP协议和wsdl的webservice。本文讲解python环境下如何发布及调用一个基于SOAP的webservice,基于soaplib(发布)和suds(调用)。
OS:ubuntu 14.04 python:2.7.6
服务端:
1.安装:
服务端要使用的工具包是soaplib,遗憾的是现在也停止维护了,不过好在还能用,下载地址在https://github.com/soaplib/soaplib,其官方文档在http://soaplib.github.io/soaplib/2_0/
首先直接下载zip文件,解压后直接运行python setup.py install即可。
2.写一个webservice服务:
接下来举个栗子,下面是一个接受一个string类型入参并返回一个string类型出参的webservice
import soaplib
from soaplib.core.model.primitive import String
from soaplib.core.server import wsgi
from soaplib.core.service import DefinitionBase #所有的服务类都继承DefinitionBase基类
from soaplib.core.service import soap #soap标识方法的特性 from model import feedforward class webserver(DefinitionBase):
@soap(String, _returns=String)
def GetModel(self, input):
return 'hello world' if __name__ == '__main__':
try:
from wsgiref.simple_server import make_server
soap_application = soaplib.core.Application([webserver], 'tns', 'webservice')
wsgi_application = wsgi.Application(soap_application) print "listening to http://0.0.0.0:7789"
print "wsdl is at: http://172.11.0.11:7789/?wsdl" server = make_server('172.11.0.11', 7789, wsgi_application)
server.serve_forever() except ImportError:
print "Error: example server code requires Python >= 2.5"
注意第11行的soap注解
@soap(String, _returns=String)
表示这个被注解的方法GetModel需要接受一个String类型的入参,_returns=String表示该方法返回的出参也是String类型。当然也可以设置更复杂的参数类型或是自定义类型,例如:
@soap(User, _returns=String)
def GetUser(self, user):
name = user.Name
return name
表示入参是一个自定义的类型User,出参为String,但是自定义的类型一定要继承ClassModel类:
class User(ClassModel):
__namespace__ = "User"
Name=String
如果返回的类型是集合需要用soaplib的Array类型,例如:
@soap(_returns=Array(String))
def GetCdrArray(self):
L_Result=["","",""] #返回集合数据的格式
return L_Result
3.发布webservice
上例中从第15行if __name__ == '__main__'开始的就是webservice的发布过程。首先要创建一个Application对象:
soap_application = soaplib.core.Application([webserver], 'tns', 'webservice')
按照文档,其中第一个参数表示 An iterable of ServiceBase subclasses that define the exposed services. 即把所有想要发布的服务所在的类装入一个列表作为该方法的第一个参数
第二个参数表示 The targetNamespace attribute of the exposed service 即该webservice的命名空间,默认为tns
第三个参数表示 The name attribute of the exposed service 默认为None
接下来将soap_application转化为一个wsgi_application: wsgi_application = wsgi.Application(soap_application)
最后新建一个server对象,设定IP和端口,接着启动即可:
server = make_server('172.11.0.11', 7789, wsgi_application)
server.serve_forever()
这样就发布了一个webservice,然后在浏览器里输入http://172.11.0.11:7789/?wsdl就能看到相应的wsdl文件了
客户端:
客户端我们使用suds调用webservice
1.安装
首先还是安装,官方主页https://fedorahosted.org/suds/,下载自己想要的版本,然后解压,python setup.py install 即可,与安装soaplib完全一致。文档地址在https://fedorahosted.org/suds/wiki/Documentation
2.使用
使用suds调用webservice非常简单。
import suds
import logging
logging.basicConfig(level=logging.INFO) class webservice_client(): def __init__(self, url):
self.client = suds.client.Client(url) # 通过smile获取model
def get_model(self, input):
try:
model = self.client.service.GetModel(input)
return model
except Exception,e:
logging.info('获取model失败:'+str(e))
return None if __name__ == '__main__':
test = webservice_client('http://172.11.30.211:7789/?wsdl')
print test.get_model('')
运行这个脚本,可以得到返回值hello world。
以上即python 发布及调用一个基于soap协议的wsdl类型webservice的方法