WCF и Python - PullRequest
       38

WCF и Python

24 голосов
/ 09 ноября 2008

Существует ли пример кода клиента cpython (не IronPython), который может вызывать службу Windows Communication Foundation (WCF)?

Ответы [ 7 ]

19 голосов
/ 05 октября 2010

Я использовал .

from suds.client import Client

print "Connecting to Service..."
wsdl = "http://serviceurl.com/service.svc?WSDL"
client = Client(wsdl)
result = client.service.Method(variable1, variable2)
print result

Это должно начать вас. Я могу подключиться к открытым службам из WCF и уровня RESTful. Для того, чтобы делать то, что вам нужно, требуется некоторая передача данных, особенно если вам нужно привязать несколько пространств имен.

8 голосов
/ 02 апреля 2009

WCF должен предоставлять функциональность через протокол связи. Я думаю, что наиболее часто используемый протокол, вероятно, SOAP через HTTP. Давайте предположим, что это что вы используете тогда.

Взгляните на эту главу в Dive Into Python . Это покажет вам, как совершать SOAP-звонки.

Я не знаю единого способа вызова службы WCF в Python, независимо от связи протокол.

3 голосов
/ 20 февраля 2017

TL; DR: для wsHttpBinding (SOAP 1.2) используйте zeep


В случае, если у кого-то возникают проблемы с использованием suds (или suds-jurko) с WCF и wsHttpBinding (то есть SOAP 1.2):

  • suds в значительной степени мертв (даже не может установить его на Python 3)
  • Судж-юрко кажется мертвым. Релиз 0.6 имеет очень досадную бесконечную ошибку рекурсии (по крайней мере в WSDL, предоставляемой нашим сервисом), которая исправлена ​​в подсказке, но не выпущена, и прошло 1,5 года (на момент написания этой статьи в феврале 17) совершить.
    Он работает на Python 3, но не поддерживает SOAP 1.2. Ответ Советникова - попытка заставить его работать с 1.2, но мне не удалось заставить его работать на меня.
  • Zeep, кажется, является текущим способом работы и работает из коробки (я не связан с Zeep, это просто работает для меня, и я провел несколько часов, стуча головой о кирпичную стену, пытаясь заставить работать пену) , Чтобы Zeep работал, конфигурация хоста службы WCF должна включать в узле wsHttpBinding На самом деле Zeep поддерживает WS-SE на основе имени пользователя и подписи (x509) но я не пробовал, поэтому не могу говорить о каких-либо проблемах вокруг него.
2 голосов
/ 22 марта 2016

Просто чтобы помочь кому-то получить доступ к службе WCF SOAP 1.2 с помощью WS-Addressing с использованием suds. Основная проблема - ввести имя действия в каждое сообщение.

Этот пример для Python 3 и порта suds https://bitbucket.org/jurko/suds.

Пример использует пользовательскую аутентификацию на основе заголовков HTTP, я оставляю это как есть.

TODO: автоматически получать api_direct_url из WSDL (сейчас он жестко запрограммирован).

from suds.plugin import MessagePlugin
from suds.sax.text import Text
from suds.wsse import Security, UsernameToken
from suds.sax.element import Element
from suds.sax.attribute import Attribute
from suds.xsd.sxbasic import Import

api_username = 'some'
api_password = 'none'

class api(object):
    api_direct_url = 'some/mex'
    api_url = 'some.svc?singleWsdl|Wsdl'

    NS_WSA = ('wsa', 'http://www.w3.org/2005/08/addressing')

    _client_instance = None
    @property
    def client(self):
        if self._client_instance:
            return self._client_instance
        from suds.bindings import binding
        binding.envns = ('SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')

        api_inst = self
        class _WSAPlugin(MessagePlugin):
            def marshalled(self, context):
                api_inst._marshalled_message(context)

        self._client_instance = Client(self.api_url,
                             plugins=[_WSAPlugin()],
                             headers={'Content-Type': 'application/soap+xml',
                                      'login':api_username,
                                      'password': api_password}
                             )
        headers = []
        headers.append(Element('To', ns=self.NS_WSA).setText(self.api_direct_url))
        headers.append(Element('Action', ns=self.NS_WSA).setText('Blank'))
        self._client_instance.set_options(soapheaders=headers)

        cache = self._client_instance.options.cache
        cache.setduration(days=10)
        return self._client_instance

    def _marshalled_message(self, context):
        def _children(r):
            if hasattr(r, 'children'):
                for c in r.children:
                    yield from _children(c)
                    yield c
        for el in _children(context.envelope):
            if el.name == 'Action':
                el.text = Text(self._current_action)
                return

    _current_action = None
    def _invoke(self, method, *args):
        try:
            self._current_action = method.method.soap.action.strip('"')
            return method(*args)
        finally:
            self._current_action = None

    def GetRequestTypes(self):
        return self._invoke(self.client.service.GetRequestTypes)[0]

    def GetTemplateByRequestType(self, request_type_id):
        js = self._invoke(self.client.service.GetTemplateByRequestType, request_type_id)
        return json.loads(js)

    def GetRequestStatus(self, request_guid):
        return self._invoke(self.client.service.GetRequestStatus, request_guid)

    def SendRequest(self, request_type_id, request_json):
        r = json.dumps(request_json, ensure_ascii=False)
        return self._invoke(self.client.service.SendRequest, request_type_id, r)
1 голос
/ 08 июня 2010

если вам нужна двоичная сериализованная связь через tcp, рассмотрите возможность внедрения решения, подобного Thrift.

1 голос
/ 05 мая 2009

Я не знаю ни одного прямого примера, но если служба WCF включена REST, вы можете получить к ней доступ через POX (обычный старый XML) с помощью методов REST / etc (если такая служба есть). Если вы контролируете сервис, вы также можете выставлять конечные точки через REST.

0 голосов
/ 10 ноября 2008

Даже если нет конкретного примера вызова WCF из Python, вы сможете создать полностью SOAP-совместимый сервис с WCF. Тогда все, что вам нужно сделать, это найти несколько примеров того, как вызвать обычный сервис SOAP из Python.

Самое простое - использовать BasicHttpBinding в WCF, а затем вы можете поддерживать собственные сеансы, передавая токен сеанса с каждым запросом и ответом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...