2008-10-28 71 views
19

我正在研究SUDS作爲python的SOAP客戶端。我想檢查指定服務中可用的方法以及指定方法所需的類型。SUDS - 編程訪問方法和類型

其目的是生成一個用戶界面,允許用戶選擇一個方法,然後以動態生成的形式填充值。

我可以得到一個特定方法的一些信息,但我不確定如何解析它:

client = Client(url) 
method = client.sd.service.methods['MyMethod'] 

我無法programmaticaly弄清楚什麼對象類型,我需要創造能夠調用服務

obj = client.factory.create('?') 

res = client.service.MyMethod(obj, soapheaders=authen) 

有沒有人有一些示例代碼?

回答

18

根據sudsdocumentation,您可以使用__str()__檢查service對象。所以下面得到的方法和複雜類型的列表:

from suds.client import Client; 

url = 'http://www.webservicex.net/WeatherForecast.asmx?WSDL' 
client = Client(url) 

temp = str(client); 

上面的代碼會產生以下結果(temp內容):

Suds (https://fedorahosted.org/suds/) version: 0.3.4 (beta) build: R418-20081208 

Service (WeatherForecast) tns="http://www.webservicex.net" 
    Prefixes (1) 
     ns0 = "http://www.webservicex.net" 
    Ports (2): 
     (WeatherForecastSoap) 
     Methods (2): 
      GetWeatherByPlaceName(xs:string PlaceName,) 
      GetWeatherByZipCode(xs:string ZipCode,) 
     Types (3): 
      ArrayOfWeatherData 
      WeatherData 
      WeatherForecasts 
     (WeatherForecastSoap12) 
     Methods (2): 
      GetWeatherByPlaceName(xs:string PlaceName,) 
      GetWeatherByZipCode(xs:string ZipCode,) 
     Types (3): 
      ArrayOfWeatherData 
      WeatherData 
      WeatherForecasts 

這將是很容易解析。同樣,每種方法都與它們的參數以及它們的類型一起列出。你甚至可以用正則表達式來提取你需要的信息。

24

好的,所以SUDS有相當的魔力。

一個suds.client.Client,從WSDL文件構建:

client = suds.client.Client("http://mssoapinterop.org/asmx/simple.asmx?WSDL") 

它下載的WSDL,並創建client.wsdl的定義。當你通過client.service.<method>調用一個使用SUDS的方法時,它實際上在幕後對這個解釋的WSDL做了大量的遞歸解決魔法。爲了發現你需要反思這個對象的方法的參數和類型。

例如:

for method in client.wsdl.services[0].ports[0].methods.values(): 
    print '%s(%s)' % (method.name, ', '.join('%s: %s' % (part.type, part.name) for part in method.soap.input.body.parts)) 

這應該打印出類似這樣:

echoInteger((u'int', http://www.w3.org/2001/XMLSchema): inputInteger) 
echoFloatArray((u'ArrayOfFloat', http://soapinterop.org/): inputFloatArray) 
echoVoid() 
echoDecimal((u'decimal', http://www.w3.org/2001/XMLSchema): inputDecimal) 
echoStructArray((u'ArrayOfSOAPStruct', http://soapinterop.org/xsd): inputStructArray) 
echoIntegerArray((u'ArrayOfInt', http://soapinterop.org/): inputIntegerArray) 
echoBase64((u'base64Binary', http://www.w3.org/2001/XMLSchema): inputBase64) 
echoHexBinary((u'hexBinary', http://www.w3.org/2001/XMLSchema): inputHexBinary) 
echoBoolean((u'boolean', http://www.w3.org/2001/XMLSchema): inputBoolean) 
echoStringArray((u'ArrayOfString', http://soapinterop.org/): inputStringArray) 
echoStruct((u'SOAPStruct', http://soapinterop.org/xsd): inputStruct) 
echoDate((u'dateTime', http://www.w3.org/2001/XMLSchema): inputDate) 
echoFloat((u'float', http://www.w3.org/2001/XMLSchema): inputFloat) 
echoString((u'string', http://www.w3.org/2001/XMLSchema): inputString) 

所以該部分的類型元組的第一個元素可能是你追求的:

>>> client.factory.create(u'ArrayOfInt') 
(ArrayOfInt){ 
    _arrayType = "" 
    _offset = "" 
    _id = "" 
    _href = "" 
    _arrayType = "" 
} 

更新:

對於天氣服務出現的「參數」與一個element不是type部分:

>>> client = suds.client.Client('http://www.webservicex.net/WeatherForecast.asmx?WSDL') 
>>> client.wsdl.services[0].ports[0].methods.values()[0].soap.input.body.parts[0].element 
(u'GetWeatherByZipCode', http://www.webservicex.net) 
>>> client.factory.create(u'GetWeatherByZipCode') 
(GetWeatherByZipCode){ 
    ZipCode = None 
} 

但這magic'd到方法調用(一拉client.service.GetWeatherByZipCode("12345")的參數。 IIRC這是SOAP RPC綁定風格嗎?我想這裏有足夠的信息讓你開始。提示:Python命令行界面是你的朋友!

+1

出於某種原因,這些都是「無」與我一起工作的WSDL,所以我沒有得到的參數或類型,但是,它們在str(客戶端)中顯示,並且具有參數和類型。 – Wyrmwood 2015-07-28 17:02:23

8

下面是我根據上述信息編寫的一個快速腳本,其中列出了WSDL上可用的輸入方法泡沫報告。傳入WSDL URL。爲我目前正在進行的項目工作,我無法保證爲您的項目。

import suds 

def list_all(url): 
    client = suds.client.Client(url) 
    for service in client.wsdl.services: 
     for port in service.ports: 
      methods = port.methods.values() 
      for method in methods: 
       print(method.name) 
       for part in method.soap.input.body.parts: 
        part_type = part.type 
        if(not part_type): 
         part_type = part.element[0] 
        print(' ' + str(part.name) + ': ' + str(part_type)) 
        o = client.factory.create(part_type) 
        print(' ' + str(o)) 
+0

謝謝!作品也爲我:) – 2015-06-16 07:49:45

3

您可以訪問泡沫的服務定義對象。下面是一個簡單示例:

from suds.client import Client 
c = Client('http://some/wsdl/link') 

types = c.sd[0].types 

現在,如果你想知道一個類型的前綴名稱,這也是非常容易的:

c.sd[0].xlate(c.sd[0].types[0][0]) 

這雙括號標記是因爲類型列表(因此第一個[0]),然後在這個列表上的每個項目中可能有兩個項目。但是,泡沫的內部實現__unicode__正是這麼做的(即取名單上只有第一項):

s.append('Types (%d):' % len(self.types)) 
    for t in self.types: 
     s.append(indent(4)) 
     s.append(self.xlate(t[0])) 

快樂編碼;)

0

一旦你創建了WSDL方法的對象你可以從它的相關信息它是__metadata__,包括參數名稱的列表。

給定參數名稱,您可以在創建的方法中訪問它的實際實例。該實例還包括它在__metadata__信息,那裏你可以得到它的類型名稱

# creating method object 
method = client.factory.create('YourMethod') 
# getting list of arguments' names 
arg_names = method.__metadata__.ordering 
# getting types of those arguments 
types = [method.__getitem__(arg).__metadata__.sxtype.name for arg in arg_names] 

免責聲明:複雜的WSDL類型這隻作品。簡單的類型,如字符串和數字,都默認爲無

0
from suds.client import Client 
url = 'http://localhost:1234/sami/2009/08/reporting?wsdl' 
client = Client(url) 
functions = [m for m in client.wsdl.services[0].ports[0].methods] 
count = 0 
for function_name in functions: 
    print (function_name) 
    count+=1 
print ("\nNumber of services exposed : " ,count)