使用Python Zeep反思WSDL

时间:2018-04-29 17:26:44

标签: python soap wsdl zeep soappy

我试图使用Zeep来描述给定WSDL中的操作和类型,以便程序知道操作名称,参数名称,参数类型和参数属性。

此信息将用于动态生成给定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 actually has this functionality,但不再维护。

那么有没有办法用zeep内省WSDL,它提供有关每个操作的粒度信息,它的参数名称,类型和属性类似于SOAPpy实现?或者我应该解析签名,或者使用常规XML解析器解析WSDL。

2 个答案:

答案 0 :(得分:3)

根据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)

答案 1 :(得分:2)

您可以使用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 是包含元素对象的元组列表。这些对象包含类型等信息。

w= 2
h= 2
board = [[0] * h for i in range(w)]
def printboard():
    for row in board:
        print("  ".join([str(cell) for cell in row]))