Quando provo a collegarmi a un servizio Web MS CRM usando suds/python-ntlm, ricevo un timeout sulle richieste. Tuttavia, il codice che sto tentando di sostituire - che richiama l'app della riga di comando cURL per fare la stessa chiamata - ha successo.Perché si verifica un errore/timeout della connessione quando si utilizza python suds per connettersi a Microsoft CRM?
Chiaramente qualcosa è diverso nel modo in cui CURL invia i dati di comando, ma sarei dannato se so qual è la differenza. Di seguito sono riportati i dettagli completi delle varie chiamate. Qualcuno ha qualche consiglio?
Ecco il codice che sta effettuando la richiesta, seguito dall'output. Il codice comando cURL è inferiore a quello e segue la sua risposta. Host, utenti e password sono stati modificati per proteggere gli innocenti, ovviamente.
wsdl_url = 'https://client.service.host/MSCrmServices/2007/MetadataService.asmx?WSDL'
username = r'domain\user.name'
password = 'userpass'
from suds.transport.https import WindowsHttpAuthenticated
from suds.client import Client
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
ntlmTransport = WindowsHttpAuthenticated(username=username, password=password)
metadata_client = Client(wsdl_url, transport=ntlmTransport)
request = metadata_client.factory.create('RetrieveAttributeRequest')
request.MetadataId = '00000000-0000-0000-0000-000000000000'
request.EntityLogicalName = 'opportunity'
request.LogicalName = 'new_typeofcontact'
request.RetrieveAsIfPublished = 'false'
attr = metadata_client.service.Execute(request)
print attr
ecco l'output:
DEBUG:suds.client:sending to (http://client.service.host/MSCrmServices/2007/MetadataService.asmx)
message:
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:Execute>
<ns1:Request xsi:type="ns1:RetrieveAttributeRequest">
<ns1:MetadataId>00000000-0000-0000-0000-000000000000</ns1:MetadataId>
<ns1:EntityLogicalName>opportunity</ns1:EntityLogicalName>
<ns1:LogicalName>new_typeofcontact</ns1:LogicalName>
<ns1:RetrieveAsIfPublished>false</ns1:RetrieveAsIfPublished>
</ns1:Request>
</ns1:Execute>
</ns0:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"', 'Content-Type': 'text/xml'}
DEBUG:suds.transport.http:sending:
URL:http://client.service.host/MSCrmServices/2007/MetadataService.asmx
HEADERS: {'SOAPAction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"', 'Content-Type': 'text/xml', 'Content-type': 'text/xml', 'Soapaction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"'}
MESSAGE:
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:Execute>
<ns1:Request xsi:type="ns1:RetrieveAttributeRequest">
<ns1:MetadataId>00000000-0000-0000-0000-000000000000</ns1:MetadataId>
<ns1:EntityLogicalName>opportunity</ns1:EntityLogicalName>
<ns1:LogicalName>new_typeofcontact</ns1:LogicalName>
<ns1:RetrieveAsIfPublished>false</ns1:RetrieveAsIfPublished>
</ns1:Request>
</ns1:Execute>
</ns0:Body>
</SOAP-ENV:Envelope>
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (16, 0))
---------------------------------------------------------------------------
URLError Traceback (most recent call last)
/Users/crose/projects/2366/crm/<ipython console> in <module>()
/var/folders/nb/nbJAzxR1HbOppPcs6xO+dE+++TY/-Tmp-/python-67186icm.py in <module>()
19 request.LogicalName = 'new_typeofcontact'
20 request.RetrieveAsIfPublished = 'false'
21
---> 22 attr = metadata_client.service.Execute(request)
23 print attr
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in __call__(self, *args, **kwargs)
537 return (500, e)
538 else:
--> 539 return client.invoke(args, kwargs)
540
541 def faults(self):
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in invoke(self, args, kwargs)
596 self.method.name, timer)
597 timer.start()
--> 598 result = self.send(msg)
599 timer.stop()
600 metrics.log.debug(
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in send(self, msg)
621 request = Request(location, str(msg))
622 request.headers = self.headers()
--> 623 reply = transport.send(request)
624 if retxml:
625 result = reply.message
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/https.pyc in send(self, request)
62 def send(self, request):
63 self.addcredentials(request)
---> 64 return HttpTransport.send(self, request)
65
66 def addcredentials(self, request):
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/http.pyc in send(self, request)
75 request.headers.update(u2request.headers)
76 log.debug('sending:\n%s', request)
---> 77 fp = self.u2open(u2request)
78 self.getcookies(fp, u2request)
79 result = Reply(200, fp.headers.dict, fp.read())
/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/http.pyc in u2open(self, u2request)
116 return url.open(u2request)
117 else:
--> 118 return url.open(u2request, timeout=tm)
119
120 def u2opener(self):
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in open(self, fullurl, data, timeout)
381 req = meth(req)
382
--> 383 response = self._open(req, data)
384
385 # post-process response
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in _open(self, req, data)
399 protocol = req.get_type()
400 result = self._call_chain(self.handle_open, protocol, protocol +
--> 401 '_open', req)
402 if result:
403 return result
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
359 func = getattr(handler, meth_name)
360
--> 361 result = func(*args)
362 if result is not None:
363 return result
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in http_open(self, req)
1128
1129 def http_open(self, req):
-> 1130 return self.do_open(httplib.HTTPConnection, req)
1131
1132 http_request = AbstractHTTPHandler.do_request_
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in do_open(self, http_class, req)
1103 r = h.getresponse()
1104 except socket.error, err: # XXX what error?
-> 1105 raise URLError(err)
1106
1107 # Pick apart the HTTPResponse object to get the addinfourl
URLError: <urlopen error [Errno 60] Operation timed out>
Il comando cURL è:
/opt/local/bin/curl --ntlm -u "domain\user.name:userpass" -k -d @- -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.1)" -H "Connection: Keep-Alive" -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction: http://schemas.microsoft.com/crm/2007/WebServices/Execute" https://client.service.host/MSCrmServices/2007/MetadataService.asmx
I dati che il piping a questo comando cURL:
<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:Header>
<CrmAuthenticationToken xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<AuthenticationType xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">0</AuthenticationType>
<CrmTicket xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes"></CrmTicket>
<OrganizationName xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">CMIFS</OrganizationName>
<CallerId xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">00000000-0000-0000-0000-000000000000</CallerId>
</CrmAuthenticationToken>
</soap:Header>
<soap:Body>
<Execute xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<Request xsi:type="RetrieveAttributeRequest">
<MetadataId>00000000-0000-0000-0000-000000000000</MetadataId>
<EntityLogicalName>opportunity</EntityLogicalName>
<LogicalName>new_typeofcontact</LogicalName>
<RetrieveAsIfPublished>false</RetrieveAsIfPublished>
</Request>
</Execute>
</soap:Body>
</soap:Envelope>
Ecco la risposta :
<?xml version="1.0" encoding="utf-8"?>
<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>
<ExecuteResponse
xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<Response xsi:type="RetrieveAttributeResponse">
<AttributeMetadata xsi:type="PicklistAttributeMetadata">
<MetadataId>101346cf-a6af-4eb4-a4bf-9c3c6bbd6582</MetadataId>
<SchemaName>New_TypeofContact</SchemaName>
<LogicalName>new_typeofcontact</LogicalName>
<EntityLogicalName>opportunity</EntityLogicalName>
<AttributeType>
<Value>Picklist</Value>
</AttributeType>
<!-- stuff here -->
</AttributeMetadata>
</Response>
</ExecuteResponse>
</soap:Body>
</soap:Envelope>
Un po 'di più: sembra che la chiamata stia ricevendo una seconda risposta 401 non autorizzata, ma il gestore è sospeso in risposta ad esso, in attesa di una risposta che non arriva mai. È strano perché le stesse credenziali sono state utilizzate con successo, non un decimo di secondo prima, per recuperare il file WSDL dal WSDL dell'endpoint. Qualsiasi opinione che la gente possa offrire qui sarebbe molto gradita. –