RSS
热门关键字:
当前位置 : 主页>编程开发>Python>列表

Python Web 服务开发者 第 5 部分: Python SOAP 库

来源:我要研发网 作者: 时间:1970-01-01 点击:



  在这个由两部分组成系列第一篇文章中,Web 服务专栏作家 Mike Olson 和 Uche Ogbuji 讨论了 Python 可以使用各种 SOAP 实现,并给出了详细代码示例。 字串6

  在前面 3 部分中,我们已经用 4Suite Server 开发了一个 Web 服务实现,并利用了该产品 SOAP 支持。(请参阅 参考资料。)Python 还有其它 SOAP 实现;实际上,这象成了很流行使用 Python 开放源代码活动。在本文中,我们将看一下工作中 Soap.py。关于其它开放源代码 SOAP 项目更新,请参阅 旁注。但我们马上要讨论麻烦问题,是 Python SOAP 模块命名。不同项目之间交流看上去象并不多,因为在这些项目名称间有许多令人困惑类似地方。最近,在向同事解释这些供选方案时,我们发现自己记不清楚 SOAPy 和 SOAP.py 特征分别是什么了 ― 而且这还是在我们用过它们很长时间后。这个问题在必须为实际库中多个模块命名时变得更为严重,请参阅旁注。 字串6

  在这个专栏前三部分中,我们讨论了 4Suite SOAP;在这篇和下篇文章中,我们将提供来自 SOAP.py 和 SOAPy 项目示例,在这两个项目冻结时,这象是最深入讨论了。注意,尽管 W3C XML 协议工作组已经制订了一个被称为 SOAP 1.2 草案,但各个平台和语言上 SOAP 实现普遍级别仍是 SOAP 1.1,更早版本甚至更具代表性。这些日子 SOAP 版本发展引入了一些复杂性,这些复杂性可能会超过 SOAP 所承诺简洁性。 字串4

  SOAP.py 客户机和服务器 字串1

  SOAP.py 包含是一些基本东西。没有 Web 服务描述语言(Web Services Description Language,WSDL)或者任何其它附加东西,只有用 Python 实现 SOAP 客户机和服务器透明支持。甚至这个包中一个很功能也只是与基础架构相关:SOAP.py 支持安全套接字层(SSL)用于加密 SOAP 传输。为使用这个功能,您必须安装 M2Crypto,M2Crypto 是一个库,包含各种加密工具和格式,从 RSA 和 DSA 到 HTTPs、S/MIME 等等。在这一部分,我们不准备讨论 SOAP.py SSL 支持。 字串3

  SOAP 操作摘要

字串9

  目前为止,SOAP 实用程序象仍是比较流行使用 Python 开放源代码活动。下面是该项目纲要以及它们目前状态。首先,参与者: 字串1

  4Suite SOAP,由 Fourthought 管理

字串6

  SOAPy,由 Adam Elman 管理

字串4

  SOAP.py,Python 项目一个 Web 服务项目 字串7

  soaplib,由 Secret Labs 管理 字串4

  Orchard,由 Ken MacLeod 管理 字串4


字串7

  PySOAP,由 Dave Warner 管理

字串5

  4Suite SOAP 是我们自己实现,我们在本专栏前面三部分中使用过(请参阅 参考资料以获得它链接)。它目前仍在开发中。

字串4

  SOAPy 是在 2001 年 4 月公布,目前处于 alpha 预备阶段,但现在象停止开发了。 字串1

  SOAP.py 开发被冻结了。SOAP.py 这个项目是由 actzero 公司赞助,而 actzero 却不再从事这一行业了。正在邀请自愿开发/维护 SOAP.py 组织。 字串2

  soaplib 开发象也延缓了,考虑到 Secret Labs 这段时间所承担大量工作,或许就可以理解为什么会这样了。这个瑞典公司是由 Fredrik Lundh 掌管,他在 Python 圈内是出名“工作狂”,同时也是 Python Association 董事会一名成员。Secret Labs 还开发 PythonWare(Python 一个核心和重要附加模块);PythonWorks(一个领先 Python IDE);Python Imaging Library 和许多其它东西(日常 Python-URL Web 日志就是其中一部分)。

字串3

  Orchard 是一个数据管理框架,基本上是一种用一个公共接口管理不同数据格式方法。它实现了一个 SOAP 客户机作为在远程过程调用中向 SOAP 服务器发送 Orchard 数据项基本方法(被称为节点)。

字串7

  PySOAP 这个项目主要是想作为 Dave Warner Church 管理套件一部分,但它还从没发行过任何文件,象是一个毫无生气项目。

字串1

  安装

