[Python] SOAP & SOAP with attachment

Filadelfo Fiamma philosganga a gmail.com
Gio 7 Giu 2012 09:54:48 CEST


Buongiorno a tutti,

è ormai un certo periodo di tempo che utilizzo "Suds" come client soap per
python, trovandomi molto bene e avendo pochi problemi!
Sarei adesso interessato ad utilizzare SOAP with attachment, mio malgrado
ho scoperto che Suds non supporta, in modo esplicito, quest'estensione.
Non perdendomi d'animo ho trovato una discussione su stackoverflow in cui
si parla proprio di questo problema:

http://stackoverflow.com/questions/6601107/how-to-send-a-file-through-soap-in-python

Un tizio ha scritto una sorta di wrapper in grado di gestire i file
allegati (
https://d-feet.fedorahosted.org/suds/attachment/ticket/350/soap_attachments.2.py
 ).
Facendo una prova, ho da subito riscontrato un problema in merito alla riga
75 del sopracitato link, client.location() non è un metodo valido, ho però
sostituito quest'istruzione con client.options.location, che sembra essere
ciò che si vuole ottenere da quel fantomatico metodo..

In seguito ho testato un servizio di esempio (
http://soapclient.com/xml/soapresponder.wsdl ), non ottenendo errori ma
ottenendo una risposta non attesa: il wsdl stesso..

Chiedo, se qualcuno si è già addentrato in queste problematiche,
gentilmente un piccolo aiuto per capire dove ho sbagliato o meno!

mi permetto di postare di seguito il codice  che ho usato, grazie
anticipatamente a tutti!

#
http://stackoverflow.com/questions/6601107/how-to-send-a-file-through-soap-in-python
import re
import uuid
import mimetypes
from suds.client import Client
def with_soap_attachment(suds_method, attachment_data, *args, **kwargs):
    """ Add an attachment to a suds soap request.
    attachment_data is assumed to contain a list:
      ( <attachment content>, <content id>, <mime-type> )
    The attachment content is only required list element.
    """

    from suds.transport import Request
    # Suds doesn't currently support SOAP Attachments, so we have to build
our
    # own attachment support, using parts of the suds library
    MIME_DEFAULT = 'text/plain'
    attachment_transfer_encoding = '8bit'
    soap_method = suds_method.method
    if len(attachment_data) == 3:
        data, attachment_id, attachment_mimetype = attachment_data
    elif len(attachment_data) == 2:
        data, attachment_id = attachment_data
        attachment_mimetype = MIME_DEFAULT
    elif len(attachment_data) == 1:
        data = attachment_data
        attachment_mimetype = MIME_DEFAULT
        attachment_id = uuid.uuid4()
    # Generate SOAP XML appropriate for this request
    soap_client = suds_method.clientclass(kwargs)
    binding = soap_method.binding.input
    soap_xml = binding.get_message(soap_method, args, kwargs)

    # Prepare MIME headers & boundaries
    boundary_id = 'uuid:%s' % uuid.uuid4()
    root_part_id ='uuid:%s' % uuid.uuid4()
    request_headers = {
      'Content-Type': '; '.join([
          'multipart/related',
          'type="text/xml"',
          'start="<%s>"' % root_part_id,
          'boundary="%s"' % boundary_id,
        ]),
    }
    soap_headers = '\n'.join([
      'Content-Type: text/xml; charset=UTF-8',
      'Content-Transfer-Encoding: 8bit',
      'Content-Id: <%s>' % root_part_id,
      '',
    ])
    attachment_headers = '\n'.join([
      'Content-Type: %s' % attachment_mimetype,
      'Content-Transfer-Encoding: %s' % attachment_transfer_encoding,
      'Content-Id: <%s>' % attachment_id,
      '',
    ])
    # Build the full request
    request_text = '\n'.join([
      '',
      '--%s' % boundary_id,
      soap_headers,
      str(soap_xml),
      '--%s' % boundary_id,
      attachment_headers,
      data,
      '--%s--' % boundary_id
    ])
    # Stuff everything into a request object
    headers = suds_method.client.options.headers.copy()
    headers.update(request_headers)
    request = Request(suds_method.client.options.location, request_text)
    #print str(request_text)+'****'
    request.headers = headers
    #print str(request.headers)+'****'
    # Send the request
    response = suds_method.client.options.transport.send(request)
    return response


if __name__ == '__main__':
infile = 'C:/Documents and
Settings/filo/Desktop/test_soap_with_attachment.py'
f = open(infile,'rb')
data_file = f.read().encode("base64")
data_file_type = mimetypes.guess_type(infile)[0]
(filename,ext) = infile.split('.')
 url =  "http://soapclient.com/xml/soapresponder.wsdl"
cl = Client(url,location=url)
 identifier = with_soap_attachment(cl.service.Method1, [data_file, '1',
data_file_type],"ciao","ciao")
 print identifier.message
-- 

FF
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20120607/e151d326/attachment.html>


Maggiori informazioni sulla lista Python