web-dev-qa-db-fra.com

Introspection d'un WSDL avec Python Zeep

J'essaie d'utiliser Zeep pour décrire les opérations et les types dans un WSDL donné, afin qu'un programme connaisse les noms des opérations, leurs noms de paramètres, les types de paramètres et les attributs de paramètres.

Ces informations seront utilisées pour générer dynamiquement une interface utilisateur pour un WSDL donné.

Ce que j'ai obtenu jusqu'à présent, c'est juste les représentations de chaîne des opérations et des types. Utiliser un code similaire à ce que l'on trouve dans cette réponse .

Voici un exemple:

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())

Cela donne une sortie comme la suivante (raccourci pour plus de brièveté)

[...]

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[])

Les représentations de chaîne renvoyées par .signature () ont les noms et les types, mais je ne sais pas comment les analyser individuellement. J'ai également essayé de boucler sur chaque objet attrs avec dir (), et ils ne contiennent pas ces informations. Il semble être imbriqué beaucoup plus profondément.

Je pourrais analyser les représentations de chaîne elles-mêmes, mais il me manque également si le paramètre est facultatif (plus précisément, s'il a l'attribut minOccurs = 0

Il semble que SOAPpy possède en fait cette fonctionnalité , mais n'est plus maintenu.

Existe-t-il un moyen d'introspection d'un WSDL avec zeep qui fournit des informations granulaires sur chaque opération, ses noms de paramètres, types et attributs similaires à l'implémentation SOAPpy? Ou dois-je analyser la signature, ou bien analyser le WSDL avec un analyseur XML standard.

9
jesse_galley

Vous pouvez accéder aux éléments de paramètre avec operation.input.body.type.elements, qui est une liste de tuples contenant des objets élément. Ces objets contiennent des informations telles que le type.

(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
3
jordanm

Sur la base de la réponse de jordanm, j'ai utilisé ce qui suit pour obtenir toutes les données dont j'avais besoin sur les méthodes disponibles

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