SUDSをSOAP Pythonのクライアントとして調査しています。指定されたサービスから利用できるメソッドと、指定されたメソッドに必要なタイプを調べたいと思います。
目的は、ユーザーインターフェイスを生成し、ユーザーがメソッドを選択して、動的に生成されたフォームに値を入力できるようにすることです。
特定のメソッドに関する情報を取得できますが、それを解析する方法がわかりません。
client = Client(url)
method = client.sd.service.methods['MyMethod']
programmaticalyサービスを呼び出すために作成する必要のあるオブジェクトタイプを把握できません
obj = client.factory.create('?')
res = client.service.MyMethod(obj, soapheaders=authen)
誰かがサンプルコードを持っていますか?
さて、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コマンドラインインターフェイスはあなたの友達です!
suds
documentation によると、__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
これは、解析がはるかに簡単になります。また、すべてのメソッドは、タイプとともにパラメーターとともにリストされています。おそらく、正規表現だけを使用して必要な情報を抽出することもできます。
上記の情報に基づいて作成した簡単なスクリプトを使用して、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))
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]))
ハッピーコーディング;)
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)
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タイプでのみ機能します。文字列や数値などの単純な型は、デフォルトで「なし」に設定されています