Sending SOAP request using Python Requests

后端 未结 1 793
夕颜
夕颜 2020-11-29 16:50

Is it possible to use Python\'s requests library to send a SOAP request?

相关标签:
1条回答
  • 2020-11-29 17:23

    It is indeed possible.

    Here is an example calling the Weather SOAP Service using plain requests lib:

    import requests
    url="http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
    #headers = {'content-type': 'application/soap+xml'}
    headers = {'content-type': 'text/xml'}
    body = """<?xml version="1.0" encoding="UTF-8"?>
             <SOAP-ENV:Envelope xmlns:ns0="http://ws.cdyne.com/WeatherWS/" 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:GetWeatherInformation/></ns1:Body>
             </SOAP-ENV:Envelope>"""
    
    response = requests.post(url,data=body,headers=headers)
    print response.content
    

    Some notes:

    • The headers are important. Most SOAP requests will not work without the correct headers. application/soap+xml is probably the more correct header to use (but the weatherservice prefers text/xml
    • This will return the response as a string of xml - you would then need to parse that xml.
    • For simplicity I have included the request as plain text. But best practise would be to store this as a template, then you can load it using jinja2 (for example) - and also pass in variables.

    For example:

    from jinja2 import Environment, PackageLoader
    env = Environment(loader=PackageLoader('myapp', 'templates'))
    template = env.get_template('soaprequests/WeatherSericeRequest.xml')
    body = template.render()
    

    Some people have mentioned the suds library. Suds is probably the more correct way to be interacting with SOAP, but I often find that it panics a little when you have WDSLs that are badly formed (which, TBH, is more likely than not when you're dealing with an institution that still uses SOAP ;) ).

    You can do the above with suds like so:

    from suds.client import Client
    url="http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
    client = Client(url)
    print client ## shows the details of this service
    
    result = client.service.GetWeatherInformation() 
    print result 
    

    Note: when using suds, you will almost always end up needing to use the doctor!

    Finally, a little bonus for debugging SOAP; TCPdump is your friend. On Mac, you can run TCPdump like so:

    sudo tcpdump -As 0 
    

    This can be helpful for inspecting the requests that actually go over the wire.

    The above two code snippets are also available as gists:

    • SOAP Request with requests
    • SOAP Request with suds
    0 讨论(0)
提交回复
热议问题