Exchange Web Services (EWS) - Exchange 2010 soap calls via suds

风流意气都作罢 提交于 2019-12-22 11:32:57

问题


Im trying to send an email via Exchange Web Services using suds 0.4.1:

import suds 
from suds.client import Client 
from suds.transport.https import WindowsHttpAuthenticated

url = "file:///C:/Services.wsdl" 
user = 'domain\\user' 
password = "hardtoguess"

ntlm = WindowsHttpAuthenticated(username=user,password=password) 
c = Client(url, transport=ntlm)

xml = ''' <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <CreateItem     
MessageDisposition="SendAndSaveCopy"
xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<SavedItemFolderId> <DistinguishedFolderId Id="sentitems"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"/> 
</SavedItemFolderId> <Items> <Message
xmlns="http://schemas.microsoft.com/exchange/services/2006/types">  
<ItemClass>IPM.Note</ItemClass> <Subject>Sent via Python->Exchange->EWS</Subject>  
<Body BodyType="Text">This message has been sent to you via Python,
Exchange and EWS :)</Body> <ToRecipients> <Mailbox> 
<EmailAddress>imran.azad@localhost</EmailAddress> </Mailbox> </ToRecipients>   
</Message> </Items> 
</CreateItem> </soap:Body></soap:Envelope>''' 

attr = c.service.CreateItem(__inject={'msg':xml})

xml = ''' <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <soap:Body>  
<ResolveNames
xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
ReturnFullContactData="true"> <UnresolvedEntry>azadi</UnresolvedEntry> 
</ResolveNames> </soap:Body> </soap:Envelope> ''' 

attr = c.service.ResolveNames(__inject={'msg':t})

 print attr 

I'm able to authenticate fine, however I keep getting the following error:

Traceback (most recent call last):
  File "soap.py", line 10, in <module>
    c = Client(url, transport=ntlm)
  File "build\bdist.win32\egg\suds\client.py", line 112, in __init__
  File "build\bdist.win32\egg\suds\reader.py", line 152, in open
  File "build\bdist.win32\egg\suds\wsdl.py", line 159, in __init__
  File "build\bdist.win32\egg\suds\wsdl.py", line 220, in build_schema
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 93, in load
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 305, in open_imports
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 542, in open
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 563, in download
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 397, in instance
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 226, in __init__
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 305, in open_imports
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 542, in open
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 563, in download
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 397, in instance
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 226, in __init__
  File "build\bdist.win32\egg\suds\xsd\schema.py", line 305, in open_imports
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 542, in open
  File "build\bdist.win32\egg\suds\xsd\sxbasic.py", line 560, in download
  File "build\bdist.win32\egg\suds\reader.py", line 79, in open
  File "build\bdist.win32\egg\suds\reader.py", line 95, in download
  File "build\bdist.win32\egg\suds\transport\https.py", line 60, in open
  File "build\bdist.win32\egg\suds\transport\http.py", line 62, in open
  File "build\bdist.win32\egg\suds\transport\http.py", line 118, in u2open
  File "C:\Python26\lib\urllib2.py", line 391, in open
    response = self._open(req, data)
  File "C:\Python26\lib\urllib2.py", line 409, in _open
    '_open', req)
  File "C:\Python26\lib\urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "C:\Python26\lib\urllib2.py", line 1170, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "C:\Python26\lib\urllib2.py", line 1143, in do_open
    r = h.getresponse()
  File "C:\Python26\lib\httplib.py", line 990, in getresponse
    response.begin()
  File "C:\Python26\lib\httplib.py", line 391, in begin
    version, status, reason = self._read_status()
  File "C:\Python26\lib\httplib.py", line 355, in _read_status
    raise BadStatusLine(line)
httplib.BadStatusLine

Any advice would be much appreciated. Thanks


回答1:


I've also been experiencing this issue. However, I only get this error intermittently. I found another post referring to a possible solution, and it helps some (I get the error less) but it hasn't fixed the issue completely.

The problem seems to be that the Exchange server closes the connection before sending a valid response. If anyone else can add more I would greatly appreciate it. This one has been driving me crazy.

Perhaps this may help you: urllib2 is throwing an error for an url , while it's opening properly in browser

I'm not sure if you're doing it already, but I needed to setup my script to download the messages.xsd, types.xsd, and the services.wsdl locally and patch it. with the following:

def setup(self):
    '''Patches the WSDL file to include a service tag. Returns path to
    local WSDL file.'''
    trans = self.transport
    try:
        makedirs(self.localdir)
    except OSError:
        # Directory already exists
        pass

    # Download messags.xsd file
    messages_url = '%s/messages.xsd' % self.urlprefix
    with open('%s/%s' % (self.localdir, 'messages.xsd'), 'w') as msg_xsd:
        msg_xsd.write(trans.geturl(messages_url, trans.authtype))

    # Download types.xsd file
    types_url = '%s/types.xsd' % self.urlprefix
    with open('%s/%s' % (self.localdir, 'types.xsd'), 'w') as types_xsd:
        types_xsd.write(trans.geturl(types_url, trans.authtype))

    # Modify WSDL to add service description
    service_url = '%s/Exchange.asmx' % self.urlprefix
    servicexml = '''
        <wsdl:service name="ExchangeServices">
            <wsdl:port name="ExchangeServicePort" binding="tns:ExchangeServiceBinding">
                  <soap:address location="%s"/>
                </wsdl:port>
          </wsdl:service>
        </wsdl:definitions>''' % service_url
    localwsdl = '%s/%s' % (self.localdir, 'Services.wsdl')
    wsdlxml = trans.geturl(self.wsdl, trans.authtype)
    with open(localwsdl, 'w') as wsdl:
        wsdl.write(wsdlxml.replace('</wsdl:definitions>', servicexml))

    return localwsdl

Hopefully this will point you in the right direction. Simply talking to Exchange with suds has been a major challenge. I found some help here, as well as the sample code that has provided the base for my project:

http://lists.fedoraproject.org/pipermail/suds/2010-September/001144.html

Update: Sending the correct SOAP headers with RequestServerVersion:

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope>
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2010"/>
    </soap:Header>
    <soap:Body>
    </soap:Body>
 </soap:Envelope>

I've truncated the xml for brevity.



来源:https://stackoverflow.com/questions/7505653/exchange-web-services-ews-exchange-2010-soap-calls-via-suds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!