23

Python の SOAP クライアントとして SUDS を調査しています。指定されたサービスから利用可能なメソッドと、指定されたメソッドに必要な型を検査したいと考えています。

目的は、ユーザー インターフェイスを生成して、ユーザーがメソッドを選択し、動的に生成されたフォームに値を入力できるようにすることです。

特定のメソッドに関する情報を取得できますが、それを解析する方法がわかりません:

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

サービスを呼び出すために作成する必要があるオブジェクトの種類をプログラムで把握することができません

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

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

誰かサンプルコードを持っていますか?

4

8 に答える 8

29

さて、SUDS はかなりの魔法を行います。

suds.client.ClientWSDL ファイルから作成されます。

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

WSDL をダウンロードし、 に定義を作成しますclient.wsdl。SUDS を使用してメソッドを呼び出すと、client.service.<method>実際には、その解釈された 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
 }

しかし、これはメソッド呼び出しのパラメーターに魔法のように組み込まれています (a la client.service.GetWeatherByZipCode("12345"). IIRC これは SOAP RPC バインディング スタイルですか? 始めるのに十分な情報がここにあると思います。ヒント: Python コマンド ライン インターフェイスはあなたの友達です!

于 2009-12-07T06:12:25.547 に答える
20

suds ドキュメントによると、serviceオブジェクトは で検査できます__str()__。したがって、以下はメソッドと複合型のリストを取得します。

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

これにより、解析がはるかに簡単になります。また、すべてのメソッドは、そのタイプとともにパラメーターとともにリストされます。おそらく、正規表現だけを使用して必要な情報を抽出することもできます。

于 2009-12-03T20:46:55.580 に答える
9

上記の情報に基づいて、入力メソッド suds レポートを 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))
于 2013-05-17T19:25:56.857 に答える
1
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)
于 2016-11-23T10:42:42.387 に答える
1

__metadata__WSDL メソッド オブジェクトを作成すると、引数の名前のリストなど、オブジェクトに関する情報を から取得できます。

引数の名前を指定すると、作成されたメソッドで実際のインスタンスにアクセスできます。そのインスタンスには の情報も含まれており__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 タイプでのみ機能します。文字列や数値などの単純な型は、デフォルトで None に設定されます

于 2015-12-23T20:01:30.083 に答える
0

オブジェクトで泡を使用する例が必要でした。ここで見つかった回答に加えて 、私の質問にさらに回答する非常に優れた記事を見つけました。

ここに短い要約があります:

まず、クライアントを印刷して内容の概要を確認します。

from suds.client import Client client =
Client("https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl")
print client

次に、タイプのインスタンスを作成し (接頭辞 ns* を含む名前を使用)、それを出力してメンバー データを確認します。

HeaderMessage = client.factory.create('ns0:HeaderMessage')
print HeaderMessage

オブジェクトのデータ メンバーを埋めるには、スカラー メンバーのスカラー値または dict をオブジェクト メンバーに割り当てます。

HeaderMessage.Context =  {
     "CatalogID": "XXXXX"
     "CustomerID": 'XXXXX'
     "SiteID": 123
 }

型名が ArrayOf で始まるメンバーは、型名の残りの部分で言及されている型のオブジェクトのリストを期待します。

ArrayOfDomainRights = client.factory.create('ns0:ArrayOfDomainRights')
ArrayOfDomainRights.DomainRights = [XXXXXXXXXXXXX, XXXXXXXXXXXX]
于 2020-05-16T20:04:55.567 に答える