Таким образом, я пытаюсь получить доступ к этому API https://www.clarityaccounting.com/api-docs/использование ПЕНЫ. Вот код, который должен работать:
from suds.client import Client
client = Client('https://www.clarityaccounting.com/api/v1?wsdl')
token = client.service.doLogin('demo', 'demo', 'www.kashoo.com', 'en_US', 300000)
Но я получаю эту ошибку:
WebFault: Server raised fault: 'No such operation: (HTTP GET PATH_INFO: /api/v1)'
Их парень поддержки говорит, что запрос должен быть похожим на это:
demo
demo
www.kashoo.com
en_US
300000
Но ПЕНЫ похожи на это:
demo
demo
www.kashoo.com
en_US
300000
Я - реальный SOAP и новичок ПЕНЫ, но я слышал, что ПЕНА является лучшей библиотекой SOAP для использования отсюда: Какие клиентские библиотеки SOAP существуют для Python, и где документация для них?
Таким образом, мой вопрос просто, каковы ключевые роли, которые отличаются и которые делают сбой запроса и как я могу настроить ПЕНУ для отправления правильно отформатированного запроса?
На первый взгляд кажется, что проблема, с которой вы столкнулись, связана с SSL. Вы обращаетесь к URL https, а обработчик Transport для suds.client по умолчанию говорит http.
Проблема
Если вы посмотрите на нижнюю часть WSDL, он указывает местоположение по умолчанию как http://www.clarityaccounting.com/api/v1
, что является http URL, но WSDL является SSL.
<wsdl:service name="v1">
<wsdl:port binding="tns:v1SoapBinding" name="BooksApiV1Port">
<soap:address location="http://www.clarityaccounting.com/api/v1"/>
</wsdl:port>
</wsdl:service>
Если вы выполните http GET на этом URL, вы получите сообщение об ошибке, которое вы получили:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>No such operation: (HTTP GET PATH_INFO: /api/v1)</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Решение
Чтобы исправить это, вам нужно переопределить местоположение по умолчанию при вызове конструктора Client
, чтобы он придерживался https:
>>> url
'https://www.clarityaccounting.com/api/v1?wsdl'
>>> client = Client(url, location='https://www.clarityaccounting.com/api/v1')
>>> token = client.service.doLogin('demo', 'demo', 'www.kashoo.com', 'en_US', 300000)
>>> token
(authToken){
authenticationCode = "ObaicdMJZY6UM8xZ2wzGjicT0jQ="
expiryDate = 2010-03-05 12:31:41.000698
locale = "en_US"
myUserId = 4163
site = "www.kashoo.com"
}
Победа!
Совет для будущих целей отладки: Включите отладку с полным протоколированием. SUDS использует стандартную библиотеку logging
, поэтому она дает вам много контроля. Итак, я поднял все до DEBUG
:
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG)
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)
Вот что помогло мне сузить круг поиска, потому что в ответе было четко указано, что он отправляет по http:
DEBUG:suds.transport.http:sending:
URL:http://www.clarityaccounting.com/api/v1
(xml output omitted)
И в ответе это тоже было указано:
DEBUG:suds.client:http failed:
Это не должно быть проблемой, связанной с подключением к службе через HTTPS. Я использую пену, чтобы сделать то же самое. Я пробовал несколько подходов к вашему файлу WSDL (сам не являюсь экспертом) и обнаружил ту же ошибку. Что вы должны делать на практике с мыльной пеной, так это использовать метод factory , например
login = client.factory.create('doLogin')
login.username = 'username'
etc...
Все, что отправлено в функцию создания, является одним из типов, определенных в файле WSDL. Если вы создаете этот тип в оболочке, вы можете запустить «print login», чтобы увидеть его дополнительные свойства.
Надеюсь, это хотя бы говорит вам, где проблема (с HTTPS). Кроме того, я заметил, что заголовки soapAction не установлены в файле WSDL, не знаю, как suds или служба обрабатывает запросы без этого.