使用suds SOAP库进行HTTP身份验证的奇怪行为

时间:2011-03-05 01:33:20

标签: python suds

我有一个工作的python程序,它使用suds通过SOAP获取大量数据。 Web服务使用分页功能实现,这样我就可以通过每次提取调用获取 nnn 行,并通过后续调用获取下一个 nnn 。如果我使用如下代码

对HTTP服务器进行身份验证
client = suds.client.Client(url=url, location=location, username=username, password=password, timeout=timeout)
一切都很好。但是,如果我使用以下

t = suds.transport.https.HttpAuthenticated(username=username, password=password)
t.handler = urllib2.HTTPBasicAuthHandler(t.pm)
t.urlopener = urllib2.build_opener(t.handler)
client = suds.client.Client(url=url, location=location, timeout=timeout, transport=t) 

它适用于6次迭代。也就是说,如果我指定每次获取10行的获取限制,我会返回60行。在第七次获取时,我收到了

  File "build/bdist.linux-i686/egg/suds/client.py", line 542, in __call__
  File "build/bdist.linux-i686/egg/suds/client.py", line 602, in invoke
  File "build/bdist.linux-i686/egg/suds/client.py", line 649, in send
  File "build/bdist.linux-i686/egg/suds/client.py", line 698, in failed
AttributeError: 'NoneType' object has no attribute 'read'

是否有人对可能导致此问题的原因提出任何建议。肯定是这种变化导致了这个问题。我可以来回交换身份验证样式,它是完全可重现的。

我正在使用suds 0.4运行python 2.6.6。

由于

1 个答案:

答案 0 :(得分:10)

问题似乎是从较低级别引发urllib2.HTTPError,其fp属性为None:

suds.transport.http中的第81行:

except u2.HTTPError, e:
    if e.code in (202,204):
        result = None
    else:
        raise TransportError(e.msg, e.code, e.fp)

该异常最终会传递到suds.clienterror.fp.read()行爆炸的第698行:

def failed(self, binding, error):
    status, reason = (error.httpcode, tostr(error))
    reply = error.fp.read()

我建议使用猴子修补suds.SoapClient类来获取HTTP错误代码和消息。在构造suds.Client之前添加这些行,然后运行它以查看第7次提取引发的HTTP错误:

class TestClient(suds.client.SoapClient):
    def failed(self, binding, error):
        print error.httpcode, error.args

suds.client.SoapClient = TestClient