序言

web services 已经不再流行,但是,由于它的在接口技术中有着非常重要的地位,同时现在最主要的Web 服务设计模型REST其实也属于web services 技术范畴。所以我们还是有必要学习一下。

其实 Web Serive 是一项不太容易讲清楚技术。他的相关概念包括:

  1. SOA Service-Oriented Architecture
  2. Web Services
  3. SOAP (Simple Object Access Protocol)
  4. WSDL (Web Services Description Language)
  5. UDDI (Universal Description Discovery and Integration)

相关概念

web services 这套复杂的技术如上文所述已经算是过时,但了解相关概念还是必要的

SOA

Service Oriented Ambiguity 中文一般理解为,面向服务架构,简称 SOA。

SOA 的提出是在企业计算领域,就是要将紧耦合的系统,划分为面向业务的,粗粒度,松耦合,无状态的服务。

SOA 的几个关键特性

特性:

一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。

对于 SOA 来说,并不需要太过较真 SOA 到是一个怎样的架构。只要符合它的定义和规范的软件系统都可以认为是 SOA 架构。

现在几乎所有的 SOA 应用场合都是和 Web Service 绑定的,所以不免有时候这两个概念混用。不可 否认 Web Service 是现在最适合实现 SOA 的技术,SOA 的走红在很大程度上归功于 Web Service 标准的成熟和 应用普及。

web services

Web Service 详细的描述: Web Service 是一个平台独立的,低耦合的,自包含的、基于可编程的 web 的应用程序,可使用开放的 XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分 布式的互操作的应用程序。

在 Web Service 中所有的访问都通过 SOAP 访问进行,用 WSDL 定义的接口封装,通过 UDDI 进行目录查找所以SOAP、WSDL 和 UDDI 构成了 Web Service 的三要素。

以下简略介绍这三要素。

SOAP

Simple Object Access Protocol,中文为简单对象访问协议,简称 SOAP。 SOAP 是基于 XML 在分散或分布式的环境中交换信息的简单的协议。允许服务提供者和服务客户经过防 火墙在 INTERNET 进行通讯交互。

最多的情况还是还是绑定在HTTP 协议上面传输。所以,导致大多数人认为SOAP 就是HTTP + XML, 或者认为 SOAP 是 HTTP post 请求的一个专用版本,遵循一种特殊的 XML 消息格式。

WSDL

Web Services Description Language,网络服务描述语言,简称 WSDL。它是一门基于 XML 的语言,用 于描述 Web Services 以及如何对它们进行访问。

UDDI

UDDI Universal Description, Discovery and Integration",可译为“通用描述、发现与集成服务”,简称 UDDI。 WSDL 用来描述了访问特定的 Web Service 的一些相关的信息,那么在互联网上,或者是在企业的不同 部门之间,如何来发现我们所需要的 Web Service 呢?而 Web Service 提供商又如何将自己开发的 Web Serivce 公布到因特网上呢?这就需要使用到 UDDI 了。


环境搭建

python 使用简单,第三方库丰富,我们搭建好环境,进行一整套web services 程序的开发。

我们使用 python 3.6 这个较新python 版本

python 环境管理的标准为conda 标准,我们使用conda 结合pip 进行开发环境的搭建。

创建conda 环境

conda create --name Web_Services python=3.6
conda activate Web_Services

导出依赖包

pip freeze > requirements.txt
conda list -e > requirements.txt

依赖包列表

# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: win-64
certifi=2019.6.16=py36_0
lxml=4.3.4=pypi_0
pip=19.1.1=py36_0
python=3.6.8=h9f7ef89_7
pytz=2019.1=pypi_0
setuptools=41.0.1=py36_0
spyne=2.12.16=pypi_0
sqlite=3.28.0=he774522_0
suds-py3=1.3.3.0=pypi_0
vc=14.1=h0510ff6_4
vs2015_runtime=14.15.26706=h3a45250_4
wheel=0.33.4=py36_0
wincertstore=0.2=py36h7fe50ca_0

使用conda 或者pip 批量安装

