suds对接web service
webservice概念
1. Web service是一个平台独立的,松耦合的,自包含的、基于可编程的web的应用程序
2. 使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序
SOAP :简单对象访问协议Simple Object Access Protocol,传输层,XML传输消息
WSDL:Web Server Description Language :Web Server描述语言(元数据),给客户端生成代理类的一个描述信息
UDDI :提供了一组基于标准的规范用于描述和发现服务,统一描述,发现和集成(UDDI-Universal Descript,Discovery,Integration),提供注册和查找服务 客户端在UDDI注册表(Registry)查找服务,取得服务的WSDL描述,通过SOAP调用服务。
简单的来说,webservice就是一个建立在Http之上数据结构为XML的协议,其中并不像平常访问API那样去访问web service接口,而是要访问相对应XML中的方法,以实现远程跨平台、跨语言的方法调用。通过XML形式说明服务在什么地方,以XML形式说明服务提供什么样的方法
一般来说内部开发会使用这种模式,但是也不缺乏对外公开的服务 如:手机号地区查询、天气预报查询 …
python对接web service
那么,如何使用python对接web service呢,我们可以使用suds!
pip3 install suds
为了方便测试客户端,可以使用这个网址中的web服务:http://www.webxml.com.cn/zh_cn/index.aspx
suds 的目标是基于 soap 的 Web 服务提供类似 RPC 的接口。这意味着在大多数情况下,用户不需要关心 WSDL 和引用模式的复杂性。无论指定哪种 soap 消息样式,服务方法的签名都保持不变。确实检查 WSDL 的用户会注意到,即使使用文档 soap 消息样式,每个方法的签名也类似于 RPC。
主要接口为 Client
对象。它提供了配置库和定义的子命名空间的方法。创建 Client
,它会处理 WSDL和引用的模式。从该信息中,它导出该信息的表示,该表示用于向用户提供服务描述和消息/回复处理
在调试中,可以使用logging来记录日志
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
- suds.client: 在此模块上将日志记录级别设置为 DEBUG 以查看 soap 消息(输入和输出)和 http 标头。
- suds.transport: 在此模块上将日志记录级别设置为 DEBUG 以查看有关 soap 消息(输入和输出)和 http 标头的更多详细信息。
- suds.xsd.schema: 在此模块上将日志记录级别设置为 DEBUG 以查看模式的消化。
DEBUG
suds.wsdl: 在此模块上将日志记录级别设置为以查看消化 WSDL。
suds.Client
为使用 Web 服务提供了统一的 API。该对象包含2个子命名空间:
service : service
命名空间为消费的服务提供代理。该对象用于调用服务端点提供的操作(方法)。
factory : factory
命名空间提供了一个工厂,可用于创建 WSDL 中定义的对象和类型的实例。
这两个为每个服务的 WSDL 的 url 创建一个客户端
from suds.client import Client
url = 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl'
client = Client(url)
print(client.__str__())'''
Suds ( https://fedorahosted.org/suds/ ) version: 1.1.2Service ( WeatherWS ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREF'''# 示例出现了 服务名为 WeatherWS 的6个方法以及91个Types, 例如 getRegionCountry()、getRegionDataset() ...
如果出现 suds.TypeNotFound: Type not found: ‘(schema, http://www.w3.org/2001/XMLSchema, )’ 这种错误,就进一步处理
from suds.client import Client
from suds.xsd.doctor import ImportDoctor, Importurl = 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl'
imp = Import('http://www.w3.org/2001/XMLSchema',location='http://www.w3.org/2001/XMLSchema.xsd'
)
imp.filter.add('http://WebXml.com.cn/')
doctor = ImportDoctor(imp)
client = Client(url, doctor=doctor)
简单参数的调用
上面代码中返回WSDL中可调用的方法,现在就试着调用 getSupportCityDataset(xs:string theRegionCode)
可以看到方法中有参数并且为str类型,需要填入查询的地区代码。如果没有参数则直接调用
client = Client(url, doctor=doctor)
result = client.service.getSupportCityDataset("北京") # 也可以填写地区名称
print(result.diffgram.Region.City) # 获取到支持的城市数据级'''
[(City){_id = "City1"_rowOrder = "0"CityID = "792"CityName = "北京"}, (City){_id = "City2"_rowOrder = "1"CityID = "785"CityName = "昌平"}, (City){_id = "City3"_rowOrder = "2"CityID = "826"CityName = "大兴"}...]
'''
复杂参数
还有一些比较复杂的参数
比如 addPerson()方法接受一个类型为Person的参数,并具有一个签名:addPerson(Person person),其中参数类型后面跟着它的名称,相应的类型能在返回的Types中找到。在getWeather()的情况下,参数是xs:string类型的字符串 和 xs:int类型的整数。
因此,要创建一个Person对象作为参数传递,我们需要使用工厂子命名空间获得一个Person参数,如下所示:
person = client.factory.create('Person')
print(person)'''
(Person)={phone = []age = NONEname(Name) ={last = NONEfirst = NONE}}'''
# 对象是按照 WSDL 定义创建的。phone列表是空的,所以必须创建一个`Phone` 对象:
phone = client.factory.create('Phone')
phone.npa = 111
phone.nxx = 222
phone.number = 123123# 创建一个`Name` 对象
name = client.factory.create('Name')
name.first = 'lu'
name.last = 'wei'# 设置person属性
person.name = name
person.age = 25
person.phone = [phone]# 或者
person.phone.append(phone)# 调用方法
try:person_added = client.service.addPerson(person)
except WebFault as e:print e
或者可以使用Dict形式组装复杂参数
person = {}phone = {'npa':111,'nxx':222,'number':123123,
}name = {'first':'lu','last':'wei'
}person['name'] = name
person['age'] = 25
person['phone'] = [phone,]try:person_added = client.service.addPerson(person)
except WebFault as e:print e
客户端可以配置为将web故障作为WebFault抛出,或者返回元组(<status>,<return value>),如下所示:
client = client(url, faults=False)
result = client.service.addPerson(person)
print(result)
suds的client选项说明
suds客户端有许多可以用来控制库的行为的功能。有些是通用选项,有些是运输选项。尽管选项对象是公开的,但首选和支持的设置/取消设置选项的方式是通过:
Client
构造函数Client
.set_options()- 构造函数
Transport
一般选项:
faults
: 控制web故障行为
service
: 控制多服务wsdl的默认服务名称
port
:控制多端口服务的默认服务端口
location
: 这将覆盖WSDL中定义的服务端口地址URL
transport
: 控制插件web传输
cache
: 提供与加载WSDL相关的文档和对象的缓存。肥皂信封从不缓存
cachingpolicy
: 缓存策略,决定如何缓存数据。默认值为0。版本0.4+
0=WSDL和XSD等XML文档
1=WSDL对象图
soap
标头:提供soap标头
wsse
: 提供WS-Security对象
__inject
:控制消息/回复消息的注入
doctor
: 架构doctor指定用于修复损坏的架构的对象
xstq
: XML架构类型限定标志指示xsi:type属性值应该由命名空间限定
prefixs
: soap消息的元素应该使用XML前缀进行限定(在需要时),而不是xmlns=“”语法
retxml
: 导致返回I{raw}soap信封而不是python对象图的标志
autoblend
:确保WSDL中定义的架构相互导入的标志
nosend
: 导致suds生成soap信封但不发送它的标志。相反,返回RequestContext Default:False
sortnamespaces
: 使sud在存储命名空间时按字母顺序对其进行排序的标志。默认值:True
allowUnknownMessageParts
: 与操作的WSDL架构定义相比,在接收web服务回复时检测到未知消息部分时引发异常。默认值:False
只有在使用默认传输时,才会使用传递给客户端构造函数的传输选项,如下所示:
proxy
: 控制http代理设置。
timeout
: URL连接超时(秒)默认值=90。每个方法调用也可以设置超时
headers
: 提供额外的http标头
username
: HTTP身份验证的用户名
password
:HTTP身份验证的密码
通过交换零部件实现自定义行为
通过交换自定义,可以自定义suds的各种行为方式
初始化带有列表的可选阵列
在一些未发布的suds-jurko版本中,所有children元素都填充了空列表。这在suds社区中被修复为一种回归。这可能是所需的行为,因为它简化了构造复杂的请求。要获得先前的行为,请使用自定义生成器类,例如:
from suds.client import Client, Builderclass AlwaysInitializeBuilder(Builder):def skip_value(self, type):return Falseclient = Client(url)
client.factory.builder = AlwaysInitializeBuilder(client.factory.builder.resolver)
获取枚举变量
假设 wsdl 定义了以下枚举:
<xs:simpleType name="resourceCategory"><xs:restriction base="xs:string"><xs:enumeration value="PLATFORM"/><xs:enumeration value="SERVER"/><xs:enumeration value="SERVICE"/></xs:restriction>
</xs:simpleType>
实力化枚举变量
resourceCategory = client.factory.create('resourceCategory')
client.service.getResourceByCategory(resourceCategory.PLATFORM)
工厂Factory
工厂用于创建由wsdl/schema定义的复杂对象
使用create()方法,因为它返回的对象已经具有正确的结构和模式类型信息。由于xsd支持嵌套类型定义,所以使用(.)点表示法的create()也是如此。例如,假设(Name)类型没有定义为顶级的“命名”类型,而是在(Person)类型中定义的。在这种情况下,创建(Name)对象必须通过其父对象的名称进行量化,并使用如下点表示法:
name = client.factory.create('Person.Name')
如果类型与wsdl(targetNamespace)在同一个命名空间中,则可以在没有任何命名空间限定的情况下引用它。如果不是,则该类型必须由命名空间前缀限定,例如:
name = client.factory.create('ns0:Person')
或者,名称可以由命名空间本身使用完整限定语法:
name = client.factory.create('{http://test.server.enterprise.rhq.org/}person')
当使用 (.) 点符号指定路径时,限定名称只能用于名称的第一部分
多个服务和多个端口的 WSDL
如果WSDL 定义了多个服务多个端口
Suds ( https://fedorahosted.org/suds/ ) version: 1.1.2Service ( WeatherWS ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS(WeatherWSSoap12)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFSService ( WeatherWSTwo ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml2.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS(WeatherWSSoap12)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS
想要指定服务或者指定端口如下所示
# 例子 client.service[service][port].getRegionCountry()client.set_options(service='WeatherWSTwo', port='WeatherWSSoap12')
client.service.getRegionCountry()# 或者
client.service['WeatherWSTwo']['WeatherWSSoap12'].getRegionCountry()# 或者按下标
client.service[1][0].getRegionCountry()# 只选择service
client.service['WeatherWSTwo'].getRegionCountry()# 按照service下标
client.service[1].getRegionCountry()# 只按照port
client.set_options(port='WeatherWSSoap')
请注意,如果WSDL定义了多个服务,则必须通过选项或使用下标语法来限定服务,以便指定端口
。
suds对接web service相关推荐
- 万物皆可集成系列:低代码对接Web Service接口
我们知道活字格支持不写代码实现双向API绑定,那么没那么主流的Web Service接口(SOAP协议+XML交互格式)呢?其实对接的思路没有那么复杂,得用C#编码来对接的. 作为一款企业级低代码开发 ...
- 【分布计算环境学习笔记】9 Web Service
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.概述: 在现有的各种异构平台的基础上,构筑一个通用的,与应用无关.语言无关的技术层,各种不同平台之上的应用依 ...
- python接口测试实战_Python接口测试实战5(下) - RESTful、Web Service及Mock Server
课程目录 更多学习资料请加添加作者微信:superz-han获取 本节内容 REST及RESTful API Web Service XML解析 Mock Server REST及RESTful AP ...
- 用cxf公布和调用web service
用cxf发布和调用web service 最近我们的系统需要和一个第三方系统对接,对接的方式是通过web service,所以就学习了一下这方面的东西 用CXF来做web service是比较简单的, ...
- 使用WSE实现Web Service安全
WSE(Web Services Enhancements)是微软为了使开发者通过.NET创建出更强大,更好用的Web Services而推出功能增强插件.现在最新的版本是WSE2.0(SP2).本文 ...
- 关于php调用.net的web service 踩过的坑
从前一阵开始,公司要和对方做web service对接.由于对方使用.net语言,而我方使用php.本来经理是要求我们也用.net写web service的服务端.而我上学时学的.net全忘了... ...
- Java RESTful Web Service实战(第2版)
Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著 图书在版编目(CIP)数据 Java RESTful Web Service实战 / 韩陆著. -2版 ...
- 如何区别API、REST API、RESTful API和Web Service之间的异同
当你看到API接口你会想起什么?是接口.第三方调用.还是API文档?初看你可能会觉得这太熟悉了,这不是系统开发日常系列吗?但你仔细想一想,你会发现API的概念在你脑海里是如此的模糊.如何你通过搜索引擎 ...
- Web Service Case Study: 认证考试申请服务
本文是Web Service Case Study系列文章的第二篇.在这篇文章中,我将围绕一个认证考试申请系统展开设计和讨论,这个应用与本文的系统不同,主要是面向B2C模式的应用,着眼点在于如何将这个 ...
最新文章
- 【OpenCV 4开发详解】分割图像——Grabcut图像分割
- 58 Node.js中操作mongoDB数据库
- win10下安装TensorFlow(CPU only)
- Vmware虚拟机安装Ubuntu 16.04 LTS(长期支持)版本+VMware tools安装
- 核心期刊 CA JST CSCD 含金量_期刊评介|《仪表技术与传感器》科技期刊的阿玛尼,只管投就对了!...
- 【网络流24题----09】方格取数问题
- Linux系统编程30:进程信号之产生信号的四种方式(Core Dump,kill,raise)
- Bootstrap3 排版之水平对齐
- python学到哪知道baseline_Python NLTK学习6(创建词性标注器)
- 使用C#操作Oracle Spatial的SDO_GEOMETRY对像(读取和写入)
- 第四次博客:循环单链表解决约瑟夫环问题
- Asciidoctor Maven插件使用
- 线性规划中的单纯形法与内点法(原理、步骤以及matlab实现)(二)
- 编程软件下载地址(java/vs/python、pycharm/Web/eclipse)
- zabbix监控服务器raid状态,基于Zabbix的MegaRAID阵列卡状态监控
- qqpcmgr_docpro 这个隐藏文件无法删除的问题解决方法
- pyhon身份证验证
- Word 2003 出现 向程序发送命令时出现问题 的 解决方案
- python跳出双循环break图例
- Linux查看本机端口开启,Linux 实用指令之查看端口开启情况