【问题标题】:ascii error in python serializing a file for SOAPpython序列化SOAP文件中的ascii错误
【发布时间】:2013-04-02 00:22:32
【问题描述】:

我正在为 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 字符。

这里有什么线索吗?

编辑:2013 年 4 月 4 日

这是包装器的实际代码

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

【问题讨论】:

  • 尝试将audio_data = file.read() 替换为audio_data = file.read().encode('utf8')。看看这是否有效。
  • @IonutHulub file.read() 已经返回 str
  • @wRAR 你不说?函数encode('utf8') 对字符串进行编码,以便“ascii”编解码器可以对其进行解码。我唯一担心的是数据会被破坏并且变得无法解释以供以后使用。
  • @IonutHulub 你不明白encode 是做什么的。

标签: python soap unicode suds


【解决方案1】:

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

【讨论】:

  • 感谢您的建议,我已经尝试过@lonutHulub 之前在其中一次“绝望的尝试”中所说的,但显然没有奏效。我没有从服务器收到传输错误,因为由于编码错误,请求永远不会发送。
  • 您对如何解决编码问题有什么建议吗?
  • 是的,我必须手动实现它,我将附件头上的 Content-Transfer-Encodinf 从 8 位更改为二进制,并在 Soap 头中将其保留为 8 位,如此处所述w3.org/TR/SOAP-attachments ,非常感谢,但我仍然收到编码错误。
  • 您好,该文件已经包含#coding: utf-8 注释头。问题在于数据本身,我对其进行了调试,问题在于它只是连接“数据”变量,其中包含来自 mp3 文件的字节。我用包装器的实际代码更新了我的问题。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多