Программно вызывать методы RPC для конечной точки SOAP в Python

Я ищу простой способ программно вызвать вызов SOAP / RPC через Python. Что-то типа:

method_to_invoke, args = parse_user_input()
outbound_xml = library.call_remote_method(method_to_invoke, args)
result = requests.post(... data=outbound_xml)

Я знаю, что есть несколько библиотек Python, которые поддерживают вызовы SOAP / RPC; однако все они творит некоторую "магию" и допускают такие вещи, как:

result = client.service.getPercentBodyFat('jeff', 68, 170)

(предыдущий пример взят из документации по пене, но основные принципы те же). Это предполагает, что я заранее знаю имя метода и не могу определить его во время выполнения.

В поисках решений они либо уже не поддерживаются, либо пытаются творить слишком много «волшебства». Например, см. этот слишком сложный сценарий или это решение, которое по сути сводится к« Создайте свой собственный XML и отправьте его ».

Есть ли какая-нибудь библиотека, которая может построить для меня "исходящий" XML, не прибегая к обручам? У меня уже есть HTTP-сервер, который будет получать входящий RPC, и я хочу использовать requests для правильной обработки таких вещей, как проверка сертификата SSL.


person lorenzog    schedule 27.04.2016    source источник
comment
есть ли причина, по которой вы не можете использовать что-то вроде пены и выбрать метод с использованием отражения (например, getattr)? Требуется ли что-то еще динамическое, кроме имени метода?   -  person Charlie    schedule 27.04.2016
comment
@Charlie может привести пример в ответах? Отражение может сработать, это просто кажется ненужным усложнением, которого я бы предпочел избежать. Я понимаю, что библиотеки RPC призваны упростить жизнь, но отсутствие простой питонической библиотеки, которая легко расширяется, кажется смешным.   -  person lorenzog    schedule 27.04.2016
comment
Хорошо, извините, у меня нет решения. По моему опыту, протокол SOAP должен быть хрупким: вы заключаете контракт со службой, а затем, если он изменяется, для внесения обновлений выполняется большой каскадный процесс.   -  person Charlie    schedule 27.04.2016


Ответы (1)


Вы можете дать python-zeep шанс (http://docs.python-zeep.org). Он может легко сгенерировать xml, который вы хотите отправить, с помощью следующего кода:

client = zeep.Client(
    wsdl='http://www.webservicex.net/ConvertSpeed.asmx?WSDL')
doc = client.service._binding.create_message('ConvertSpeed', 100, 
      'kilometersPerhour', 'milesPerhour'))    
print(etree.tostring(doc, pretty_print=True))

(Я автор, дайте мне знать, если у вас возникнут проблемы с этим)

person mvantellingen    schedule 27.04.2016
comment
Выглядит идеально. Спасибо за это. Могу я порекомендовать вам разместить его здесь wiki.python.org/moin/WebServices, например, на верх полужирным шрифтом размером 250pt или что-то в этом роде :) - person lorenzog; 27.04.2016
comment
Также - было бы неплохо увидеть еще несколько примеров использования, например - если я хочу сделать обратное, например. передать XML в zeep, поддерживает ли он генерацию методов на стороне сервера из WSDL? - person lorenzog; 27.04.2016
comment
Это всего лишь клиент и в настоящее время не может действовать как сервер. У меня есть хороший опыт работы с spyne.io/docs/2.10/index.html для этого. - person mvantellingen; 27.04.2016
comment
Что-то изменилось в последних версиях? Пример, который вы опубликовали, похоже, больше не работает. У меня сейчас 0.13.0 - person lorenzog; 03.08.2016
comment
Да, это изменено на :: client.service._binding.create_message ('ConvertSpeed', 100, 'kmPerhour', 'milesPerhour')) - person mvantellingen; 03.08.2016
comment
спасибо, я обновил ответ (нужно утвердить, но он есть) - person lorenzog; 03.08.2016
comment
Как передать необработанный xml в качестве запроса с помощью zeep @mvantellingen - person Raj Kumar; 17.05.2021