[Fedora-suds-list] suds and Exchange Web Services

Glen Walker Glen.Walker at kordia.co.nz
Fri Sep 3 00:48:16 UTC 2010


Another option, if you're using suds 0.4.0 beta, is to use a plugin to manipulate the WSDL as it is loaded by suds. See https://fedorahosted.org/suds/wiki/Documentation#Version2 for details of the plugin API.

A plugin something like this might do the trick:


import xml.ns

import suds.plugin
import suds.sax.element
import suds.sax.attribute

class ServiceAddPlugin(suds.plugin.DocumentPlugin):

    def parsed(self, context):

        # context.document is the root element of the WSDL document.
        definitions_element = context.document

        # Make sure we are dealing with a WSDL document.
        if definitions_element.namespace()[1] != xml.ns.WSDL.BASE or \
          definitions_element.name != 'definitions':
            return

        # Find the namespace prefix used for WSDL elements.
        wsdl_prefix = definitions_element.findPrefix(xml.ns.WSDL.BASE,
                                                     default='wsdl')
        wsdl_namespace = (wsdl_prefix, xml.ns.WSDL.BASE)

        # Find the namespace prefix used for SOAP elements.
        soap_prefix = definitions_element.findPrefix(xml.ns.WSDL.BIND_SOAP,
                                                     default='soap')
        soap_namespace = (soap_prefix, xml.ns.WSDL.BIND_SOAP)

        # Find the WSDL target namespace URI and prefix (if any).
        target_namespace = definitions_element.get('targetNamespace')
        target_namespace_prefix = \
          definitions_element.findPrefix(target_namespace)

        # Create a wsdl:service element and add to the wsdl:definitions.
        service_element = suds.sax.element.Element('service', ns=wsdl_namespace)
        definitions_element.append(service_element)

        # Add a name attribute to the wsdl:service element.
        name_attribute = \
          suds.sax.attribute.Attribute('name', 'ExchangeServices')
        service_element.append(name_attribute)

        # Create a wsdl:port element and add to the wsdl:service.
        port_element = suds.sax.element.Element('port', ns=wsdl_namespace)
        service_element.append(port_element)

        # Add a name attribute to the wsdl:port element.
        name_attribute = suds.sax.attribute.Attribute('name',
                                                      'ExchangeServicePort')
        port_element.append(name_attribute)

        # Create a prefix for the target namespace if it wasn't already defined.
        if target_namespace_prefix is None:
            target_namespace_prefix = 'tns'
            port_element.addPrefix(target_namespace_prefix, target_namespace)

        # Add a binding attribute to the wsdl:port element.
        binding = '%s:%s' % (target_namespace_prefix, 'ExchangeServiceBinding')
        name_attribute = suds.sax.attribute.Attribute('binding', binding)
        port_element.append(name_attribute)

        # Create a soap:address element and add to the wsdl:port.
        address_element = suds.sax.element.Element('address',
                                                   ns=soap_namespace)
        port_element.append(address_element)

        # Add a location attribute to the soap:address element.
        location_attribute = suds.sax.attribute.Attribute('location',
          'https://exchange.server.com/ews/Exchange.asmx')
        address_element.append(location_attribute)



-----Original Message-----
From: suds-bounces at lists.fedoraproject.org [mailto:suds-bounces at lists.fedoraproject.org] On Behalf Of jon at objectevolution.com
Sent: Friday, 3 September 2010 10:12 a.m.
To: suds at lists.fedoraproject.org
Subject: [Fedora-suds-list] suds and Exchange Web Services

Hi,

I'm using the suds-ews branch to "try" and connect to Exchange Web Services for a client. Couple things I've run into:

1. I need to bring Services.wsdl, messages.xsd and types.xsd local and not on the Exchange server so I could modify Services.wsdl and append the following:

<wsdl:service name="ExchangeServices">
        <wsdl:port name="ExchangeServicePort" binding="tns:ExchangeServiceBinding">
                <soap:address location="https://exchange.server.com/ews/Exchange.asmx" />
        </wsdl:port>
    </wsdl:service>

2. Now, I get the client creation in Python just fine but when I go to call a service it wants me to, obviously, authenticate.

I can authenticate to the server upon client creation but I get a bad wsdl which needs the xml snippet from above. I can go local with the wsdl but then I need to authenticate to call a service.

Can the client call a service and pass a transport as well?

Thanks,

Jon
This email and attachments: are confidential; may be protected by privilege and copyright; if received in error may not be used, copied, or kept; are not guaranteed to be virus-free; may not express the views of Kordia(R); do not designate an information system; and do not give rise to any liability for Kordia(R).



More information about the suds mailing list