mvantellingen / python-zeep

A Python SOAP client
http://docs.python-zeep.org
Other
1.89k stars 587 forks source link

Plugin egress not doing anything #217

Closed FrugoFruit90 closed 8 years ago

FrugoFruit90 commented 8 years ago

I need to add a custom namespace to the XML that I send to the server (wsdl is in the code). I tried to do it similarly as I would with suds, i.e. by using a message plugin. Unfortunately, nothing happens. the envelope stays the same. In fact, when I run the code in debug mode I could see that the envelope was never once modified even directly after the line that is supposed to add a namespace. Below is the code that reproduces this:

from zeep import Client
from zeep.transports import Transport

class MyPlugin(Plugin):
    def egress(self, envelope, http_headers, operation, binding_options):
        envelope.nsmap['n11'] = 'http://www.nfz.gov.pl/xml/prkus/sso/drukuj-karte/v3.0'
        return envelope, http_headers

wsdl = 'https://test-dilo.nfz.gov.pl/ws-broker-server-pkus-auth/services/Auth?wsdl'
client = Client(wsdl=wsdl, transport=Transport(verify=False), plugins=[MyPlugin()])
domain = "07"
login = "XXXX"
password = "XXXXX"
credentials = {"item": [{"name": "login", 'value': {"stringValue": login}},
                        {"name": "domain", 'value': {"stringValue": domain}}]}
response = client.service.login(credentials=credentials, password=password)

And here is the the XML that is being sent, courtesy of the logger (I set it up as in the documentation):

zeep.transports: HTTP Post to https://test-dilo.nfz.gov.pl/ws-broker-server-pkus-auth/services/Auth:
<?xml version='1.0' encoding='utf-8'?>
<soap-env:Envelope xmlns:ns3="http://xml.kamsoft.pl/ws/kaas/login_types" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Body>
    <ns3:login>
      <ns3:credentials>
        <ns3:item>
          <ns3:name>login</ns3:name>
          <ns3:value>
            <ns3:stringValue>XXXX</ns3:stringValue>
          </ns3:value>
        </ns3:item>
        <ns3:item>
          <ns3:name>domain</ns3:name>
          <ns3:value>
            <ns3:stringValue>07</ns3:stringValue>
          </ns3:value>
        </ns3:item>
      </ns3:credentials>
      <ns3:password>XXXXX</ns3:password>
    </ns3:login>
  </soap-env:Body>
</soap-env:Envelope>

As you can see, there is no xmlns:n11="http://www.nfz.gov.pl/xml/prkus/sso/drukuj-karte/v3.0" in the resulting XML. Any idea what is wrong here?

As always, I will be more than happy to provide additional information and perform any necessary tests. Cheers!

mvantellingen commented 8 years ago

Element.nsmap is readonly, see for example:

>>> from lxml import etree
>>> foo = etree.Element('foo')
>>> etree.tostring(foo)
b'<foo/>'
>>> foo.nsmap
{}
>>> foo.nsmap['x'] = 'http://example.org'
>>> foo.nsmap
{}
FrugoFruit90 commented 8 years ago

Is there a different way in which I should make changes like adding a custom namespace that is undefined in the wsdl but required by the server? Or is such functionality unsupported at the moment?

mvantellingen commented 8 years ago

Well zeep uses lxml for the xml generation. So it needs to be supported by lxml. You can register a custom prefix via etree.register_namespace() but then you still need to add an element with that namespace in order to get it in the xml. Not sure how, it's a bit out of scope of zeep i'm afraid.

Perhaps you can workaround it by adding an header element with that namespace and hoping that your server ignores it?

mvantellingen commented 8 years ago

Closing for now (trying to keep the number of open issues limited)