python序列化SOAP文件中的ascii错误

时间:2013-04-02 00:22:33

标签: python soap unicode suds

我正在为一个API的肥皂包装工作(我知道REST存在......这是我工作中的一个项目),我正在使用SUDS库。

我发现了this问题,答案对我帮助很大。在尝试了几件事后,稍微修改了那个问题指向我的脚本,我得到了以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x82 in position 2159: ordinal not in range(128)

当将请求发送到SOAP端点时会发生这种情况,我尝试使用带有NFKD选项的unicodedata来规范化它,但我仍然得到相同的错误。

由于这不是一个简单的文本,这是来自音频文件的实际数据,我不确定,但我想修改它应该会破坏实际数据,所以我不知道该怎么做。

这就是我正在做的事情,这与其他问题的程序没有什么不同:

file = open('path/to/the/file.mp3', 'rb')
mime_type = 'audio/mpeg'
audio_data = file.read()
bin_param = (audio_data, uuid.uuid4(), mime_type)

with_soap_attachment(client.service.set_greeting, bin_param, request_data)

据我所知,脚本将所有输入参数转换为SOAP消息字符串,然后将其封装到Request对象中并将其发送到SOAP端点,因此,问题是audio_data包含无效的ascii字符。 / p>

这里有任何线索吗?

编辑:04/04/2013

以下是包装器的实际代码

#coding: utf-8
from suds.transport import Request
import re
import uuid

def with_soap_attachment(suds_method, attachment_data, soap_location, *args, **kwargs):
    MIME_DEFAULT = 'text/plain'
    attachment_transfer_encoding = 'binary'
    soap_method = suds_method.method

    if len(attachment_data) == 3:
        data, attachment_id, attachment_mimetype = attachment_data
    elif len(attachment_data) == 2:
        data, attachment_mimetype = attachment_data
        attachment_id = uuid.uuid4()
    elif len(attachment_data) == 1:
        data = attachment_data
        attachment_mimetype = MIME_DEFAULT
        attachment_id = uuid.uuid4()

    soap_client = suds_method.clientclass(kwargs)
    binding = soap_method.binding.input
    soap_xml = binding.get_message(soap_method, args, kwargs)

    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,
      '',
    ])

    request_text = '\n'.join([
      '',
      '--%s' % boundary_id,
      soap_headers,
      unicode(soap_xml),
      '--%s' % boundary_id,
      attachment_headers,
      data,
      '--%s--' % boundary_id
    ])

    location = soap_location

    headers = suds_method.client.options.headers.copy()
    headers.update(request_headers)
    request = Request(location, request_text)
    request.headers = headers

    response = suds_method.client.options.transport.send(request)
    return response

这是整个追溯

---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 soap_attachments.with_soap_attachment(service.set_menu_prompt, bin_param, AUTOATTENDANT_ENDPOINT, request)

/home/israelord/Work/4geeks/ringtu/ringtu/services/soap_attachments.py in with_soap_attachment(suds_method, attachment_data, soap_location, *args, **kwargs)
     54       attachment_headers,
     55       data,
---> 56       '--%s--' % boundary_id
     57     ])
     58 

UnicodeDecodeError: 'ascii' codec can't decode byte 0x82 in position 148: ordinal not in range(128)

1 个答案:

答案 0 :(得分:1)

好吧,包装器不支持二进制文件,因为它只使用Content-Transfer-Encoding: 8bit,这当然不能用于二进制文件。您可能需要修改它,参考SOAP-attachments规范。