I am having a problem with python suds trying to create a proper Suds XML Request:
This is my suds Code (after a few trials):
from suds import *
from suds.client import Client
from suds.transport.http import HttpAuthenticated
import logging
url = 'http://ws/webservices/600/ws.asmx?wsdl'
soap_client = Client(url, location='http://ws/webservices/600/ws.asmx')
soap_client.set_options(port='GatewayWebServiceSoap')
person = soap_client.factory.create('checkIfExists')
person.UserID = 'toni.tester#anywhere.at'
person.SessionID = ''
eventService = soap_client.service.CustomerService(person)
print 'last received:'
print soap_client.last_received()
print '-------------------------------------'
print 'last sent:'
print soap_client.last_sent()
This is what my suds sends:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://service.example.at/gateway/v6.00" 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:Service>
<ns0:Service>
<ns0:SessionID></ns0:SessionID>
<ns0:UserID>toni.tester#anywhere.at</ns0:UserID>
</ns0:Service>
</ns0:Service>
</ns1:Body>
</SOAP-ENV:Envelope>
And this is what the WebService expects:
<?xml version="1.0" encoding="UTF-8"?>
<GATEWAY xmlns="urn:service-example-at:gateway:v4-00">
<Service>
<checkIfExists>
<SessionID></SessionID>
<UserID>test</UserID>
</checkIfExists>
</Service>
</GATEWAY>
My Questions:
How can I change SOAP-ENV:Envelope -> GATEWAY
How can I remove the namespaces ns1, ns0?
How can I remove the Body
If you really don't care about WSDL and stuff you can easily write request generator yourself since xml request is just a string template. That's what i did for my soapy needs.
Related
I need the session id. It contains in raw but not in the object directly
from zeep import Client, Settings
settings = Settings(strict=False, xml_huge_tree=True)
client_auth = Client('http://extgate.alean.ru:8082/webservice/ewebsvc.dll/wsdl/IewsServer', settings=settings)
with client_auth.settings(raw_response=True):
response = client_auth.service.Login(ConnectionID ='',UserAlias = 'Test',Password ='testik', Language ='RU',ProfileID ='',ContextXML='',Timeout ='900000' )
print(response.text)
answer is :
<?xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENC:encodingStyle="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS2="urn:webservice-electrasoft-ru:types-ewsServerIntf"><NS1:LoginResponse xmlns:NS1="urn:webservice-electrasoft-ru:types-ewsServerIntf-IewsServer"><return xsi:type="NS2:TewsLoginResult">lrSuccess</return><SessionID xsi:type="xsd:string">{C3EC1993-00B0-4CDE-B26F-68FA0BD4CA76}</SessionID></NS1:LoginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
You can convert response from xml to dict with xmltodict lib and then get expected value from it:
import xmltodict
response = '<?xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENC:encodingStyle="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS2="urn:webservice-electrasoft-ru:types-ewsServerIntf"><NS1:LoginResponse xmlns:NS1="urn:webservice-electrasoft-ru:types-ewsServerIntf-IewsServer"><return xsi:type="NS2:TewsLoginResult">lrSuccess</return><SessionID xsi:type="xsd:string">{C3EC1993-00B0-4CDE-B26F-68FA0BD4CA76}</SessionID></NS1:LoginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>'
data = xmltodict.parse(response)
guid = data['SOAP-ENV:Envelope']['SOAP-ENV:Body']['NS1:LoginResponse']['SessionID']['#text']
Output:
{C3EC1993-00B0-4CDE-B26F-68FA0BD4CA76}
I need some help with suds request in python.
Generated XML request looks like this
<SOAP-ENV:Envelope 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">
<SOAP-ENV:Header>
<m:ExternalApiHeader xmlns:m="http://www.GlobalBettingExchange.com/ExternalAPI/" version="" languageCode="" username="" password="" applicationIdentifier=""/>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:GetEventSubTreeWithSelections xmlns:m="http://www.GlobalBettingExchange.com/ExternalAPI/">
<m:getEventSubTreeWithSelectionsRequest WantPlayMarkets="true">
<m:EventClassifierIds>2147483647</m:EventClassifierIds>
</m:getEventSubTreeWithSelectionsRequest>
</m:GetEventSubTreeWithSelections>
</SOAP-ENV:Body>
I have created python script and the only thing I can't figure out how to pass the value EventClassifierIds, which is 2147483647
import suds
url = 'http://api.betdaq.com/v2.0/API.wsdl'
client = suds.client.Client(url)
#prepare headers
token=client.factory.create('ExternalApiHeader')
token._version='2'
token._languageCode='en'
token._username=''
token._password=''
client.set_options(soapheaders=token)
#reguest
result = client.service.GetEventSubTreeWithSelections('false')
print result
I'm interfacing with a SOAP API, wherein a particular method requires a raw XML string as a parameter. Like so:
import suds.client as sudscl
client = sudscl.Client('http://host/ws.wsdl', location='http://host/ws')
session = 'test123'
options = '<rawXML><Item>Foobar</Item></rawXML>'
result = client.service.ExecuteSearch(session, options)
Pretty straight-forward. However, suds HTML-encodes the XML string I just sent in, like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://host/ws">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:ExecuteSearch>
<ns0:session>test123</ns0:session>
<ns0:options>
<rawXML&rt;<Item&rt;Foobar</Item&rt;</rawXML&rt;
</ns0:options>
</ns0:ExecuteSearch>
</ns1:Body>
</SOAP-ENV:Envelope>
Boo! Is there any way to get suds to pass in the XML string un-altered?
Thanks!
Ok, got it.
from suds.sax.text import Raw
import suds.client as sudscl
client = sudscl.Client('http://host/ws.wsdl', location='http://host/ws')
session = 'test123'
options = Raw('<rawXML><Item>Foobar</Item></rawXML>')
result = client.service.ExecuteSearch(session, options)
I am trying this code to fetch data from wsdl.
Querying the website for the zipid("60630") works fine but in my code it gives the error as
"Invalid ZIP"
wsdlFile = 'http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl'
wsdlObject = WSDL.Proxy(wsdlFile)
wsdlObject.show_methods()
zipid = "60630"
result = wsdlObject.GetCityWeatherByZIP(ZIP=zipid)
print result[1]
Can someone please help whats wrong here and why the code is not working correctly.
Thanks !!!
The problem probably is that your client sends a request the server doesn't understand. Seems you're using SOAPpy, that's the request it sends when I try it:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
>
<SOAP-ENV:Body>
<GetCityWeatherByZIP SOAP-ENC:root="1">
<v1 xsi:type="xsd:string">60630</v1>
</GetCityWeatherByZIP>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
In comprison when using suds:
from suds.client import Client
cli = Client("http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl")
cli.service.GetCityWeatherByZIP(ZIP=60630)
it produces:
<?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:GetCityWeatherByZIP>
<ns0:ZIP>60630</ns0:ZIP>
</ns0:GetCityWeatherByZIP>
</ns1:Body>
</SOAP-ENV:Envelope>
(captured using wireshark)
The second request returns a valid result from the server.
I don't know SOAPpy well enough to suggest a way to fix this, but maybe you could consider switching your client library to suds.
I need to construct this SOAP query using python SOAPpy module:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<LicenseHeader xmlns="http://schemas.acme.eu/">
<LicenseKey>88888-88888-8888-8888-888888888888</LicenseKey>
</LicenseHeader>
</soap:Header>
<soap:Body>
<GetProductClassification xmlns="http://schemas.acme.eu/">
<GetProductClassificationRequest />
</GetProductClassification>
</soap:Body>
</soap:Envelope>
So I use this code:
from SOAPpy import WSDL
wsdlFile = 'https://example.comt/1.0/service.asmx?wsdl'
server = WSDL.Proxy(wsdlFile)
result = server.GetProductClassification();
The request generated is:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>
<SOAP-ENV:Body>
<GetProductClassification SOAP-ENC:root="1">
</GetProductClassification>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
When I send request I get Object reference not set to an instance of an object. I think this might be because I don't have a header section with license key in my request.
How do I modify my code to add header section with LicenseHeader parameter?
I am not sure how to do this in SOAPpy but I do know how to do it in suds. SUDS does the same thing as SOAPpy but it is newer and is still supported. I don't think SOAPpy is supported anymore. Below show's the code to connect to a WSDL and send a soap request:
class MySudsClass():
def sudsFunction(self):
url = "http://10.10.10.10/mywsdl.wsdl"
# connects to WSDL file and stores location in variable 'client'
client = Client(url)
#I have no address set in the wsdl to the camera I connect to so I set it's location here
client.options.location = 'http:/10.10.10.11'
# Create 'xml_value' object to pass as an argument using the 'factory' namespace
xml_value = client.factory.create('some_value_in_your_xml_body')
#This send the SOAP request.
client.service.WSDLFunction(xml_value)
Put this in the script before you send the soap request and it will add any headers you want.
# Namespaces to be added to XML sent
wsa_ns = ('wsa', 'http://schemas.xmlsoap.org/ws/2004/08/addressing')
wsdp_ns = ('http://schemas.xmlsoap.orf/ws/2006/02/devprof')
# Field information for extra XML headers
message = 'mymessage'
address_txt = 'myheader_information'
# Soapheaders to be added to the XML code sent
# addPrefix allow's you to addc a extra namespace. If not needed remove it.
message_header = Element('MessageID', ns=wsa_ns).setText(message)
address_header = Element('Address', ns=wsa_ns).setText(address_txt).addPrefix(p='wsdp', u=wsdp_ns)
header_list = [message_header, address_header]
# Soapheaders being added to suds command
client.set_options(soapheaders=header_list)
This will allow you to add in wsa encding that makes the XML understand:
# Attribute to be added to the headers to make sure camera verifies information as correct
mustAttribute = Attribute('SOAP-ENV:mustUnderstand', 'true')
for x in header_list:
x.append(mustAttribute)
If you use something like this you will be able to add any headers, namespaces etc. I have used this and it worked perfectly.
To add the license header in SUDS add:
license_key = Element('LicenseKey', ns=some_namespace).setText('88888-88888-8888-8888-888888888888')
license_header = Element('LicenseHeader', ns=some_namespace).insert(license_key)
license_attribute = Attribute(xmlns, "http://schemas.acme.eu/")
license_header.append(license_attribute)