0

私は API の SOAP ラッパーに取り組んでいます (REST が存在することは知っています... それは私の仕事のプロジェクトです)、そのために SUDS ライブラリを使用しています。

私はこの質問を見つけ、その答えは私を大いに助けてくれました。いくつかのことを試し、その質問が私に指摘したスクリプトを少し変更した後、次のエラーが発生しました。

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

1 に答える 1

1

ラッパーはバイナリ ファイルをサポートしていませんContent-Transfer-Encoding: 8bit。もちろん、バイナリ ファイルでは動作しないものだけを使用するからです。おそらく、SOAP 添付ファイルの仕様を参照して変更する必要があります。

于 2013-04-02T00:31:21.897 に答える