使用Python请求模块发出SOAP请求

时间:2013-03-22 11:34:02

标签: python soap

我使用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模块无法实现,那么其他选择可能是什么呢?

4 个答案:

答案 0 :(得分:9)

我最近遇到了同样的问题,不幸的是,既没有泡沫也没有jurko-suds(保持肥皂泡沫)能够提供帮助。 这主要是因为suds一直生成错误格式化的肥皂信封(如果应该生成的肥皂具有一些应该在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。 根据{{​​3}}

 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的值通常可以在您要进行的API调用的wsdl文件中找到;如果wsdl文件中没有,那么您可以使用空字符串作为该标题的值

另见:

  1. SOAP 1.1 specifiaction
  2. http://archive.oreilly.com/pub/post/unraveling_the_mystery_of_soap.html

答案 1 :(得分:6)

要使用SOAP服务器,您应该使用专门的库。不幸的是,Python没有好的SOAP客户端模块,我使用的最好的是suds

答案 2 :(得分:2)

这很大程度上是假设的,因为我不知道有人实际上已经实现了它,但是suds支持自定义suds.transport.Transport的实现。一旦这样是suds.transport.http.HttpTransport。因此,从技术上讲,通过实现传输子类,您可以创建一个使用请求的suds传输。

http://jortel.fedorapeople.org/suds/doc/suds.transport.http.HttpTransport-class.html是默认使用的,它会返回 http://jortel.fedorapeople.org/suds/doc/suds.transport.Reply-class.html所以你可以看到,包装请求回复应该相当简单,以便suds理解它们。此处记录了传输请求(应随请求一起发送) http://jortel.fedorapeople.org/suds/doc/suds.transport.Request-class.html 如果没有人向我致敬,我迟早会实施这个

为什么要这么努力?因为suds在内部使用urllib2,远远低于python请求作为HTTP客户端实现。

还有一个编辑:我提出了一个要点作为起点https://gist.github.com/nanonyme/6268358。它是MIT代码并且未经测试,但应该作为传输的起点。

答案 3 :(得分:1)

万一有人最终读到这篇文章:基于suds的解决方案通常停滞不前,但是在请求和lxml之上有一个名为zeep的较新的库。这是一个完全独立的解决方案,而不是像其他解决方案一样的泡沫叉。根据个人经验,我知道这种方法已在某些企业环境中使用。