Доступ к Kashoo API через Python и SUDS.Проблема с форматом времени в токене аутентификации - PullRequest
3 голосов
/ 10 июля 2011

Я пытаюсь получить доступ к этому 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 за ваши отзывы и рекомендации.

1 Ответ

0 голосов
/ 11 июля 2011

Если вы можете создать журнал того, что происходит «по проводам» в виде HTTP-запросов и ответов, это может помочь диагностировать проблему. Вы, похоже, поступаете правильно.

Работают ли другие звонки? Как насчет service.getMyBususiness (токен)?

Также вы можете рассмотреть возможность использования REST API вместо SOAP, посмотрите, поможет ли это вообще.

...