2011-03-05 10 views
6

Tengo un programa python en funcionamiento que está obteniendo un gran volumen de datos a través de SOAP utilizando espuma. El servicio web se implementa con una función de búsqueda de manera que pueda tomar nnn filas con cada llamada de recuperación y tomar el siguiente nnn con las siguientes llamadas. Si me autentico en el servidor HTTP con el siguiente códigoComportamiento extraño de la autenticación HTTP con la biblioteca SOAP de suds

 
client = suds.client.Client(url=url, location=location, username=username, password=password, timeout=timeout) 

todo funciona muy bien. Sin embargo, si uso el siguiente

 
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) 

funciona exactamente con 6 iteraciones. Es decir, si especifico un límite de búsqueda de 10 filas por extracción, obtengo 60 filas. En la séptima búsqueda, recibo

 
    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' 

Alguien tiene alguna sugerencia sobre lo que podría estar causando esto. Definitivamente este cambio es lo que está causando el problema. Puedo intercambiar estilos de autenticación de ida y vuelta y es completamente reproducible.

Estoy ejecutando python 2.6.6 con espuma 0.4.

Gracias

+0

Cualquier progreso con esto? Si paso datos incorrectos de autenticación al constructor, obtengo el mismo error en lugar de una excepción. Si utilizo HttpAuthenticated para conectar y pasar eso al constructor del cliente de espuma, siempre obtengo la solicitud 403 Bad (autenticación inválida) incluso si los datos de autenticación son válidos. –

Respuesta

10

El problema parece ser que un urllib2.HTTPError está siendo levantado de un nivel más bajo, y su atributo fp es Ninguno:

Línea 81 en suds.transport.http:

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

Esa excepción finalmente pasa a la línea 698 en suds.client donde esa línea error.fp.read() explota:

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

Sugeriría el parche de mono de la clase suds.SoapClient para obtener el código de error HTTP y el mensaje. Añadir estas líneas antes de construir su suds.Client, a continuación, ejecutarlo para ver qué HTTP Error La 7ª fetch aumentos:

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

suds.client.SoapClient = TestClient 
+0

En la 7ª ejecución de la llamada de recuperación, recibí "401 ('autenticación básica no',), Ninguno". Si paso el nombre de usuario y la contraseña al constructor del cliente, no recibo tal error. – zenzic

+0

Tal vez realice una depuración de urllib2 de nivel inferior para asegurarse de que sus transportes/indicadores se utilizan en ese 7º pase. Suds podría estar volviendo a usar su transporte predeterminado por alguna razón, que falla cuando no se proporciona ningún usuario/pase. – samplebias

+1

Utilicé su parche, pero en lugar de 'print..', utilicé' raise error' y todo funcionó como se esperaba. ¡Gracias! –

Cuestiones relacionadas