Python suds mal nombre de prefijo en la solicitud SOAP

Utilizo python / suds para implementar un cliente y obtengo prefijos de espacio de nombres incorrectos en el encabezado SOAP enviado para un tipo de parámetros definido por el element ref= en el wsdl.

.Wsdl hace referencia a un archivo .xsd de tipos de datos, consulte a continuación. El problema es con la función GetRecordAttributes y su primer argumento de tipo gbt:recordReferences .

Archivo: browse2.wsdl

        

Archivo de referencia: grantabasetypes2.xsd

        

Solicitud de SOAP enviada por suds:

            

Problema : tiene un prefijo incorrecto, debe ser ya que pertenece al espacio de nombres ...GrantaBaseTypes definidos en .xsd.

Esto sucede para todos los argumentos definidos por ref= en el wsdl. ¿Cómo se puede arreglar esto automáticamente?

Nota: Verifiqué que el prefijo “bueno” es aceptado por el servicio mediante el envío manual de la solicitud SOAP xml a través de curl.

ACTUALIZAR

Me mezclé con el código fuente de SUDS y la siguiente solución empírica obliga a todos los elementos con ref= atributo a asumir el espacio de nombres ref-ed (anteriormente, toman el espacio de nombres de la raíz del esquema o lo que sea tns ):

Archivo: /suds/xsd/sxbase.py

 class SchemaObject(object): .... def namespace(self, prefix=None): ns = self.schema.tns #FIX BEGIN if self.ref and self.ref in self.schema.elements.keys(): ns = self.ref #FIX END 

Funciona con mi servicio, pero no estoy seguro si romperá otras cosas. Preferiría una solución más inteligente que no cambie el código fuente de SUDS.

Gracias,

Alex

Escriba un complemento de Suds para modificar el XML antes de enviarlo.

 from suds.client import Client from suds.plugin import MessagePlugin class MyPlugin(MessagePlugin): def marshalled(self, context): #modify this line to reliably find the "recordReferences" element context.envelope[1][0][0].setPrefix('ns0') client = Client(WSDL_URL, plugins=[MyPlugin()]) 

Citando la documentación de Suds:

marshalled ()
Proporciona al complemento la oportunidad de inspeccionar / modificar el documento del sobre antes de enviarlo.

Tuve el mismo problema al usar la espuma para acceder a un servicio BizTalk / IIS SOAP. Por lo que puedo decir del WSDL, ocurre cuando hay un “complexType” que no es parte del “targetNamespace” (tiene su propio nombre), que tiene un hijo que también es complexType, pero sin un conjunto de espacio de nombres. En BizTalk, esto significa que el niño debe pertenecer al mismo espacio de nombres que el padre, pero los Suds parecen pensar que debería ser parte del targetNamespace …

La solución en el código fuente resolvió la cosa “correctamente”, pero como quiero poder actualizar sin aplicar la solución cada vez que busco otra solución …

Mi solución fue omitir Suds y simplemente copiar el XML sin formato, usarlo como plantilla y copiar los valores en él … No es hermoso, pero al menos simple. La solución para agregar un complemento es, en mi opinión, igualmente codificada y quizás aún más difícil de mantener.

Podría crear un mensaje de soap usted mismo y usar SoapClient para enviar el mensaje:

 sc = SoapClient(cli.service.XXXMethod.client,cli.service.XXXMethod.method) sc.send(some_soap_doc) 

Prefiero expresiones regulares 🙂

 import re class EnvelopeFixer(MessagePlugin): def sending(self, context): # rimuovi i prefissi context.envelope = re.sub( 'ns[0-9]:', '', context.envelope ) return context.envelope