【问题标题】:Which python soap client supports spyne binary types?哪个 python soap 客户端支持 spyne 二进制类型?
【发布时间】:2016-12-05 22:51:46
【问题描述】:

我想调用一个以 spyne 二进制类型作为参数的 Web 服务方法。 但我找不到任何支持它的 python soap 客户端。

为了调试我的问题,我做了一个简单的 web 服务方法,应该打印一个文件:



    #     @srpc(Attachment, _returns=Unicode)
        @srpc(ByteArray, _returns=Unicode)
    #     @srpc(File, _returns=Unicode)
    #     @srpc(Unicode, _returns=Unicode)
        def print_file(file_content):
            logger.info(u"print file:\n{}\ntype:{}".format(file_content, file_content.__class__))

            return u''

如您所见,我尝试了 3 种 spyne 二进制类型。 对于调试,我也尝试使用 Unicode,并以 base64 传递文件内容,在这种情况下没有问题。 这样 Web 服务就可以运行了。

服务器端是一个 Django 应用程序和一个 spyne 应用程序。 我的问题在客户端。 使用suds,得到的错误很模糊,根据论坛没有解决方案。

我使用 python 2.7 和 3.3 尝试了https://wiki.python.org/moin/WebServices#SOAP 中描述的所有 SOAP 客户端。 在构建请求、序列化 spyne 二进制对象时,它们都失败了。

我最后一次尝试是使用 zeep。 我用 wsdl 本地 url 实例化 zeep 客户端。 抱歉,wsdl 不公开。

我用一个空的 ByteArray 调用这个方法:

param = ByteArray()
client.service.print_file(param)

捕获的异常是:



        File "/usr/lib/python2.7/site-packages/zeep/client.py", line 41, in __call__
            self._op_name, args, kwargs)
        File "/usr/lib/python2.7/site-packages/zeep/wsdl/bindings/soap.py", line 107, in send
            options=options)
        File "/usr/lib/python2.7/site-packages/zeep/wsdl/bindings/soap.py", line 65, in _create
            serialized = operation_obj.create(*args, **kwargs)
        File "/usr/lib/python2.7/site-packages/zeep/wsdl/definitions.py", line 165, in create
            return self.input.serialize(*args, **kwargs)
        File "/usr/lib/python2.7/site-packages/zeep/wsdl/messages/soap.py", line 48, in serialize
            self.body.render(body, body_value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/elements.py", line 333, in render
            self._render_value_item(parent, value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/elements.py", line 354, in _render_value_item
            return self.type.render(node, value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/types.py", line 356, in render
            element.render(parent, element_value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/indicators.py", line 189, in render
            element.render(parent, element_value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/elements.py", line 333, in render
            self._render_value_item(parent, value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/elements.py", line 354, in _render_value_item
            return self.type.render(node, value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/types.py", line 180, in render
            parent.text = self.xmlvalue(value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/builtins.py", line 83, in _wrapper
            return func(self, value)
        File "/usr/lib/python2.7/site-packages/zeep/xsd/builtins.py", line 357, in xmlvalue
            return base64.b64encode(value)
        File "/usr/lib64/python2.7/base64.py", line 53, in b64encode
            encoded = binascii.b2a_base64(s)[:-1]
    TypeError: must be convertible to a buffer, not ModelBaseMeta


有人知道 zeep 是否有解决方案吗?
也许使用专用的 zeep 插件?

或者还有其他解决方案吗?
也许在 C/C++ 中,编译为 python 包?

埃里克

================================================ ==============
== 解决方案

由于我在这个问题上浪费了很多时间,这里是我的解决方案。

最后我还需要文件名,而不仅仅是文件数据。 spyne.model.binary.File 类型本来是完美的,但它不能序列化为 SOAP 格式。

感谢与 Burak 的讨论,最终的解决方案是创建一个自定义的 ComplexType,如:



class File(ComplexModel):
    filename = Unicode
    data = ByteArray

在客户端使用 suds,直接将 ByteArray 字段替换为 base64 编码的数据:



    f = File()
    data = open({FILENAME}, "rb").read()
    f.data = base64.b64encode(data)

在服务器端,f.data 将直接包含解码后的数据。

【问题讨论】:

    标签: soap client suds spyne zeep


    【解决方案1】:

    【讨论】:

    • 非常感谢。我没有尝试绕过 ByteArray 类型并用 b64encode 的结果替换它。
    • ByteArray 不是一个值,它只是一个类型标记。与 ByteArray 兼容的本机值是字节序列。例如。让class A(ComplexModel): a=ByteArray; 你应该做A(a=[b"\x00\x01 etc.."]) 以正确地将二进制数据分配给一个类。
    【解决方案2】:

    Zeep 应该可以很好地处理字节,我刚刚针对 spyne 服务器进行了测试。

    例如service.client.echo_bytearray(b'\x00\x01\x02\x03\x04') 没有问题。你有更多信息吗?

    干杯,迈克尔(zeep 的作者)

    【讨论】:

    • 感谢迈克尔抽出宝贵时间。作为 Burak,您直接使用字节调用 Web 服务,而不是使用 ByteArray 对象。如果您尝试传递一个 ByteArray 对象,它将不起作用。这是我的错。
    猜你喜欢
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 2012-02-15
    • 2013-04-04
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多