pip install -r requirements.txt
conda install --yes --file requirements.txt



但是注意,async=False ,这个参数问题在3.7版本中有问题,spyne 库会有报错。因为在Python3.7里async变成了关键字,关键字是不能做变量名的,只要把这个名字改成任意不是关键字的词就好了。


服务端开发

针对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,并将持续进行更新。

综上,所以选用spyne进行开发了。

服务端样例代码:

https://github.com/arskom/spyne/blob/master/examples/helloworld_soap.py

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#-------------------------------------------------------------------------------
'''
@Author : {SEASON}
@License : (C) Copyright 2013-2022, {OLD_IT_WANG}
@Contact : {}
@Software: PyCharm
@File : Web_Services_Test20190708 -- Web_Services
@Time : 2019/7/11 9:03
@Desc : '''
#-------------------------------------------------------------------------------
# !/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()

客户端开发

这方面有两个python 组件可以使用,分别是:

  • suds-jurko
  • suds-py3

suds-jurko

pip install suds-jurko

文档

https://bitbucket.org/jurko/suds/wiki/Original%20Documentation

suds-py3

https://github.com/cackharot/suds-py3

pip3 install suds-py3

客户端样例代码

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#-------------------------------------------------------------------------------
'''
@Author : {SEASON}
@License : (C) Copyright 2013-2022, {OLD_IT_WANG}
@Contact : {shiter@live.cn}
@Software: PyCharm
@File : Web_Services_Test20190708 -- test_client_suds-py3_eg
@Time : 2019/7/11 23:45
@Desc : '''
#------------------------------------------------------------------------------- import sys
import os
suds_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(suds_path) from suds.client import Client def set_log():
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
# logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG) def call_service(url):
client = Client(url, username='bob', password='catbob')
do_call_service(client, url) def do_call_service(client, url):
print("Calling: sayHello()")
result = client.service.sayHello('Username') print("Result: %s" % result)
a = 10.98
b = 98.83
print("Calling: add()")
sum = client.service.add(a, b)
print("Result: Sum of %f + %f = %f" % (a,b,sum)) print("Calling: addDate()")
from datetime import datetime
import time
inputDate = datetime.now()
dt = client.service.addDate(inputDate, 1)
print("Result: %s" % dt) def test(url):
client = Client(url)
for p in client.sd[0].ports:
for m, args in p[1]:
if len(args) == 0:
print(client.service[0][m]()) if __name__ == '__main__':
# set_log()
url = 'http://localhost:8000/?wsdl'
if len(sys.argv) > 1:
url = sys.argv[1] call_service(url)
# test('http://dati.meteotrentino.it/service.asmx?WSDL')
client1 = Client("http://127.0.0.1:8181/soap/infoservice?wsdl", username='bob', password='catbob')
print(client1.service.getInfo("Bob")) # client2 = Client("http://127.0.0.1:8181/soap/infoservice?wsdl", username='bob', password='catbob')
# print(client2.service.getInfo("Test2"))
#
# client3 = Client("http://127.0.0.1:8181/soap/infoservice?wsdl", username='bob', password='catbob')
# print(client3.service.getInfo("Test3"))

参考文献

1.《web 接口开发与自动化测试 基于Python语言》

2. https://www.cnblogs.com/guanfuchang/p/5985070.html