字串7

  开始先下载分发包(在写这篇文章时候,SOAPpy 0.9.7 是最新分发包),把文件解包,转到结果目录,并把文件 SOAP.py复制到自己倾向位置。当然,这个“倾向”就是需要技巧地方。由于这些 SOAP lib 中有很多都使用大小写组合不同“soap.py”作为模块名,所以大家一定要小心。当然,UNIX 用户只需关心大小写是否精确匹配,但对于 Windows 用户来说,甚至“SOAP.py”和“soap.py”之间冲突也会带来麻烦。Orchard SOAP.py 也有一个容易发生冲突名称,但它有可能避开所有问题,因为它模块聪明地放在了 Orchard 包中。 字串4

  上面内容简言之就是建议您确保安装所有 Python SOAP 模块时都使用与众不同包名称。在我们案例中,我们在 PYTHONPATH 中发现了一个合适目录并创建了一个 WebServices 包,把 SOAP.py 放在了这个包中。因此,在 Linux 中: 字串2

$ mkdir ~/lib/python/WebServices
$ touch ~/lib/python/WebServices/__init__.py
$ cp SOAPpy097/SOAP.py ~/lib/python/WebServices
字串1


字串9

  请注意很重要第二条命令,它将生成一个 __init__.py 文件,这个文件将 WebServices 目录标志为 Python 包。如果您需要把这些代码打包成 Windows 版本,您可能希望向空文件中输入一些注释,因为一些 Windows 工具不创建空文件。

字串8

  您已深入主题了 字串4

  对于公开提供 SOAP 服务器,早已经有了几个活动注册中心。最流行可能是 XMethods。当然,它也是一个相当有趣指导,通过它我们可以了解 SOAP 实际状况,而不要听它吹嘘。这里大多数公共 Web 服务仍然只是一些无关紧要东西,几乎不值得我们勇敢新模型多费口舌,但那是另一回事了。实际上,我们将选择一个公共服务来演示和测试如何把 SOAP.py 作为 SOAP 客户机使用。 字串2

  或者,我们可以试试。作者尝试第一个服务,卫生保健提供者定位器,在遇到下列报错消息时显示 SOAP 互操作性当前状态中陷阱:

字串9

WebServices.SOAP.faultType: Server did not recognize the value of
HTTP Header SOAPAction: "".>
字串3

  哦。SOAPAction 是一个 HTTP 头,应该是用来标记被访问服务。它是 SOAP 请求中必需头,但即便是设置了所需头(只是一对空双引号)后,上面错误仍然存在。作者发现大多数 MS SOAP 实现都存在这个问题。在试遍了这些服务后,我们断定,Delphi 实现象与 SOAP.py 合作得最,但在试服务时 — 即使是用 Delphi 实现时,也返回复杂类型,比如列表,SOAP.py 无法使用它们,返回不带数据 WebServices.SOAP.typedArrayType 实例。

字串8

  最后,作者选择了一个相当合适 Web 服务,该服务返回漫画《丁丁历险记》中人物 Haddock 船长常用骂人语言(是,大多数 Web 服务都是这样)。 清单 1(curse.py)就是这个程序。

字串4

  清单 1:访问 Curse 生成器 SOAP 服务 SOAP.py 程序 字串6

 #!/usr/bin/env python
#http://xmethods.net/detail.html?id=175
import sys
#Import the SOAP.py machinery
from WebServices import SOAP
remote = SOAP.SOAPProxy(
"http://www.tankebolaget.se/scripts/Haddock.exe/soap/IHaddock",
 namespace="urn:HaddockIntf-IHaddock",
 soapaction="urn:HaddockIntf-IHaddock#Curse"
)
try:
 lang = sys.argv[1]
except IndexError:
 lang = "us"
result = remote.Curse(LangCode=lang)
print "What captain Haddock had to say: "%s""%result

字串7


字串9

  把一切综合在一起

字串6

  导入库后,我们将设置代理对象 remote 。这个对象将方法调用转换为远程 SOAP 消息。它初始化器使用管理远程请求关键参数:服务器 URI(被称为“端点”)、请求元素 XML 名称空间(通过它,SOAP-as-RPC 将口头承诺变成 XML 基础)和 SOAPAction 头值。

字串6

  接下来,我们将确定方法参数,对于这个 Web 服务来说,方法参数只是 Haddock 骂人语言,瑞典语(“se”)或英语(奇怪是,是“us”而不是“en”)。

字串4

  最后,我们调用名称正确方法,代理对象 Curse 进行 SOAP 调用,然后打印出结果。下面会话演示了对该程序使用: 字串8

$ python curse.py
What captain Haddock had to say: "Ectoplasmic Byproduct!"
字串7

  我们自己 SOAP 服务器

字串2

  用 SOAP.py 实现 SOAP 服务器相当容易。作为一个示例,我们将仿建字段,还要实现一个很常见服务:一个程序,给出年份和月份,它将以字符串形式打印出日历。它程序服务器是 清单 2(calendar-ws.py)。

字串6

  清单 2:实现日历服务器 SOAP.py 程序

字串9

 #!/usr/bin/env python
import sys, calendar
#Import the SOAP.py machinery
from WebServices import SOAP
CAL_NS = "http://uche.ogbuji.net/eg/ws/simple-cal"
class Calendar:
 def getMonth(self, year, month):
  return calendar.month(year, month)
 def getYear(self, year):
  return calendar.calendar(year)
