Python: Как я могу использовать Скрученный в качестве транспорта для ПЕНЫ?

У меня есть проект, который является на основе Скрученного, используемого для общения с сетевыми устройствами, и я добавляю поддержку нового поставщика (Citrix NetScaler), API которого является SOAP. К сожалению, поддержка SOAP в Скрученном все еще полагается SOAPpy, который плохо устарел. На самом деле с этого вопроса (я просто проверил), twisted.web.soap самостоятельно не был даже обновлен за 21 месяц!

Я хотел бы спросить, есть ли у кого-либо опыт, они были бы готовы совместно использовать с использованием превосходной асинхронной транспортной функциональности Twisted с ПЕНОЙ. Кажется, что включение пользовательского Скрученного транспорта было бы естественным соответствием в ПЕНАХ Client.options.transport, Мне просто нелегко переносить мою голову вокруг этого.

Я действительно придумывал способ назвать метод SOAP с ПЕНОЙ асинхронно путем использования twisted.internet.threads.deferToThread(), но это чувствует себя подобно взлому мне.

Вот пример того, что я сделал, для давания Вам общее представление:

# netscaler is a module I wrote using suds to interface with NetScaler SOAP
# Source: http://bitbucket.org/jathanism/netscaler-api/src
import netscaler
import os
import sys
from twisted.internet import reactor, defer, threads

# netscaler.API is the class that sets up the suds.client.Client object
host = 'netscaler.local'
username = password = 'nsroot'
wsdl_url = 'file://' + os.path.join(os.getcwd(), 'NSUserAdmin.wsdl')
api = netscaler.API(host, username=username, password=password, wsdl_url=wsdl_url)

results = []
errors = []

def handleResult(result):
    print '\tgot result: %s' % (result,)
    results.append(result)

def handleError(err):
    sys.stderr.write('\tgot failure: %s' % (err,))
    errors.append(err)

# this converts the api.login() call to a Twisted thread.
# api.login() should return True and is is equivalent to:
# api.service.login(username=self.username, password=self.password)
deferred = threads.deferToThread(api.login)
deferred.addCallbacks(handleResult, handleError)

reactor.run()

Это работает как ожидалось и задерживает возврат api.login() звоните, пока это не будет завершено вместо блокирования. Но поскольку я сказал, это не чувствует себя хорошо.

Заранее спасибо за любую справку, руководство, обратную связь, критику, оскорбления или комплексные решения.

Обновление: единственным решением, которое я нашел, является скрученная пена, который является ветвлением Пены, измененной для работы со Скрученным.

12
задан jathanism 25 September 2013 в 16:32
поделиться

1 ответ

Интерпретация по умолчанию транспорта в контексте Twisted, вероятно, является реализацией twisted.internet.interfaces.ITransport . На этом уровне вы в основном имеете дело с необработанными байтами, отправляемыми и получаемыми через какой-либо сокет (чаще всего используются UDP, TCP и SSL). Это не совсем то, что интересует интеграционную библиотеку SUDS / Twisted. Вместо этого вам нужен HTTP-клиент, который SUDS может использовать для выполнения необходимых запросов и который представляет все данные ответа, чтобы SUDS мог определить, какой результат было. Другими словами, SUDS на самом деле не заботится о необработанных байтах в сети. Его интересуют HTTP-запросы и ответы.

Если вы изучите реализацию twisted.web.soap.Proxy (клиентская часть Twisted Web SOAP API), то увидите, что на самом деле она мало что дает. Примерно 20 строк кода склеивают SOAPpy с twisted.web.client.getPage . То есть он подключает SOAPpy к Twisted так, как я описал выше.

В идеале SUDS должен предоставлять какой-то API в духе SOAPpy.buildSOAP и SOAPpy.parseSOAPRPC (возможно, API-интерфейсы были бы немного сложнее или принимали бы еще несколько параметров - я не эксперт по SOAP, поэтому я не знаю, не хватает ли в конкретных API-интерфейсах SOAPpy чего-то важного, но основная идея должна быть таким же). Тогда вы могли бы написать что-то вроде twisted.web.soap.Proxy на основе SUDS. Если twisted.web.client.getPage не предлагает достаточного контроля над запросами или достаточной информации об ответах, вы также можете использовать вместо него twisted.web.client.Agent , который появился совсем недавно и предлагает гораздо больший контроль над всем процессом запроса / ответа. Но опять же, это действительно та же идея, что и текущий код на основе getPage , только более гибкая / выразительная реализация.

Только что взглянув на документацию по API для Client.options.transport , похоже, что транспорт SUDS является в основном HTTP-клиентом. Проблема с такой интеграцией заключается в том, что SUDS хочет отправить запрос, а затем сразу же получить ответ. Поскольку Twisted в значительной степени основан на обратных вызовах , API HTTP-клиента на основе Twisted не может немедленно вернуть ответ на SUDS. Он может возвращать только Deferred (или эквивалент).

Вот почему все работает лучше, если отношения перевернуты. Вместо предоставления SUDS HTTP-клиента для игры, предоставьте SUDS и HTTP-клиент третьему фрагменту кода и позвольте ему управлять взаимодействиями.

Однако, возможно, невозможно заставить все работать, создав транспорт SUDS на основе Twisted (он же HTTP-клиент). Тот факт, что Twisted в основном использует Deferred (также известные как обратные вызовы) для раскрытия событий, не означает, что это единственный способ работы. Используя стороннюю библиотеку, такую ​​как greenlet , можно предоставить API на основе сопрограмм, где запрос асинхронной операции включает переключение выполнения с одной сопрограммы на другую, а события доставляются путем обратного переключения. к исходной сопрограмме. Есть проект под названием corotwine , который может делать именно это. Это может быть возможным использовать это для предоставления SUDS того типа API HTTP-клиента, который ему нужен; однако это не гарантируется. Это зависит от того, не срабатывает ли SUDS, когда переключатель контекста внезапно вставляется там, где раньше его не было. Это очень тонкое и хрупкое свойство SUDS, которое может быть легко изменено (даже непреднамеренно) разработчиками SUDS в будущем выпуске, так что это, вероятно, не идеальное решение, даже если вы сможете получить его до работайте сейчас (если вы не можете заручиться сотрудничеством со стороны сопровождающих SUDS в форме обещания протестировать их код в такой конфигурации, чтобы убедиться, что он продолжает работать).

Кстати, причина, по которой поддержка SOAP в Twisted Web все еще основана на SOAPpy и не подвергалась изменениям в течение почти двух лет, заключается в том, что не было явной замены SOAPpy.Было много претендентов ( Какие клиентские библиотеки SOAP существуют для Python и где к ним документация? охватывает некоторые из них). Если что-то когда-нибудь уляжется, имеет смысл попробовать обновить встроенную поддержку SOAP в Twisted. А пока, думаю, имеет смысл делать эти интеграционные библиотеки отдельно,чтобы их было легче обновлять, и поэтому сам Twisted не заканчивается большим количеством различных интеграций SOAP, которые никому не нужны (что было бы хуже, чем текущая ситуация, когда есть только одна интеграция SOAP модуль, который никому не нужен).

13
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: