SUDS - программный доступ к методам и типам - PullRequest
21 голосов
/ 28 октября 2008

Я исследую SUDS как клиент SOAP для python. Я хочу проверить методы, доступные в указанной службе, и типы, требуемые для указанного метода.

Целью является создание пользовательского интерфейса, позволяющего пользователям выбирать метод, а затем заполнять значения в динамически генерируемой форме.

Я могу получить некоторую информацию о конкретном методе, но не знаю, как его проанализировать:

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

Я не могу программно выяснить, какой тип объекта мне нужно создать, чтобы иметь возможность вызвать службу

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

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

У кого-нибудь есть пример кода?

Ответы [ 6 ]

27 голосов
/ 07 декабря 2009

Хорошо, так что SUDS делает немного магии.

A suds.client.Client, построен из файла WSDL:

client = suds.client.Client("http://mssoapinterop.org/asmx/simple.asmx?WSDL")

Он загружает WSDL и создает определение в client.wsdl. Когда вы вызываете метод, использующий SUDS через client.service.<method>, он фактически делает много рекурсивного волшебства разрешения за кулисами против этого интерпретируемого 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 = ""
 }

Обновление:

Для службы погоды представляется, что «параметры» являются частью с 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
 }

Но это волшебство в параметрах вызова метода (а-ля client.service.GetWeatherByZipCode("12345"). IIRC, это стиль связывания SOAP RPC? Думаю, здесь достаточно информации, чтобы начать работу. Подсказка: интерфейс командной строки Python твой друг!

19 голосов
/ 03 декабря 2009

Согласно suds документации , вы можете проверить service объект с помощью __str()__. Таким образом, следующее получает список методов и сложных типов:

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

Это было бы намного легче разобрать. Также каждый метод перечислен с их параметрами наряду с их типами. Возможно, вы могли бы даже использовать регулярное выражение для извлечения необходимой вам информации.

8 голосов
/ 17 мая 2013

Вот быстрый скрипт, который я написал на основе приведенной выше информации для перечисления отчетов о методах ввода suds, доступных на WSDL. Передайте URL WSDL. Работает над проектом, в котором я сейчас работаю, я не могу гарантировать его за вас.

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))
3 голосов
/ 24 июля 2013

Вы можете получить доступ к объекту ServiceDefinition suds. Вот быстрый пример:

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]), а затем в каждом элементе этого списка может быть два элемента. Однако внутренняя реализация suds __unicode__ делает именно это (то есть занимает только первый элемент в списке):

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

Удачного кодирования;)

0 голосов
/ 23 ноября 2016
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 голосов
/ 23 декабря 2015

После создания объекта метода 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. Простые типы, такие как строки и числа, по умолчанию имеют значение Нет

...