server = SOAP.SOAPServer(("localhost", 8888))
cal = Calendar()
server.registerObject(cal, CAL_NS)
print "Starting server..."
server.serve_forever()
字串6

  进行过必要导入后,我们为自己服务器定义 SOAP 请求元素期望名称空间( CAL_NS )。接下来我们定义实现所有方法类,这些方法将被公开为 SOAP 方法。大家也可以把单个函数作为 SOAP 方法注册,但使用类方法是最灵活,特别是当您想管理调用间状态时。这个 Calendar 类定义了一个方法 getMonth ,该方法使用 Python 内置日历模块在文本表单中返回月度日历,同时它还定义了另一个返回整年日历方法。 字串3

  然后创建 SOAP 服务器框架一个实例,这个实例还带有侦听端口 8888 指令。我们还必须创建 Calendar 类一个实例,这个实例在下一行中被注册用来处理 SOAP 消息,同时为其指出相关名称空间。最后,我们调用 serve_forever 方法,该方法直到进程终止才返回。 字串9


字串1

  为运行服务器,请打开另一个命令 shell 并执行 python calendar-ws.py 。执行结束时使用 ctrl-C 杀死进程。 字串2

  我们本来可以用也是用 SOAP.py 写客户机测试服务器,但那太显而易见了。我们还是用低级 Python 编写客户机把 SOAP 响应作为 XML 字符串来构建,并发送一条 HTTP 消息。这个程序(testcal.py)在 清单 3中。

字串9

  清单 3:用 Python 核心库写访问日历服务客户机 字串1

 import sys, httplib
SERVER_ADDR = "127.0.0.1"
SERVER_PORT = 8888
CAL_NS = "http://uche.ogbuji.net/ws/eg/simple-cal"
BODY_TEMPLATE = """ xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:s="http://uche.ogbuji.net/eg/ws/simple-cal"
 xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/1999/XMLSchema"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
>
 
  
   %s
   %s
  

 

"""
def GetMonth():
  year = 2001
  month = 12
  body = BODY_TEMPLATE%(year, month)
  blen = len(body)
  requestor = httplib.HTTP(SERVER_ADDR, SERVER_PORT)
  requestor.putrequest("POST", "cal-server")
  requestor.putheader("Host", SERVER_ADDR)
  requestor.putheader("Content-Type", "text/plain; charset="utf-8"") 字串5
  requestor.putheader("Content-Length", str(blen))
  requestor.putheader("SOAPAction", "http://uche.ogbuji.net/eg/ws/simple-car")
  requestor.endheaders()
  requestor.send(body)
  (status_code, message, reply_headers) = requestor.getreply()
  reply_body = requestor.getfile().read()
  print "status code:", status_code
  print "status message:", message
  print "HTTP reply body:
", reply_body
if __name__ == "__main__":
  GetMonth()

字串1


字串1

  下面会话演示了这个测试运行情况。

字串2

$ python testcal.py
status code: 200
status message: OK
HTTP reply body:

xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SO
AP-ENC="http://schemas.xmlsoap.org/soap/encoding/">


  December 2001
Mo Tu We Th Fr Sa Su
        1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31



字串3

  仔细审查字节 字串3

  如果您查找行 self.debug = 0 并把“0”改为“1”(这是 SOAP.py 版本 0.9.7 中第 210 行),有一件要注意事情是您可以获得被交换实际 SOAP 消息详细信息和用于调试与跟踪其它关键数据,这对您很有用。作为示例,下面提供了一个会话,它是打开了调试信息显示开关以前 curses.py 程序一个会话: 字串4

$ python curse.py
*** Outgoing HTTP headers **********************************************
POST /scripts/Haddock.exe/soap/IHaddock HTTP/1.0
Host: www.tankebolaget.se
User-agent: SOAP.py 0.9.7 (actzero.com)
Content-type: text/xml; charset="UTF-8"
Content-length: 523
SOAPAction: "urn:HaddockIntf-IHaddock#Curse"
************************************************************************
*** Outgoing SOAP ******************************************************

xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SO
AP-ENC="http://schemas.xmlsoap.org/soap/encoding/">


us

字串5

************************************************************************
*** Incoming HTTP headers **********************************************
HTTP/1.? 200 OK
Server: Microsoft-IIS/5.0
Date: Tue, 11 Sep 2001 16:40:19 GMT
Content-Type: text/xml
Content-Length: 528
Content:
************************************************************************
*** Incoming SOAP ******************************************************
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xml
soap.org/soap/encoding/">xsi:type="xsd:string">Anacoluthons!se>
字串6
************************************************************************
What captain Haddock had to say: "Anacoluthons!"

字串5


字串1

  为进行比较,您可以在带有下列代码 Python 脚本或程序中获得相同信息: 字串4

import calendar
return calendar.month(2001, 10)
字串5

  SOAP.py 总结 字串2

  我们已经注意到了,虽然 SOAP.py 互操作性还存在一些问题,但可用调试工具可望提供帮助 ― 这个专栏一位作者 Mike Olson 是已经签约要帮助这个项目继续发展开发者之一。我们将看一下另一个 Python SOAP 实现。

字串3

字串6

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
相关文章