jurko example alternative python suds

python - example - suds-jurko



SUDS: acceso programático a métodos y tipos (6)

Estoy investigando SUDS como un cliente SOAP para Python. Quiero inspeccionar los métodos disponibles de un servicio específico y los tipos requeridos por un método específico.

El objetivo es generar una interfaz de usuario, que permita a los usuarios seleccionar un método, y luego completar los valores en una forma generada dinámicamente.

Puedo obtener información sobre un método en particular, pero no estoy seguro de cómo analizarlo:

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

No puedo averiguar programáticamente qué tipo de objeto necesito crear para poder llamar al servicio

obj = client.factory.create(''?'') res = client.service.MyMethod(obj, soapheaders=authen)

¿Alguien tiene algún código de muestra?


De acuerdo con la documentación de la suds , puede inspeccionar el objeto de service con __str()__ . Entonces, lo siguiente obtiene una lista de métodos y tipos complejos:

from suds.client import Client; url = ''http://www.webservicex.net/WeatherForecast.asmx?WSDL'' client = Client(url) temp = str(client);

El código anterior produce el siguiente resultado (contenido de 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

Esto sería mucho más fácil de analizar. Además, cada método se enumera con sus parámetros junto con sus tipos. Probablemente, incluso podría usar expresiones regulares para extraer la información que necesita.


Aquí hay una secuencia de comandos rápida que escribí en base a la información anterior para listar los informes de los métodos de entrada como disponibles en un WSDL. Pase en la URL WSDL. Funciona para el proyecto en el que estoy actualmente, no puedo garantizarlo para el suyo.

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


De acuerdo, SUDS hace un poco de magia.

Un suds.client.Client , se construye a partir de un archivo WSDL:

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

Descarga el WSDL y crea una definición en client.wsdl . Cuando llamas a un método usando SUDS a través de client.service.<method> , en realidad está haciendo una gran cantidad de magia de resolución recursiva detrás de la escena contra ese WSDL interpretado. Para descubrir los parámetros y tipos de métodos, deberá introspectar este objeto.

Por ejemplo:

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

Esto debería imprimir algo así como:

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)

Entonces, el primer elemento de la tupla de tipo de la parte es probablemente lo que busca:

>>> client.factory.create(u''ArrayOfInt'') (ArrayOfInt){ _arrayType = "" _offset = "" _id = "" _href = "" _arrayType = "" }

Actualizar:

Para el servicio Meteorológico, parece que los "parámetros" son una parte con un element no un 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 }

Pero esto está mágico en los parámetros de la llamada al método (a la client.service.GetWeatherByZipCode("12345") . IIRC este es el estilo de encuadernación RPC de SOAP? Creo que hay suficiente información aquí para comenzar. Sugerencia: Python interfaz de línea de comando es tu amigo!


Puede acceder al objeto ServiceDefinition de suds. Aquí hay una muestra rápida:

from suds.client import Client c = Client(''http://some/wsdl/link'') types = c.sd[0].types

Ahora, si quiere saber el nombre prefijado de un tipo, también es bastante fácil:

c.sd[0].xlate(c.sd[0].types[0][0])

Esta notación de doble corchete se debe a que los tipos son una lista (de ahí una primera [0]) y luego en cada elemento de esta lista puede haber dos elementos. Sin embargo, la implementación interna de suds de __unicode__ hace exactamente eso (es decir, toma solo el primer elemento en la lista):

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

Feliz codificación;)


Una vez que haya creado el objeto de método WSDL, puede obtener información sobre él a partir de su __metadata__ , incluida la lista de sus nombres de argumentos.

Dado el nombre del argumento, puede acceder a su instancia real en el método creado. Esa instancia también contiene su información en __metadata__ , allí puede obtener su nombre de tipo

# 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]

Descargo de responsabilidad: esto solo funciona con tipos de WSDL complejos. Los tipos simples, como cadenas y números, están predeterminados como Ninguno


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)