1

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

为了调试我的问题,我做了一个简单的 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 将直接包含解码的数据。

4

2 回答 2

0

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

例如 service.client.echo_bytearray(b'\x00\x01\x02\x03\x04') 可以正常工作。你有更多信息吗?

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

于 2016-12-09T21:49:25.640 回答
0

完整答案在这里: http: //lists.spyne.io/archives/people/2016-December/000187.html

为了完整性;如果您手动执行 base64 操作,则可以使用 suds。见https://github.com/arskom/spyne/blob/be222c041837c9f7cd1e6e6e455e6704b5069837/spyne/test/interop/test_suds.py#L111

于 2016-12-08T11:36:15.497 回答