Why can't I set SOAP headers in pysimplesoap?

I got some sample php code to call the SOAP service, which I now need to convert to Python. In php code, they set headers as follows:

$auth = array(); $auth['token'] = 'xxx'; if ($auth) { // add auth header $this->clients[$module]->__setSoapHeaders( new SoapHeader( $namespace, 'auth', $auth ) ); } 

So, the auth header should look like this: ['token' => 'xxx'] . Then I loaded wsdl into SoapUI , which gave me the following xml example:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sub="https://example.com/path/to/sub"> <soapenv:Header> <sub:auth> <token>?</token> <!--Optional:--> <user_id>?</user_id> <!--Optional:--> <user_token>?</user_token> </sub:auth> </soapenv:Header> <soapenv:Body> <sub:customer_logos_pull> <!--Optional:--> <language>?</language> <!--Optional:--> <limit>?</limit> <!--Optional:--> <options_utc>?</options_utc> </sub:customer_logos_pull> </soapenv:Body> </soapenv:Envelope> 

In pysimplesoap, now I will try something like this:

 from pysimplesoap.client import SoapClient WSDL = 'https://example.com/some/path/sub.wsdl' TOKEN = 'xxx' client = SoapClient(wsdl=WSDL, trace=True) client['auth'] = {'token': TOKEN} print client.customer_logos_pull({}) 

but I get the error message ExpatError: not well-formed (invalid token): line 1, column 0 , which makes sense, because in the registered xml I see that the header is empty:

 <soap:Header/> 

I tried changing the code to include sub: before auth as follows: client['sub:auth'] = {'token': TOKEN} , but I get the same error.

Does anyone know what I'm doing wrong here? All tips are welcome!

+6
source share
1 answer

Therefore, I think that we can solve this problem using the suds library.

Here is a very simple example of sending a SOAP request that includes headers:

Example:

 from suds.sax.element import Element client = client(url) ssnns = ('ssn', 'http://namespaces/sessionid') ssn = Element('SessionID', ns=ssnns).setText('123') client.set_options(soapheaders=ssn) result = client.service.addPerson(person) 

This is an example of how you send the following header:

 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP ENC="http://www.w3.org/2003/05/soap-encoding"> <ssn:SessionID SOAP-ENV:mustUnderstand="true">123</ssn:SessionID> </SOAP-ENV:Header> 

NB: I really have not tried this on my own since I do not have access to any available SOAP / XML services with which I can test!

So, in your specific example, you would do something like this:

 >>> from suds.sax.element import Element >>> subns = ("sub", "http://namespaces/sub") >>> sub = Element("auth", ns=subns) >>> token = Element("token").setText("?") >>> user_id = Element("user_id").setText("?") >>> user_token = Element("user_token").setText("?") >>> sub.append(token) Element (prefix=sub, name=auth) >>> sub.append(user_id) Element (prefix=sub, name=auth) >>> sub.append(user_token) Element (prefix=sub, name=auth) >>> print(sub.str()) <sub:auth xmlns:sub="http://namespaces/sub"> <token>?</token> <user_id>?</user_id> <user_token>?</user_token> </sub:auth> 

Then call set_options() on your client object:

 client.set_options(soapheaders=sub) 

And you can easily install suds with pip by doing:

 $ pip install suds 
+3
source

Source: https://habr.com/ru/post/988338/


All Articles