Exchange Web服务(EWS)- 通过suds进行Exchange 2010 SOAP调用

2 投票
1 回答
5054 浏览
提问于 2025-04-17 02:47

我正在尝试通过Exchange Web Services使用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 

我能够顺利进行身份验证,但我总是遇到以下错误:

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

如果有任何建议,我将非常感激。谢谢!

1 个回答

1

我也遇到过这个问题。不过,我只是偶尔会出现这个错误。我找到了一篇帖子提到可能的解决办法,这对我有一点帮助(我遇到错误的次数少了),但并没有完全解决问题。

问题似乎是Exchange服务器在发送有效响应之前就关闭了连接。如果其他人能提供更多信息,我将非常感激。这件事让我很头疼。

也许这对你有帮助: urllib2在打开一个网址时抛出错误,而在浏览器中正常打开

我不确定你是否已经这样做了,但我需要设置我的脚本来本地下载messages.xsd、types.xsd和services.wsdl,并进行修补,代码如下:

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

希望这能指引你朝正确的方向前进。用suds与Exchange进行沟通一直是个大挑战。我在这里找到了一些帮助,还有一些示例代码为我的项目提供了基础:

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

更新: 发送正确的SOAP头和RequestServerVersion:

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

我为了简洁省略了一些xml内容。

撰写回答