Можете ли вы помочь мне решить эту проблему с SUDS / SOAP?

Поэтому я пытаюсь получить доступ к этому api https://www.clarityaccounting.com/api-docs/, используя SUDS. Вот код, который должен работать:

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)' 

Их помощник говорит, что запрос должен выглядеть так:

 <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:api="http://api.service.books/"> <SOAP-ENV:Body> <api:doLogin> <username>demo</username> <password>demo</password> <siteName>www.kashoo.com</siteName> <locale>en_US</locale> <duration>300000</duration> </api:doLogin> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Но SUDS 'выглядит так:

 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:ns0="http://api.service.books/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <ns1:Body> <ns0:doLogin> <username>demo</username> <password>demo</password> <siteName>www.kashoo.com</siteName> <locale>en_US</locale> <duration>300000</duration> </ns0:doLogin> </ns1:Body> </SOAP-ENV:Envelope> 

Я настоящий SOAP и SUDS новичок, но я слышал, что SUDS – лучшая библиотека SOAP для использования отсюда: какие библиотеки клиента SOAP существуют для Python, и где для них документация?

Таким образом, мой вопрос заключается в том, какие ключевые моменты отличаются друг от друга, и что приводит к сбою запроса и как я могу настроить SUDS для отправки правильно отформатированного запроса?

3 Solutions collect form web for “Можете ли вы помочь мне решить эту проблему с SUDS / SOAP?”

На первый взгляд похоже, что проблема связана с SSL. Вы получаете доступ к URL-адресу https, а обработчик транспорта для suds.client говорит по умолчанию по умолчанию.

Проблема
Если вы посмотрите на нижнюю часть WSDL, он указывает местоположение по умолчанию как http://www.clarityaccounting.com/api/v1 , которое является http-адресом, но 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" } 

Победа!

Pro для будущих целей отладки: включите полную отладочную регистрацию. 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-файлу (а не самому эксперту) и столкнулся с той же ошибкой. То, что вы должны делать, как практика с пеной, но использует заводской метод, например

 login = client.factory.create('doLogin') login.username = 'username' etc... 

Где все, что отправляется функции create, является одним из типов, определенных в файле WSDL. Если вы создаете этот тип в оболочке, вы можете запустить «login для печати», чтобы увидеть его дополнительные свойства.

Надеюсь, это, по крайней мере, говорит вам, где проблема не (с HTTPS). Кроме того, я заметил, что заголовки soapAction не установлены в файле WSDL, не уверены, как бездействуют запросы или службы.

Использование suds-jurko https://pypi.python.org/pypi/suds-jurko, который является поддерживаемой вилкой пены. Вы можете передать опцию __inject, где вы можете передать ей необработанный xml, который хотите отправить.

 from suds.client import Client username, password, sitename, locale, duration = 'demo', 'demo', 'www.kashoo.com', 'en_US', 300000 raw_xml = """<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:api="http://api.service.books/"> <SOAP-ENV:Body> <api:doLogin> <username>{0}</username> <password>{1}</password> <siteName>{2}</siteName> <locale>{3}</locale> <duration>{4}</duration> </api:doLogin> </SOAP-ENV:Body> </SOAP-ENV:Envelope>""".format(username, password, sitename, locale, duration) client = Client(url, location) result = client.service.doLogin(__inject={'msg':raw_xml}) 

Я чувствую, что я должен документировать все способы, которыми можно проверять сырое мыло, которое вспенивает здесь.

  1. Использование флага nosend при построении клиента. Обратите внимание, что с флагом, установленным на True, пена будет просто генерировать мыло, но не отправлять его.

    client =Client(url, nosend=True)
    res = client.service.example()
    print res.envelope отпечатки сырого мыла

  2. Использование журнала. Здесь мы только регистрируем suds.transport.http, поэтому он будет выводить только то, что отправлено / получено.

    import logging
    import sys
    handler = logging.StreamHandler(sys.stderr)
    logger = logging.getLogger('suds.transport.http')
    logger.setLevel(logging.DEBUG), handler.setLevel(logging.DEBUG)
    logger.addHandler(handler)

  3. Использование MessagePlugin

    from suds.plugin import MessagePlugin
    class MyPlugin(MessagePlugin):
    def marshalled(self, context):
    #import pdb; pdb.set_trace()
    print context.envelope.str()

    client = Client(url, plugins=[MyPlugin()])

Мало того, что MessagePlugin дает вам возможность проверять мыло, но вы также можете изменить его перед отправкой, см .-> https://jortel.fedorapeople.org/suds/doc/suds.plugin.MessagePlugin-class.html.

 
Interesting Posts for Van-Lav

Resident Backend Google App Engine "/ _ah / background" (Python)

Выйти из цикла нажатием клавиши ENTER

Отсканированное изображение на рабочем столе соответствует оригинальному изображению с использованием OpenCV и SIFT / SURF

Обработка проблемы с травлением classmethod с помощью copy_reg

Opencv: Как сшить четыре трапецеидальных изображения, чтобы сделать квадратное изображение?

Сюжет / Преобразование выражения, исходящего из sympy: серия Тейлора с matplotlib

Python 27: Как исправить / сохранить значение для метода для сохранения его интерфейса?

Временные поля в джанго

Маркировка гистограммного блока matplotlib со стрелкой

Чтение Python нескольких файлов осадков NetCDF с переменным размером

Не удается подключиться к локальному хосту с помощью Python MySQLdb

ExpatError: неверно сформирован (недействительный токен)

Unicodedecodeerror с сервером

Как преобразовать шестнадцатеричную строку в шестнадцатеричный номер?

Ошибка при загрузке IPython-ноутбука

Python - лучший язык программирования в мире.