spyne - 在服务定义中使用默认参数

时间:2014-12-29 17:23:22

标签: python web-services soap spyne soaplib

我使用Spyne并且效果很好。我希望能够为我的可选参数使用默认值。据我了解,每种类型都可以使用其强制形式:我是对的吗?

这是我的服务:

from spyne.model.primitive import Unicode, Boolean

@rpc(Unicode, _returns = Unicode)
def optional_parameter(ctx, input = "default value")
    return input

当我在没有参数的情况下调用它时,它什么也没有返回,就像我用“'' (空字符串)。

SOAP INPUT(来自SoapUI):

<soapenv:Body>
  <spy:optional_parameter>
     <!--Optional:-->
     <spy:input/>
  </spy:optional_parameter>
</soapenv:Body>

SOAP OUTPUT:

<senv:Body>
   <tns:optional_parameterResponse>
      <tns:optional_parameterResult/>
   </tns:optional_parameterResponse>
</senv:Body>

布尔值最差,这是另一项服务:

@rpc(Boolean, _returns = Boolean)
def optional_parameter_second(ctx, input = False)
    return input

在那里,当我使用SoapUI调用我的服务时,我收到以下错误:

输入请求:

<soapenv:Body>
  <spy:optional_parameter>
     <!--Optional:-->
     <spy:input/>
  </spy:optional_parameter>
</soapenv:Body>

输出:

  <senv:Fault>
     <faultcode>senv:Client.SchemaValidationError</faultcode>
     <faultstring>:10:0:ERROR:SCHEMASV:SCHEMAV_CVC_DATATYPE_VALID_1_2_1: Element '{spyne.examples.hello}input': '' is not a valid value of the atomic type 'xs:boolean'.</faultstring>
     <faultactor/>
  </senv:Fault>

你有什么想法帮助我吗?

我使用的是Spyne 2.11.0

2 个答案:

答案 0 :(得分:2)

在spyne中,默认情况下,所有参数都是可选的(min_occurs=0nillable=True)。

当一个参数从请求中省略时,Spyne无论如何都将它传递给None,因此从不使用Python的默认参数。您应该将default kwarg传递给类型标记。

示例:

@rpc(Unicode(default='default value'), _returns=Unicode)
def optional_parameter(ctx, input)
    return input

这就是说,请考虑以下摘录:

<soapenv:Body>
  <spy:optional_parameter>
     <spy:input/>
  </spy:optional_parameter>
</soapenv:Body>

你没有在这里传递一个缺失的参数,你传递了一个空字符串("")。如果要省略该参数,则必须省略该标记。这意味着:

<soapenv:Body>
  <spy:optional_parameter/>
</soapenv:Body>

此处,标签内容也是一个空字符串,但由于Soap处理器正在寻找子元素而不是标签内容,因此它与此无关。

如果你想传递一个明确的null,请按照以下方式进行:

<soapenv:Body>
  <spy:optional_parameter>
     <spy:input xmlns:xsi="http://w3.org/2001/XMLSchema-instance" xmlns:xsi="" xsi:nil="true"/>
  </spy:optional_parameter>
</soapenv:Body>

请注意,即使传递了显式null,Spyne 2.11仍然会使用默认值。

请参阅:https://github.com/arskom/spyne/blob/79f8120668ec471097f410e63fa48cdf797fae7a/spyne/protocol/xml.py#L378

我不确定这是一个错误还是一个功能:)

答案 1 :(得分:0)

我发现了一种看似干净的方式:

使用默认布尔值的服务实现:

def optional_parameter_second(ctx, input):
    if input is not None:
        return my_method(input)
    else:
        return my_method()

def my_method(param = True):
    return param

来自soapUI的调用不得包含标记

<soapenv:Body>
  <spy:optional_parameter>
     <!--Optional:-->
   </spy:optional_parameter>
 </soapenv:Body>

它就像一个魅力

<senv:Body>
  <tns:optional_booleanResponse>
     <tns:optional_booleanResult>true</tns:optional_booleanResult>
  </tns:optional_booleanResponse>
</senv:Body>