Подтвердить что ты не робот

WCF и Python

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

4b9b3361

Ответ 1

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

Посмотрите эту главу в Dive Into Python. Он покажет вам, как сделать SOAP-вызовы.

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

Ответ 2

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

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. Для обеспечения того, что вам нужно, нужно провести некоторое массирование данных, особенно если вам нужно привязать к нескольким пространствам имен.

Ответ 3

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


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

  • suds в значительной степени мертв (даже pip не может установить его на python 3)
  • Судж-Юрко кажется мертвым. Релиз 0.6 имеет очень досадную бесконечную ошибку рекурсии (по крайней мере, для WSDL, предоставляемой нашим сервисом), которая исправлена в подсказке, но не выпущена, и с момента ее написания в феврале 17 года прошло 1,5 года (на момент написания этой статьи). совершить.
    Он работает на Python 3, но не поддерживает SOAP 1.2. Ответ Советникова - попытка заставить его работать с 1.2, но мне не удалось заставить его работать на меня.
  • Zeep, кажется, является текущим способом пойти и работать из коробки (я не связан с Zeep, это просто работает для меня, и я провел несколько часов, стуча головой о кирпичную стену, пытаясь заставить работать пену). Чтобы Zeep работал, конфигурация хоста службы WCF должна включать <security mode = "None"/> в узле wsHttpBinding. На самом деле, Zeep поддерживает WS-SE на основе имени и подписи (x509), но я не пробовал, так что могу ' не говорить о каких-либо проблемах вокруг.

Ответ 4

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

Этот пример для порта 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)

Ответ 5

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

Ответ 6

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

Ответ 7

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

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