spyne — использовать параметры по умолчанию в определениях сервисов

Я использую Spyne, и он работает хорошо. Я хотел бы иметь возможность использовать значения по умолчанию для моих дополнительных параметров. Насколько я понимаю, каждый тип можно использовать в своей обязательной форме или нет: я прав?

Вот мой сервис:

from spyne.model.primitive import Unicode, Boolean

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

Когда я вызываю его без параметра, он ничего не возвращает, точно так же, как если бы я вызывал его с '' (пустая строка).

МЫЛЬНЫЙ ВВОД (из SoapUI):

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

ВЫВОД МЫЛА:

<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


person Julien Greard    schedule 29.12.2014    source источник


Ответы (2)


В spyne по умолчанию все параметры являются необязательными (min_occurs=0 и nillable=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 ищет подэлементы, а не содержимое тега, это здесь не имеет значения.

Если вы хотите передать явный нуль, вот как вы это делаете:

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

Обратите внимание, что Spyne 2.11 по-прежнему будет использовать значение по умолчанию, если оно у вас есть, даже если передается явное значение null.

См.: https://github.com/arskom/spyne/blob/79f8120668ec471097f410e63fa48cdf797fae7a/spyne/protocol/xml.py#L378

Не знаю, баг это или фича :)

person Burak Arslan    schedule 01.01.2015

Я узнал один способ, который кажется чистым:

Реализация службы с логическим значением по умолчанию:

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>
person Julien Greard    schedule 30.12.2014