プログラムが操作名、パラメーター名、パラメーターの種類、およびパラメーターの属性を把握できるように、特定のWSDLでZeepを使用して操作と種類を記述しようとしています。
この情報は、特定のWSDLのUIを動的に生成するために使用されます。
私がこれまでに得たのは、操作と型の文字列表現です。 this answer にあるものと同様のコードを使用します。
以下に例を示します。
from zeep import Client
import operator
wsdl = 'http://webservices.Amazon.com/AWSECommerceService/AWSECommerceService.wsdl'
client = Client(wsdl)
# get each operation signature
for service in client.wsdl.services.values():
print("service:", service.name)
for port in service.ports.values():
operations = sorted(
port.binding._operations.values(),
key=operator.attrgetter('name'))
for operation in operations:
print("method :", operation.name)
print(" input :", operation.input.signature())
print()
print()
# get a specific type signature by name
complextype = client.get_type('ns0:CartGetRequest')
print(complextype.name)
print(complextype.signature())
これにより、次のような出力が得られます(簡潔にするために短縮されています)。
[...]
method : CartCreate
input : MarketplaceDomain: xsd:string, AWSAccessKeyId: xsd:string, AssociateTag: xsd:string, Validate: xsd:string, XMLEscaping: xsd:string, Shared: ns0:CartCreateRequest, Request: ns0:CartCreateRequest[]
method : CartGet
input : MarketplaceDomain: xsd:string, AWSAccessKeyId: xsd:string, AssociateTag: xsd:string, Validate: xsd:string, XMLEscaping: xsd:string, Shared: ns0:CartGetRequest, Request: ns0:CartGetRequest[]
[...]
CartGetRequest
{http://webservices.Amazon.com/AWSECommerceService/2011-08-01}CartGetRequest(CartId: xsd:string, HMAC: xsd:string, MergeCart: xsd:string, ResponseGroup: xsd:string[])
.signature()によって返される文字列表現には名前と型がありますが、それらを個別に解析する方法がわかりません。私もdir()で各オブジェクトattrsをループしようとしましたが、それらにはこの情報が含まれていません。深くネストされているようです。
文字列表現自体を解析することもできましたが、パラメーターがオプションであるかどうか(具体的には、属性minOccurs = 0である場合、
SOAPpyには実際にこの機能があります のように見えますが、もうメンテナンスされていません。
では、各操作に関する詳細な情報を提供するzeepでWSDLをイントロスペクトする方法はありますか?それは、SOAPpy実装と同様のパラメーター名、タイプ、属性です?または、署名を解析するか、通常のXMLパーサーでWSDLを解析する必要があります。
operation.input.body.type.elements
を使用してパラメーター要素にアクセスできます。これは、要素オブジェクトを含むタプルのリストです。これらのオブジェクトには、タイプなどの情報が含まれています。
(Pdb) operation.input.body.type.elements
[('MarketplaceDomain', <Element(name='MarketplaceDomain', type=<zeep.xsd.types.builtins.String object at 0x7f1bd8a4b320>)>), ('AWSAccessKeyId', <Element(name='AWSAccessKeyId', type=<zeep.xsd.types.builtins.String object at 0x7f1bd8a4b320>)>), ('AssociateTag', <Element(name='AssociateTag', type=<zeep.xsd.types.builtins.String object at 0x7f1bd8a4b320>)>), ('Validate', <Element(name='Validate', type=<zeep.xsd.types.builtins.String object at 0x7f1bd8a4b320>)>), ('XMLEscaping', <Element(name='XMLEscaping', type=<zeep.xsd.types.builtins.String object at 0x7f1bd8a4b320>)>), ('Shared', <Element(name='Shared', type=<zeep.xsd.dynamic_types.BrowseNodeLookupRequest object at 0x7f1bd8177e48>)>), ('Request', <Element(name='Request', type=<zeep.xsd.dynamic_types.BrowseNodeLookupRequest object at 0x7f1bd8177e48>)>)]
(Pdb) operation.input.body.type.elements[0][1].name
'MarketplaceDomain'
(Pdb) operation.input.body.type.elements[0][1].type.name
'string'
(Pdb) operation.input.body.type.elements[0][1].is_optional
True
Jordanmからの回答に基づいて、以下を使用して、使用可能なメソッドで必要なすべてのデータを取得しました
from zeep import Client
from pprint import pprint
wsdl = 'http://webservices.Amazon.com/AWSECommerceService/AWSECommerceService.wsdl'
client = Client(wsdl)
def parseElements(elements):
all_elements = {}
for name, element in elements:
all_elements[name] = {}
all_elements[name]['optional'] = element.is_optional
if hasattr(element.type, 'elements'):
all_elements[name]['type'] = parseElements(
element.type.elements)
else:
all_elements[name]['type'] = str(element.type)
return all_elements
interface = {}
for service in client.wsdl.services.values():
interface[service.name] = {}
for port in service.ports.values():
interface[service.name][port.name] = {}
operations = {}
for operation in port.binding._operations.values():
operations[operation.name] = {}
operations[operation.name]['input'] = {}
elements = operation.input.body.type.elements
operations[operation.name]['input'] = parseElements(elements)
interface[service.name][port.name]['operations'] = operations
pprint(interface)