1

I'm trying to call a SOAP webservice from the Dutch land register (WSDL here). I first tried doing that using the pysimplesoap library. Although I do get relevant xml back, pysimplesoap gives a TypeError: Tag: IMKAD_Perceel invalid (type not found) (I created a SO question about that here). Since I suspect this to be a bug in pysimplesoap I'm now trying to use the suds library.

In pysimplesoap the following returned correct xml (but as I said pysimplesoap gave a TypeError):

from pysimplesoap.client import SoapClient
client = SoapClient(wsdl='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl', username=xxx, password=xxx, trace=True)
response = client.VerzoekTotInformatie(
    Aanvraag={
        'berichtversie': '4.7',  # Refers to the schema version: http://www.kadaster.nl/web/show?id=150593&op=/1/schemas/homepage.html
        'klantReferentie': 'MyReference1',  # Refers to something we can set ourselves.
        'productAanduiding': '1185',  # a four-digit code referring to whether the response should be in "XML" (1185), "PDF" (1191) or "XML and PDF" (1057).
        'Ingang': {
            'Object': {
                'IMKAD_KadastraleAanduiding': {
                    'gemeente': 'ARNHEM',
                    'sectie': 'AC',
                    'perceelnummer': '1234'
                }
            }
        }
    }
)

This produced the xml below:

<soap:Body>
  <VerzoekTotInformatieRequest xmlns="http://www.kadaster.nl/schemas/kik-inzage/20141101">
    <Aanvraag xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
      <berichtversie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">4.7</berichtversie>
      <klantReferentie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">ARNHEM-AC-1234</klantReferentie>
      <productAanduiding xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">1185</productAanduiding>
      <Ingang xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
        <Object xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
          <IMKAD_KadastraleAanduiding xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
            <gemeente xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">ARNHEM AC</gemeente>
            <sectie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">AC</sectie>
            <perceelnummer xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">5569</perceelnummer>
          </IMKAD_KadastraleAanduiding>
        </Object>
      </Ingang>
    </Aanvraag>
  </VerzoekTotInformatieRequest>
</soap:Body>

So now I tried changing this code to use suds instead. So far I came up with this:

from suds.client import Client
client = Client(url='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl', username='xxx', password='xxx')
Aanvraag = client.factory.create('ns3:Aanvraag')
Aanvraag.berichtversie = '4.7'
Aanvraag.klantReferentie = 'MyReference1'
Aanvraag.productAanduiding = '1185'
IMKAD_KadastraleAanduiding = client.factory.create('ns3:IMKAD_KadastraleAanduiding')
IMKAD_KadastraleAanduiding.gemeente = 'ARNHEM'
IMKAD_KadastraleAanduiding.sectie = 'AC'
IMKAD_KadastraleAanduiding.perceelnummer = '1234'
Object = client.factory.create('ns3:Object')
Object.IMKAD_KadastraleAanduiding = IMKAD_KadastraleAanduiding
Ingang = client.factory.create('ns3:Ingang')
Ingang.Object = Object
Aanvraag.Ingang = Ingang

result = client.service.VerzoekTotInformatie(Aanvraag)

which produces the following xml:

<ns2:Body>
  <ns0:VerzoekTotInformatieRequest>
    <ns0:Aanvraag>
      <ns1:berichtversie>4.7</ns1:berichtversie>
      <ns1:klantReferentie>MyReference1</ns1:klantReferentie>
      <ns1:productAanduiding>1185</ns1:productAanduiding>
      <ns1:Ingang>
        <ns1:Object>
          <ns1:IMKAD_KadastraleAanduiding>
            <ns1:gemeente>ARNHEM</ns1:gemeente>
            <ns1:sectie>AC</ns1:sectie>
            <ns1:perceelnummer>1234</ns1:perceelnummer>
          </ns1:IMKAD_KadastraleAanduiding>
        </ns1:Object>
      </ns1:Ingang>
    </ns0:Aanvraag>
  </ns0:VerzoekTotInformatieRequest>
</ns2:Body>

Unfortunately, this results in the server giving back a Nullpointer:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
    result = client.service.VerzoekTotInformatie(Aanvraag)
  File "/Library/Python/2.7/site-packages/suds/client.py", line 542, in __call__
    return client.invoke(args, kwargs)
  File "/Library/Python/2.7/site-packages/suds/client.py", line 602, in invoke
    result = self.send(soapenv)
  File "/Library/Python/2.7/site-packages/suds/client.py", line 649, in send
    result = self.failed(binding, e)
  File "/Library/Python/2.7/site-packages/suds/client.py", line 702, in failed
    r, p = binding.get_fault(reply)
  File "/Library/Python/2.7/site-packages/suds/bindings/binding.py", line 265, in get_fault
    raise WebFault(p, faultroot)
WebFault: Server raised fault: 'java.lang.NullPointerException'

This error is of course terribly unhelpful. The error gives no hint whatsoever on what causes the NullPointer.

If I look at the differences between the xml which pysimplesoap and suds send over the wire, the xml by suds is missing a lot of xmlns definitions (although I don't know whether they are needed) and the names of the tags include prefixes with for example ns0:. I don't know if these differences are relevant, and I also don't know how I would make suds create the same xml as pysimplesoap.

Although the wsdl file of the service is public, the service itself is paid (€60 yearly + €3 for every successful request). So I guess it is hard/impossible for people reading this to reproduce the issue, and I can't really give out my user credentials here.

But since I'm really stuck on this issue, maybe someone can give me some tips on how to debug this? For example; how can I make suds create the same xml as pysimplesoap? Or how I can get more information on the nullpointer?

Any help is welcome!

Community
  • 1
  • 1
kramer65
  • 50,427
  • 120
  • 308
  • 488

1 Answers1

-1

This is not so much an answer, but an advice from prior experience with Python and SOAP.

  1. Find some good (established, reference for SOAP) Java tool for making SOAP queries given WSDL.
  2. Make some typical queries, interesting to you, and record what is being sent / received as templates
  3. Forget Python SOAP libraries and just use template to query SOAP endpoint (there are many templating languages for Python).

If the step 2. fails with the prominent Java tool, contact techsupport of the service you are paying for.

Have you checked whether all those nice XSDs are really downloaded by Python SOAP clients?

Roman Susi
  • 4,135
  • 2
  • 32
  • 47