基于soap 的 python web services 服务开发指南的更多相关文章

  1. The Python web services developer: XML-RPC for Python

    原文地址:http://www.ibm.com/developerworks/webservices/library/ws-pyth10/index.html 摘要:概括地说,您可以将 XML-RPC ...

  2. PHP 调用asp.net Web Services服务问题总结

    原文:PHP 调用asp.net Web Services服务问题总结 PHP是弱类型语言,转换非常不方便. < ?php //soap 客户端 $client=new SoapClient(' ...

  3. 试读《基于MVC的JavaScript Web富应用开发》— 不一样的JavaScript

    前言 <基于MVC的JavaScript Web富应用开发>是ItEye在7月份发起试读的书.下载了试读的章节,发现只有全本的开始到第二章,第一章很简洁明了地讲述了JavaScript的历 ...

  4. HanLP封装为web services服务的过程介绍

    前几天的召开的2019年大数据生态产业大会不知道大家关注到没有,看到消息是hanlp2.0版本发布了.不知道hanlp2.0版本又将带来哪些新的变化?准备近期看能够拿到一些hanlp2.0的资料,如果 ...

  5. 基于第三方开源库的OPC服务器开发指南(3)——OPC客户端

    本篇将讲解如何编写一个OPC客户端程序测试我们在前文<基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署>一篇建立的服务器.本指南的目的是熟悉OPC服务器的开发流 ...

  6. 基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署

    前文已经说过,OPC基于微软的DCOM技术,所以开发OPC服务器我们要做的事情就是开发一个基于DCOM的EXE文件.一个代理/存根文件,然后就是写一个OPC客户端测试一下我们的服务器了.对于第一项工作 ...

  7. 30分钟学会使用Spring Web Services基础开发

    时隔一年终于又推出了一篇30分钟系列,上一篇<30分钟学会反向Ajax>是2016年7月的事情了.时光荏苒,岁月穿梭.虽然一直还在从事Java方面的开发工作,但是私下其实更喜欢使用C++. ...

  8. 基于Centos搭建Python Web 环境搭建教程

    CentOS 7.2 64 位操作系统 安装 setuptools 工具 安装 因为之后我们需要安装 Django ,而 Django 需要用这个工具,所以我们需要先安装 setuptools 工具. ...

  9. 基于Flask框架的Python web程序的开发实战 <一> 环境搭建

    最近在看<Flask Web开发基于Python的Web应用开发实战>Miguel Grinberg著.安道译 这本书,一步步跟着学习Flask框架的应用,这里做一下笔记 电脑只安装一个P ...

随机推荐

  1. JAVA中汉字的Compare排序

    当调用String.compare方法的时候,比较的是Unicode码,并不能对汉字进行准确的排序,所以汉字比较时会出现比较混乱的结果. java.text.Collator类中有一个getInsta ...

  2. JavaEE--JNDI(上,简介)

    参考:https://blog.csdn.net/yan372397390/article/details/50450332 https://www.landui.com/help/show-6158 ...

  3. Bugku 加密(持续更新)

    1.滴答~滴 不多说,摩斯密码解密. 2.聪明的小羊 栅栏密码解密. 3.ok Ook解密 4.这不是摩斯密码 brainfuck解码 5.简单加密 凯撒有两种编码脚本,一种是字母26内循环移位,一种 ...

  4. Nginx无法监听虚拟VIP的问题报:99: Cannot assign requested address

    99: Cannot assign requested address #本地网卡上没有10.0.0.3这个IPNginx就会报错: [root@lb01 conf]# /application/ng ...

  5. A - Alice and the List of Presents (排列组合+快速幂取模)

    https://codeforces.com/contest/1236/problem/B Alice got many presents these days. So she decided to ...

  6. jupyter notebook 安装配置使用,+目录插件安装

    1.安装 pip3 install jupyter 2.配置 2.1. 生成一个 notebook 配置文件 jupyter notebook --generate-config /root/.jup ...

  7. Ubuntu Teamviewer安装使用

    关于Ubuntu环境下teamviewer的安装(亲测可用-) 以下内容均转自:https://blog.csdn.net/weixin_41887832/article/details/798329 ...

  8. ruoyi ShiroUtils

    package com.ruoyi.framework.util; import org.apache.shiro.SecurityUtils; import org.apache.shiro.cry ...

  9. PAT Advanced 1024 Palindromic Number (25) [数学问题-⼤整数相加]

    题目 A number that will be the same when it is written forwards or backwards is known as a Palindromic ...

  10. 专业程序设计part1

    7 专业程序设计 (有多少人在大学里学到了自己真正喜欢的专业??并在此专业上获得了升华??)i== 软件图标下载网址:easyicon 01thu 4邻域 8邻域 D邻域 是啥 像素间的连通性,是转为 ...