Выполнение запроса SOAP с использованием модуля запросов Python

Я использовал модуль запросов python для запросов REST.

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

<auth>
<apikey>xcvzxcvcxzv-a0-0035c6fbc04f</apikey>
</auth>

тело

<reports>
<report>
<name>Test</name>
</report>
</reports>

И вот wsdl url

https://ltn.net/webservices/booking/r1/index.wsdl

Скажите, пожалуйста, как я могу сделать заявку здесь, используя python. Если это невозможно с помощью модуля requests, то какими могут быть другие альтернативы?

Ответ 1

В последнее время я столкнулся с одной и той же проблемой, и, к сожалению, ни одна пена или юрко-суды (поддерживаемая вилка пены) не смогли помочь. Это происходит главным образом из-за того, что пенообразование продолжает создавать ошибочно форматированный конверт с мылом (это особенно происходит, если мыло, которое должно быть сгенерировано, имеет некоторый контент, который должен находиться внутри CDATA), отличный от того, что ожидал сервер. Это было так, даже когда я попытался сам вставить конверт с мылом, используя опцию __inject.

Вот как я решил это с помощью запросов python

import requests

request = u"""<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://SOME_URL">
   <soapenv:Header>
         <user>{0}</user>
         <pass>{1}</pass>
   </soapenv:Header>
   <soapenv:Body>
      <req:RequestInfo><![CDATA[<?xml version='1.0' encoding='UTF-8'?><request xmlns='http://SOME_OTHER_URL'>
    <Call>
        <callID>{2}</callID>
        ...
    </Call>
    <Foo>
        <Bar>
            <Baz>{3}</Baz>
            ...
        </Bar>
        <Neytri>
            ...
        </Neytri>
    </Foo>
    <Title>{4}</Title>
</request>]]></req:RequestInfo>
   </soapenv:Body>
</soapenv:Envelope>""".format('Jake_Sully', 
                              'super_secret_pandora_password',
                              'TYSGW-Wwhw',
                              'something_cool',
                              'SalaryPayment',
                              'Pandora_title',
                            )

encoded_request = request.encode('utf-8')

headers = {"Host": "http://SOME_URL",
            "Content-Type": "application/soap+xml; charset=UTF-8",
            "Content-Length": str(len(encoded_request)),
            "SOAPAction": "http://SOME_OTHER_URL"}

response = requests.post(url="http://SOME_OTHER_URL",
                     headers = headers,
                     data = encoded_request,
                     verify=False)

print response.content #print response.text

Что действительно важно было указать Content-Type в заголовках, а также SOAPAction. В соответствии с спецификацией SOAP 1.1

 The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.       

Значение SOAPAction обычно можно найти в файле wsdl вызова API, который вы хотите создать; если он отсутствует в файле wsdl, вы можете использовать пустую строку в качестве значения этого заголовка

Также смотрите:

Ответ 2

Для работы с SOAP-сервером вы должны использовать специализированную библиотеку. К сожалению, нет хороших клиентских модулей SOAP для Python, лучший из которых я использовал suds.

Ответ 3

Это в значительной степени гипотетично, так как я не знаю, кто на самом деле его реализовал, но suds поддерживает создание пользовательских реализаций suds.transport.Transport. Как только это будет suds.transport.http.HttpTransport. Таким образом, технически путем реализации транспортного подкласса вы можете создать транспорт пены, который использует запросы.

http://jortel.fedorapeople.org/suds/doc/suds.transport.http.HttpTransport-class.html - это то, что используется по умолчанию, и оно возвращается http://jortel.fedorapeople.org/suds/doc/suds.transport.Reply-class.html, так как вы можете видеть, должно быть довольно просто обернуть запросы на запросы, чтобы пена их понимала. Транспортный запрос (который должен быть отправлен с запросами) документирован здесь http://jortel.fedorapeople.org/suds/doc/suds.transport.Request-class.html Я мог бы рано или поздно реализовать это, если никто не подведет меня к нему

Почему все эти усилия? Поскольку suds использует urllib2 внутренне, что намного хуже, чем python-запросы в качестве реализации HTTP-клиента.

Еще одно редактирование: я сделал gist доступным в качестве отправной точки https://gist.github.com/nanonyme/6268358. Это код MIT и непроверенный, но должен работать как отправная точка для транспорта.