Я пытаюсь получить доступ к этому API https://www.kashoo.com/api-docs, используя SUDS в Python.
Код Python, который я использую, следующий:
>>> 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)
AuthToken создается без проблем:
>>> print token
(authToken){
_authenticationCode = "crxQRveuVaDb6swKCJaQKKPiYaY="
_expiryDate = 2011-07-10 12:49:28.000702
_locale = "en_US"
_myUserId = 531772668
_site = "www.kashoo.com"
Проблема в том, что когда я пытаюсь закодировать токен и сделать закодированную строку аутентификации
>>>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\client.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'
Возможно, проблема в формате времени в токене. Конверт, полученный от вызова функции doLogin, следующий:
<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>
Если я передаю этот токен в API Kashoo с помощью инструмента, подобного soapUI , он работает без проблем. Однако когда я вызываю функцию encodeAuthToken из Python с использованием SUDS, генерируется следующий конверт SOAP:
<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>
Обратите внимание, как изменился формат времени атрибута expiryDate:
<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"/>
В полученном токене время указывается в миллисекундах, а в переданном токене время указывается в микросекундах.
ПРОБЛЕМА РЕШЕНА.
В библиотеке SUDS я изменил модуль suds.sax.date в строке 218, чтобы заменить
return dt.time(hour, minute, second, ms)
с
return dt.time(hour, minute, second, 1000 * ms)
теперь, когда я получаю токен, атрибут времени правильно интерпретируется и передается
>>> 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
Я новичок в программировании, и решение далеко не элегантное, но, похоже, работает.
Спасибо @dobesv за ваши отзывы и рекомендации.