web-dev-qa-db-ja.com

SUDS-メソッドとタイプへのプログラムによるアクセス

SUDSをSOAP Pythonのクライアントとして調査しています。指定されたサービスから利用できるメソッドと、指定されたメソッドに必要なタイプを調べたいと思います。

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

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

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

programmaticalyサービスを呼び出すために作成する必要のあるオブジェクトタイプを把握できません

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

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

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

21
GHZ

さて、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 = ""
 }
_

更新:

Weatherサービスの場合、「パラメータ」は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コマンドラインインターフェイスはあなたの友達です!

27
sj26

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

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

19
artdanil

上記の情報に基づいて作成した簡単なスクリプトを使用して、WSDLで使用可能な入力メソッドsudsレポートを一覧表示します。 WSDLURLを渡します。私が現在取り組んでいるプロジェクトで動作します。あなたのプロジェクトを保証することはできません。

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))
8
gbutler

SudsのServiceDefinitionオブジェクトにアクセスできます。簡単なサンプルは次のとおりです。

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])であり、このリストの各項目に2つの項目がある可能性があるためです。ただし、sudsの__unicode__の内部実装は、まさにそれを実行します(つまり、リストの最初の項目のみを取得します)。

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

ハッピーコーディング;)

3
toudi
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)
0
SAMI UL HUDA

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
fomars