Понимание декораторов RPC: сложные возвращаемые аргументы с SOAP и XML

Я новичок в создании веб-сервисов SOAP, и у меня есть вопрос о декораторах RPC.

В любом случае, мое намерение состоит в том, чтобы мой веб-сервис имел несколько сложный тип возврата (я полагаю, что это его полиморфный). Входным протоколом является SOAP, а выходным протоколом — XML.

Я хотел бы вернуть словарь, содержащий массив, каждый из которых имеет значения, которые могут быть либо числами с плавающей запятой, либо строками (см. строку 6 в коде ниже). Я понимаю, как это будет выглядеть в виде дерева элементов XML, однако я не знаю, как обозначить это в параметре _returns декоратора @rpc. Чтобы немного усложнить ситуацию, если клиент отправляет неверные учетные данные, я просто хотел бы вернуть строку «Неверные учетные данные». Или, возможно, было бы проще вернуть пустой список...

Некоторые советы по этому вопросу очень ценятся!

class CoreService(ServiceBase):
    @rpc(Unicode, Unicode, Integer, _returns=Unicode) #@rpc arguments corespond to the retrieve_score() arguments below
    def retreive_score(ctx, username, password, uid):
        if validate_creds(username,password):
            return {"score:" 0.6, features=[{"gender": "male"}, {"height": 160], ... ]
        else:
            return "Invalid credentials"


application = Application([CoreService], 'spyne.iefp.soap',
                          in_protocol=Soap11(validator='lxml'),
                          out_protocol=XmlDocument(polymorphic=True))

person Andrew Bell    schedule 04.06.2019    source источник


Ответы (1)


SOAP имеет один тип возврата. Идиоматический способ заключается в том, чтобы вызывать исключения при ошибках, не возвращая мошеннический ответ (то есть ответ, который несовместим с назначенным возвращаемым типом).

Если вы хотите вернуть произвольные данные, вы можете попробовать _return=AnyDict или, что еще лучше, _return=AnyXml, что позволит вам вернуть все, что вы хотите.

См. эту функцию, чтобы понять, как произвольные словари преобразуются в XML-документы.

https://github.com/arskom/spyne/blob/b8925ee5dc407eb9e2a8d97047f14b10425ee01d/spyne/util/etreeconv.py#L60

Эта функция реализует один из возможных способов сопоставления словарей с данными XML. Это процесс с потерями, поэтому он может соответствовать или не соответствовать вашим потребностям.

Если это не работает для вас, вам придется использовать тип AnyXml и напрямую использовать lxml для построения вашего ответа. Я предлагаю API lxml.builder. Дополнительную информацию см. здесь: https://lxml.de/api/lxml.builder.ElementMaker-class.html

person Burak Arslan    schedule 07.06.2019