使用SSL和标头在python中通过SUDS调用Soap API

时间:2016-09-01 05:45:26

标签: python-2.7 ssl soap suds

我有一个soap api,我想在python中用suds调用它。我已经安装了suds并且能够连接soap api。

client = Client("http://my_sevone_appliance/soap3/api.wsdl")

但是我必须向soap api发送一些标题和额外的标题,我还必须在TLSv1中发送ssl文件。

ssl.wrap_socket() 记住python版本是2.7

但不知怎的,我无法做到这一点。 有人可以帮助我如何从肥皂水中调用肥皂api并传递头文件和ssl。三江源

2 个答案:

答案 0 :(得分:2)

我找到了解决方案。我已经在 python suds 中做了所有这些事情。请安装 suds。

首先我在python中编写了一个tranport.py脚本,它实际上接受了cert和密钥文件并将其传递给suds客户端。这是代码。

import urllib2, httplib, socket
from suds.transport.http import HttpTransport, Reply, TransportError
class HTTPSClientAuthHandler(urllib2.HTTPSHandler):

    def __init__(self, key, cert):
        urllib2.HTTPSHandler.__init__(self)
        self.key = key
        self.cert = cert

    def https_open(self, req):
        #Rather than pass in a reference to a connection class, we pass in
        # a reference to a function which, for all intents and purposes,
        # will behave as a constructor
        return self.do_open(self.getConnection, req)

    def getConnection(self, host, timeout=300):
        return httplib.HTTPSConnection(host,
                                      key_file=self.key,
                                      cert_file=self.cert)
class HTTPSClientCertTransport(HttpTransport):

    def __init__(self, key, cert, *args, **kwargs):
        HttpTransport.__init__(self, *args, **kwargs)
        self.key = key
        self.cert = cert

    def u2open(self, u2request):
        """
        Open a connection.
        @param u2request: A urllib2 request.
        @type u2request: urllib2.Requet.
        @return: The opened file-like urllib2 object.
        @rtype: fp
        """
        tm = self.options.timeout
        url = urllib2.build_opener(HTTPSClientAuthHandler(self.key, self.cert))
        if self.u2ver() < 2.6:
            socket.setdefaulttimeout(tm)
            return url.open(u2request)
        else:
            return url.open(u2request, timeout=tm)

使用上面的一个并成功调用soap api我使用下面的代码。

url = <wsdl url of soap api eg: url ="http://my_sevone_appliance/soap3/api.wsdl">
pem = <is the key file>  
cert = <is the cert>   
c = Client(url, transport=HTTPSClientCertTransport(pem, cert))

然后我调用我想要的功能。你可以看到你想要的所有功能。

print c

这里我必须使用标题来发送肥皂。所以我也必须传递标题(可选)。

import ast
headers = '{}'
c.set_options(headers=ast.literal_eval(headers))

我必须使用ast,因为你必须以json格式发送标头。然后我调用该函数。

xml=<the xml data  which you want to send>
example : 
 xml ='<soap:Env xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://www.abc1.com/services">
             <soap:Header/>
             <soap:Body>
                <ser:getName>
                   <ser:ver>1</ser:ver>
                   <ser:syncId>222</ser:syncID>
                   <ser:mobileNo>0987654321</ser:mobileNo>
                </ser:getBalance>
             </soap:Body>
          </soap:Env>'

现在点击肥皂功能

 c.service.getName(__inject={'msg': xml})

这里getName是我在soap api中的函数。

就是这样。问你是否有任何问题。

答案 1 :(得分:1)

#**If you don't have any cert file and key:**

import ast
from suds.client import Client
headers='{}'
url = <wsdl url of soap api eg: url ="http://my_sevone_appliance/soap3/api.wsdl">
client = Client(url,location=url)
client.options.cache.clear()
c.set_options(headers=ast.literal_eval(headers))
c=client.service.<service name>(__inject={'msg': xml})    #eg. c.service.getName(__inject={'msg': xml})


#**fetching data from response**
#for example if the output will:
# c.CustomerInfo
#(ArrayOfCustomer){
#   Customer[] = 
#      (Customer){
#         Account = xyz
#         AccountType = abc
#         Account_TypeID = mno
#         Address = None
#         Address2 = None
#         City = Pune
#},
#}

#then fetch like:  c.CustomerInfo.Customer[0].Account