Python中SOAP項(xiàng)目的介紹及其在web開發(fā)中的應(yīng)用
SOAP.py 客戶機(jī)和服務(wù)器
SOAP.py 包含的是一些基本的東西。沒有 Web 服務(wù)描述語言(Web Services Description Language,WSDL)或者任何其它附加的東西,只有用 Python 實(shí)現(xiàn)的 SOAP 客戶機(jī)和服務(wù)器的透明支持。甚至這個(gè)包中的一個(gè)很好的功能也只是與基礎(chǔ)架構(gòu)相關(guān):SOAP.py 支持安全套接字層(SSL)用于加密的 SOAP 傳輸。為使用這個(gè)功能,您必須安裝 M2Crypto,M2Crypto 是一個(gè)庫,包含各種加密工具和格式,從 RSA 和 DSA 到 HTTPs、S/MIME 等等。在這一部分,我們不準(zhǔn)備討論 SOAP.py 的 SSL 支持。
SOAP 操作摘要
目前為止,SOAP 實(shí)用程序好象仍是比較流行的使用 Python 的開放源代碼活動(dòng)。下面是該項(xiàng)目的綱要以及它們目前的狀態(tài)。首先,參與者:
- 4Suite SOAP,由 Fourthought 管理
- SOAPy,由 Adam Elman 管理
- SOAP.py,Python 項(xiàng)目的一個(gè) Web 服務(wù)項(xiàng)目
- soaplib,由 Secret Labs 管理
- Orchard,由 Ken MacLeod 管理
- PySOAP,由 Dave Warner 管理
4Suite SOAP 是我們自己的實(shí)現(xiàn),我們?cè)诒緦诘那懊嫒糠种惺褂眠^(請(qǐng)參閱 參考資料以獲得它的鏈接)。它目前仍在開發(fā)中。
SOAPy 是在 2001 年 4 月公布的,目前處于 alpha 的預(yù)備階段,但現(xiàn)在好象停止開發(fā)了。
SOAP.py 開發(fā)被凍結(jié)了。SOAP.py 這個(gè)項(xiàng)目是由 actzero 公司贊助的,而 actzero 卻不再從事這一行業(yè)了。正在邀請(qǐng)自愿開發(fā)/維護(hù) SOAP.py 的組織。
soaplib 的開發(fā)好象也延緩了,考慮到 Secret Labs 這段時(shí)間所承擔(dān)的大量工作,或許就可以理解為什么會(huì)這樣了。這個(gè)瑞典的公司是由 Fredrik Lundh 掌管的,他在 Python 圈內(nèi)是出名的“工作狂”,同時(shí)也是 Python Association 董事會(huì)的一名成員。Secret Labs 還開發(fā) PythonWare(Python 的一個(gè)核心和重要的附加模塊);PythonWorks(一個(gè)領(lǐng)先的 Python IDE);Python Imaging Library 和許多其它好東西(日常 Python-URL Web 日志就是其中的一部分)。
Orchard 是一個(gè)數(shù)據(jù)管理框架,基本上是一種用一個(gè)公共接口管理不同數(shù)據(jù)格式的方法。它實(shí)現(xiàn)了一個(gè) SOAP 客戶機(jī)作為在遠(yuǎn)程過程調(diào)用中向 SOAP 服務(wù)器發(fā)送 Orchard 數(shù)據(jù)項(xiàng)的基本方法(被稱為節(jié)點(diǎn))。
PySOAP 這個(gè)項(xiàng)目主要是想作為 Dave Warner 的 Church 管理套件的一部分,但它還從沒發(fā)行過任何文件,好象是一個(gè)毫無生氣的項(xiàng)目。
安裝
開始先下載分發(fā)包(在寫這篇文章的時(shí)候,SOAPpy 0.9.7 是最新的分發(fā)包),把文件解包,轉(zhuǎn)到結(jié)果目錄,并把文件 SOAP.py復(fù)制到自己傾向的位置。當(dāng)然,這個(gè)“傾向”就是需要技巧的地方。由于這些 SOAP lib 中有很多都使用大小寫組合不同的“soap.py”作為模塊名,所以大家一定要小心。當(dāng)然,UNIX 用戶只需關(guān)心大小寫是否精確匹配,但對(duì)于 Windows 用戶來說,甚至“SOAP.py”和“soap.py”之間的沖突也會(huì)帶來麻煩。Orchard 的 SOAP.py 也有一個(gè)容易發(fā)生沖突的名稱,但它有可能避開所有的問題,因?yàn)樗哪K聰明地放在了 Orchard 包中。
上面的內(nèi)容簡(jiǎn)言之就是建議您確保安裝所有的 Python SOAP 模塊時(shí)都使用與眾不同的包名稱。在我們的案例中,我們?cè)?PYTHONPATH 中發(fā)現(xiàn)了一個(gè)合適的目錄并創(chuàng)建了一個(gè) WebServices 包,把 SOAP.py 放在了這個(gè)包中。因此,在 Linux 中:
$ mkdir ~/lib/python/WebServices $ touch ~/lib/python/WebServices/__init__.py $ cp SOAPpy097/SOAP.py ~/lib/python/WebServices
請(qǐng)注意很重要的第二條命令,它將生成一個(gè) __init__.py 文件,這個(gè)文件將 WebServices 目錄標(biāo)志為 Python 包。如果您需要把這些代碼打包成 Windows 版本,您可能希望向空文件中輸入一些注釋,因?yàn)橐恍?Windows 工具不創(chuàng)建空文件。
您已深入主題了
對(duì)于公開提供的 SOAP 服務(wù)器,早已經(jīng)有了好幾個(gè)活動(dòng)的注冊(cè)中心。最流行的可能是 XMethods。當(dāng)然,它也是一個(gè)相當(dāng)有趣的指導(dǎo),通過它我們可以了解 SOAP 的實(shí)際狀況,而不要聽它的吹噓。這里的大多數(shù)公共 Web 服務(wù)仍然只是一些無關(guān)緊要的東西,幾乎不值得我們勇敢的新模型多費(fèi)口舌,但那是另一回事了。實(shí)際上,我們將選擇一個(gè)公共服務(wù)來演示和測(cè)試如何把 SOAP.py 作為 SOAP 客戶機(jī)使用。
或者,我們可以試試。作者嘗試的第一個(gè)服務(wù),衛(wèi)生保健提供者定位器,在遇到下列報(bào)錯(cuò)消息時(shí)顯示 SOAP 互操作性的當(dāng)前狀態(tài)中的陷阱:
WebServices.SOAP.faultType: <Fault soap:Client: Server did not recognize the value of HTTP Header SOAPAction: "".>
哦。SOAPAction 是一個(gè) HTTP 頭,應(yīng)該是用來標(biāo)記被訪問服務(wù)的。它是 SOAP 請(qǐng)求中必需的頭,但即便是設(shè)置了所需的頭(只是一對(duì)空的雙引號(hào))后,上面的錯(cuò)誤仍然存在。作者發(fā)現(xiàn)大多數(shù) MS SOAP 實(shí)現(xiàn)都存在這個(gè)問題。在試遍了這些服務(wù)后,我們斷定,Delphi 實(shí)現(xiàn)好象與 SOAP.py 合作得最好,但在試服務(wù)時(shí) — 即使是用 Delphi 實(shí)現(xiàn)時(shí),也返回復(fù)雜的類型,比如列表,SOAP.py 無法使用它們,返回不帶數(shù)據(jù)的 WebServices.SOAP.typedArrayType 實(shí)例。
最后,作者選擇了一個(gè)相當(dāng)合適的 Web 服務(wù),該服務(wù)返回漫畫《丁丁歷險(xiǎn)記》中的人物 Haddock 船長(zhǎng)常用的罵人語言(是的,大多數(shù) Web 服務(wù)都是這樣)。 清單 1(curse.py)就是這個(gè)程序。
清單 1:訪問 Curse 生成器 SOAP 服務(wù)的 SOAP.py 程序
#!/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
把一切綜合在一起
導(dǎo)入庫后,我們將設(shè)置代理對(duì)象 remote 。這個(gè)對(duì)象將方法調(diào)用轉(zhuǎn)換為遠(yuǎn)程 SOAP 消息。它的初始化器使用管理遠(yuǎn)程請(qǐng)求的關(guān)鍵參數(shù): 服務(wù)器的 URI(被稱為“端點(diǎn)”)、請(qǐng)求元素的 XML 名稱空間(通過它,SOAP-as-RPC 將 口頭承諾變成 XML 基礎(chǔ))和 SOAPAction 頭值。
接下來,我們將確定方法參數(shù),對(duì)于這個(gè) Web 服務(wù)來說,方法參數(shù)只是 Haddock 罵人的語言,瑞典語(“se”)或英語(奇怪的是,是“us”而不是“en”)。
最后,我們調(diào)用名稱正確的方法,代理對(duì)象的 Curse 進(jìn)行 SOAP 調(diào)用,然后打印出結(jié)果。下面的會(huì)話演示了對(duì)該程序的使用:
$ python curse.py What captain Haddock had to say: "Ectoplasmic Byproduct!"
我們自己的 SOAP 服務(wù)器
用 SOAP.py 實(shí)現(xiàn) SOAP 服務(wù)器相當(dāng)容易。作為一個(gè)示例,我們將仿建字段,還要實(shí)現(xiàn)一個(gè)很常見的服務(wù):一個(gè)程序,給出年份和月份,它將以字符串的形式打印出日歷。它的程序服務(wù)器是 清單 2(calendar-ws.py)。
清單 2:實(shí)現(xiàn)日歷服務(wù)器的 SOAP.py 程序
#!/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()
進(jìn)行過必要的導(dǎo)入后,我們?yōu)樽约旱姆?wù)器定義 SOAP 請(qǐng)求元素期望的名稱空間( CAL_NS )。接下來我們定義實(shí)現(xiàn)所有方法的類,這些方法將被公開為 SOAP 方法。大家也可以把單個(gè)函數(shù)作為 SOAP 方法注冊(cè),但使用類方法是最靈活的,特別是當(dāng)您想管理調(diào)用間的狀態(tài)時(shí)。這個(gè) Calendar 類定義了一個(gè)方法 getMonth ,該方法使用 Python 的內(nèi)置日歷模塊在文本表單中返回月度日歷,同時(shí)它還定義了另一個(gè)返回整年日歷的方法。
然后創(chuàng)建 SOAP 服務(wù)器框架的一個(gè)實(shí)例,這個(gè)實(shí)例還帶有偵聽端口 8888 的指令。我們還必須創(chuàng)建 Calendar 類的一個(gè)實(shí)例,這個(gè)實(shí)例在下一行中被注冊(cè)用來處理 SOAP 消息,同時(shí)為其指出相關(guān)的名稱空間。最后,我們調(diào)用 serve_forever 方法,該方法直到進(jìn)程終止才返回。
為運(yùn)行服務(wù)器,請(qǐng)打開另一個(gè)命令 shell 并執(zhí)行 python calendar-ws.py 。執(zhí)行結(jié)束時(shí)使用 ctrl-C 殺死進(jìn)程。
我們本來可以用也是用 SOAP.py 寫的客戶機(jī)測(cè)試服務(wù)器,但那太顯而易見了。我們還是用低級(jí) Python 編寫客戶機(jī)把 SOAP 響應(yīng)作為 XML 字符串來構(gòu)建,并發(fā)送一條 HTTP 消息。這個(gè)程序(testcal.py)在 清單 3中。
清單 3:用 Python 核心庫寫的訪問日歷服務(wù)的客戶機(jī)
import sys, httplib SERVER_ADDR = "127.0.0.1" SERVER_PORT = 8888 CAL_NS = "http://uche.ogbuji.net/ws/eg/simple-cal" BODY_TEMPLATE = """<SOAP-ENV:Envelope 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/" > <SOAP-ENV:Body> <s:getMonth> <year xsi:type="xsd:integer">%s</year> <month xsi:type="xsd:integer">%s</month> </s:getMonth> </SOAP-ENV:Body> </SOAP-ENV:Envelope>""" 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"") requestor.putheader("Content reply_body = requestor.getfi-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() le().read() print "status code:", status_code print "status message:", message print "HTTP reply body:\n", reply_body if __name__ == "__main__": GetMonth()
下面的會(huì)話演示了這個(gè)測(cè)試的運(yùn)行情況。
$ python testcal.py status code: 200 status message: OK HTTP reply body: <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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/"> <SOAP-ENV:Body> <getMonthResponse SOAP-ENC:root="1"> <Result xsi:type="xsd:string"> 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 </Result> </getMonthResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
仔細(xì)審查的字節(jié)
如果您查找行 self.debug = 0 并把“0”改為“1”(這是 SOAP.py 版本 0.9.7 中的第 210 行),有一件要注意的事情是您可以獲得被交換的實(shí)際 SOAP 消息的詳細(xì)信息和用于調(diào)試與跟蹤的其它關(guān)鍵數(shù)據(jù),這對(duì)您很有用。作為示例,下面提供了一個(gè)會(huì)話,它是打開了調(diào)試信息顯示開關(guān)的以前的 curses.py 程序的一個(gè)會(huì)話:
$ 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 ****************************************************** <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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/"> <SOAP-ENV:Body> <ns1:Curse xmlns:ns1="urn:HaddockIntf-IHaddock" SOAP-ENC:root="1"> <LangCode xsi:type="xsd:string">us</LangCode> </ns1:Curse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> ************************************************************************ *** 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 ****************************************************** <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns: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/"><SOAP-ENV:Body><NS1:CurseResponse xmlns:NS1="urn:HaddockIntf- IHaddock" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><NS1:return xsi:type="xsd:string">Anacoluthons!</NS1:return></NS1:CurseRespon se></SOAP-ENV:Body></SOAP-ENV:Envelope> ************************************************************************ What captain Haddock had to say: "Anacoluthons!"
為進(jìn)行比較,您可以在帶有下列代碼的舊的 Python 腳本或程序中獲得相同的信息:
import calendar return calendar.month(2001, 10)
SOAP.py 總結(jié)
我們已經(jīng)注意到了,雖然 SOAP.py 的互操作性還存在一些問題,但可用的調(diào)試工具可望提供幫助。
- python網(wǎng)絡(luò)應(yīng)用開發(fā)知識(shí)點(diǎn)淺析
- 基于Python_腳本CGI、特點(diǎn)、應(yīng)用、開發(fā)環(huán)境(詳解)
- 使用Docker開發(fā)python Web 應(yīng)用
- Python開發(fā).exe小工具的詳細(xì)步驟
- python開發(fā)一個(gè)解析protobuf文件的簡(jiǎn)單編譯器
- 教你使用Sublime text3搭建Python開發(fā)環(huán)境及常用插件安裝另分享Sublime text3最新激活注冊(cè)碼
- 詳解vscode實(shí)現(xiàn)遠(yuǎn)程linux服務(wù)器上Python開發(fā)
- 10款最佳Python開發(fā)工具推薦,每一款都是神器
- python開發(fā)一款翻譯工具
- Visual Studio code 配置Python開發(fā)環(huán)境
- 如何用python開發(fā)Zeroc Ice應(yīng)用
相關(guān)文章
python實(shí)現(xiàn)請(qǐng)求數(shù)據(jù)包簽名
這篇文章主要介紹了python實(shí)現(xiàn)請(qǐng)求數(shù)據(jù)包簽名,主要以python怎么快速對(duì)請(qǐng)求體做一次簽名為主題,塑造實(shí)現(xiàn)請(qǐng)求數(shù)據(jù)包簽名過程,具有一定得參考價(jià)值,需要的小伙伴可以參考一下2022-02-02Python實(shí)現(xiàn)將不規(guī)范的英文名字首字母大寫
這篇文章給大家主要介紹的是利用map()函數(shù),把用戶輸入的不規(guī)范的英文名字,變?yōu)槭鬃帜复髮懀渌懙囊?guī)范名字。文中給出了三種解決方法,大家可以根據(jù)需要選擇使用,感興趣的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。2016-11-11Python基于PyGraphics包實(shí)現(xiàn)圖片截取功能的方法
這篇文章主要介紹了Python基于PyGraphics包實(shí)現(xiàn)圖片截取功能的方法,涉及PyGraphics包的安裝及基于PyGraphics包實(shí)現(xiàn)圖片的打開、讀取、截取等相關(guān)操作技巧,需要的朋友可以參考下2017-12-12pycharm2022.2遠(yuǎn)程連接服務(wù)器調(diào)試代碼實(shí)現(xiàn)
本文主要介紹了pycharm2022.2遠(yuǎn)程連接服務(wù)器調(diào)試代碼實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Python使用difflib標(biāo)準(zhǔn)庫實(shí)現(xiàn)查找文本間的差異
在文本處理和比較中,查找文本之間的差異是一項(xiàng)常見的任務(wù),本文將詳細(xì)介紹如何使用difflib模塊來查找文本之間的差異,包括單行和多行文本的比較、生成差異報(bào)告,需要的可以參考下2024-03-03python pytest進(jìn)階之xunit fixture詳解
這篇文章主要介紹了python pytest進(jìn)階之xunit fixture詳解,了解unittest的同學(xué)應(yīng)該知道我們?cè)诔跏蓟h(huán)境和銷毀工作時(shí),unittest使用的是setUp,tearDown方法,那么在pytest框架中同樣存在類似的方法,今天我們就來具體說明,需要的朋友可以參考下2019-06-06Python中NumPy的線性代數(shù)子模塊linalg詳解
這篇文章主要介紹了Python中NumPy的線性代數(shù)子模塊linalg詳解,NumPy 的線性代數(shù)子模塊linalg提供了 20 余個(gè)函數(shù),用于求解行列式、逆矩陣、特征值、特征向量,以及矩陣分解等,需要的朋友可以參考下2023-08-08