2015-06-01 22 views
6

Ho ricevuto qualche esempio di codice php per chiamare un servizio SOAP che ora ho bisogno di convertire in Python. Nel codice php si misero le intestazioni come segue:Perché non posso impostare le intestazioni SOAP in pysimplesoap?

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

Quindi l'intestazione auth dovrebbe assomigliare a questa: ['token' => 'xxx']. Poi ho caricato il WSDL in SoapUI, che mi ha dato il seguente esempio xml:

<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 ora provare qualcosa di simile:

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({}) 

ma ottengo un errore che dice ExpatError: not well-formed (invalid token): line 1, column 0, che ha un senso , perché nel xML Accesso vedo che l'intestazione è vuota:

<soap:Header/> 

ho provato variando il codice includendo il sub: b efore auth piace questo: client['sub:auth'] = {'token': TOKEN}, ma ottengo lo stesso errore.

Qualcuno sa cosa sto facendo male qui? Tutti i suggerimenti sono ben accetti!

+0

ha a usare [pysimplesoap] (https://pypi.python.org/pypi/pysimplesoap) - Non può nemmeno essere installato come è sorta di rotto:/ –

+0

@JamesMills - doesn Devo essere pysimplesoap di per sé. Ho solo bisogno di farlo funzionare. L'ho provato anche usando la schiuma. Ma non riesco a farlo funzionare: http://stackoverflow.com/questions/30874988/how-to-create-soap-header-with-python-suds-library La libreria che uso non ha importanza, è solo bisogno di essere in Python, questo è tutto. Sapresti come farlo in una libreria diversa? – kramer65

risposta

3

Quindi penso che possiamo risolvere utilizzando la libreria suds.

Ecco un molto di base esempio di come inviare una richiesta SOAP che include le intestazioni:

Esempio:

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) 

Questo è un esempio di come devi inviare il seguente intestazione:

<?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: In realtà non ho provato loperché non ho accesso a servizi SOAP/XML prontamente disponibili su cui posso testare!

Quindi nel tuo caso particolare si potrebbe fare qualcosa di simile:

>>> 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> 

Quindi chiamare set_options() sul client oggetto:

client.set_options(soapheaders=sub) 

E si può facilmente installare suds utilizzando pip eseguendo:

$ pip install suds