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
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 would like to send my hand build xml by SUDS using WSDL. I found, that I can do it like that:
xml = Raw("""
<SOAP-ENV:Envelope xmlns:ns0="urn:ca:std:cdc:tech:xsd:cdc.001.01" 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:GetAccountBalance>
<ns0:Document>
<myData>
something
</myData>
</ns0:Document>
</ns0:GetAccountBalance>
</ns1:Body>
</SOAP-ENV:Envelope>
""")
print client.service.GetAccountBalance(xml)
But using this method SUDS sends:
<SOAP-ENV:Envelope xmlns:ns0="urn:ca:std:cdc:tech:xsd:cdc.001.01" 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:GetAccountBalance>
<ns0:Document>
<SOAP-ENV:Envelope xmlns:ns0="urn:ca:std:cdc:tech:xsd:cdc.001.01" 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:GetAccountBalance>
<ns0:Document>
<myData>
something
</myData>
</ns0:Document>
</ns0:GetAccountBalance>
</ns1:Body>
</SOAP-ENV:Envelope>
</ns0:Document>
</ns0:GetAccountBalance>
</ns1:Body>
</SOAP-ENV:Envelope>
My question is, how can I send my XML, without adding anything by SUDS?
According to the suds documentation, you can send a raw SOAP message using the __inject argument to the method you're calling:
client.service.GetAccountBalance(__inject={'msg': xml})
I'm a newb when it comes to soap, but here is what I have. If I make a soap call with perl's SOAP::Lite library, everything is cool. When I make the same call with suds, I get an error from the server.
Here is the working xml generated by the perl call:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:urn="urn:webservicesapi"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<urn:getChassis xsi:nil="true" />
</soap:Body>
</soap:Envelope>
Making the same call with suds, I get this xml generated
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:webservicesapi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:getChassis/>
</ns0:Body>
</SOAP-ENV:Envelope>
The error produced with the server is: <ErrorCode>43</ErrorCode><Description>Start and end tag names don't match</Description>
If I use a soap plugin with my browser, I can replicate this. If I change the body to:
<SOAP-ENV:Body>
<urn:getChassis xsi:nil="true" />
</SOAP-ENV:Body>
The call works just fine.
So, I either need to know how to change the prefix for Body and urn: or I need to understand why the Start and end tag names don't match?
I understand I can use from suds.plugin import MessagePlugin to manipulate the xml before it is sent, but I am at a loss here.
Any help or advice would be greatly appreciated.
OK. Got it to work.
class EnvelopeFixer(MessagePlugin):
def marshalled(self, context):
context.envelope.getChild('ns0:Body').setPrefix('ns1')
Then I called the plugin when creating the client object
client = Client(WSDL_LOCATION, transport=t, location=url, plugins=[EnvelopeFixer()])
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 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.