I'm trying to access this API https://www.kashoo.com/api-docs using SUDS in Python.
The Python code I use is the following:
>>> from suds.client import Client
>>> client = Client('https://www.kashoo.com/api/v1?wsdl')
>>> token = client.service.doLogin('username', 'password', 'www.kashoo.com', 'en_US', 3000000)
The authToken is created without problems:
>>> print token
(authToken){
_authenticationCode = "crxQRveuVaDb6swKCJaQKKPiYaY="
_expiryDate = 2011-07-10 12:49:28.000702
_locale = "en_US"
_myUserId = 531772668
_site = "www.kashoo.com"
The problem is when I try to encode the token and make an encoded authentication string
>>>encodedtoken = client.service.encodeAuthToken(token)
Traceback (most recent call last):
File "<console>", line 0, in <module>
File "C:\Python27\lib\suds\client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "C:\Python27\lib\suds\client.py", line 602, in invoke
result = self.send(soapenv)
File "C:\Python27\lib\suds\clie开发者_JAVA百科nt.py", line 649, in send
result = self.failed(binding, e)
File "C:\Python27\lib\suds\client.py", line 702, in failed
r, p = binding.get_fault(reply)
File "C:\Python27\lib\suds\bindings\binding.py", line 265, in get_fault
raise WebFault(p, faultroot)
WebFault: Server raised fault: 'Token authentication code is incorrect'
The problem seems to be the time format in token. The envelope received from calling the doLogin function is the following:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:doLoginResponse xmlns:ns2="https://www.kashoo.com/api/">
<token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T03:33:24.046-07:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
</ns2:doLoginResponse>
</soap:Body>
</soap:Envelope>
If I pass that token in the Kashoo API using a tool like soapUI , it works without problem. However, when I call the encodeAuthToken function from Python using SUDS, the following SOAP envelope is generated:
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://www.kashoo.com/api/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:encodeAuthToken>
<token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T11:33:24.000046+01:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
</ns1:encodeAuthToken>
</ns0:Body>
</SOAP-ENV:Envelope>
Notice how the timeformat of the expiryDate attribute changed:
<token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T03:33:24.046-07:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
<token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T11:33:24.000046+01:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
In the token received, the time is specified using milliseconds, while in the token passed on, the time is specified in microsecond.
PROBLEM SOLVED.
In the SUDS library, I modified the suds.sax.date module on line 218 to replace
return dt.time(hour, minute, second, ms)
with
return dt.time(hour, minute, second, 1000 * ms)
now when I obtain a token, the time attribute is correctly interpreted and passed on
>>> print token1
(authToken){
_locale = "en_US"
_authenticationCode = "JQyior8Qprg3+3wuZo8B5JnN3c8="
_myUserId = 531772668
_site = "www.kashoo.com"
_expiryDate = 2011-07-11 18:36:38.136000
}
>>> token2 = client.service.encodeAuthToken(token1)
>>> print token2
6454e3af-b09d-4484-90b3-ea2632ab9fe4
I'm new at programming and the solution is far from elegant, but it seems to work.
Thanks to @dobesv for your feedback and guidance.
If you can produce a log of what is going "over the wire" as HTTP requests and responses, it might help diagnose the problem. You certainly seem to be doing the right thing.
Do any other calls work? How about service.getMyBusinesses(token) ?
Also you can consider using the REST API instead of SOAP, see if that helps at all.
精彩评论