Search code examples
pythonwsdlonvifzeep

ONVIF - Python + ZEEP: create_service not working


I'm implementing an application using ONVIF protocol. There is a WSDL file https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl which I have to work with. But it's necessary to define default service, to add following code into WSDL file:

<wsdl:service name="DeviceService">
    <wsdl:port name="DevicePort" binding="tds:DeviceBinding">
        <soap:address location="http://ip_address/onvif/device_service"/>
    </wsdl:port>
</wsdl:service>

But it's not possible due to these points:

  1. to add the Node into the WSDL file, you have to download the WSDL file (this is not a real problem, because I downloaded the file due to performance - for now)
  2. the application should communicate with many IP cameras in various networks, so it's not possible to define line: <soap:address location="http://ip/onvif/device_service"/>

So I was looking for some solution and I've found it in Zeep documentation (http://docs.python-zeep.org/en/master/client.html#creating-new-serviceproxy-objects), where is written:

There are situations where you either need to change the SOAP address from the one which is defined within the WSDL or the WSDL doesn’t define any service elements.

So I've tried to call this:

client = Client(
    wsdl = '/path/to/local/wsdl_file.wsdl',
    wsse = self.InitSecurity(),
    service_name = 'DeviceService',
    port_name = 'DevicePort'
)

service = client.create_service(
    '{http://www.onvif.org/ver10/device/wsdl}DeviceBinding',
    'http://ip_address/onvif/device_service'
)

But when I run the script, following exception is thrown:

ValueError: There is no default service defined. This is usually due to missing wsdl:service definitions in the WSDL

And when I modify WSDL file directly (add the Node above), everything works correctly.

Any idea, please? I'm fighting with a while, so I need to kick a little bit.

Thank you.


Solution

  • The service = client.create_service() should work (see also https://github.com/mvantellingen/python-zeep/issues/106 for the same wsdl).

    Are you using the created service object for subsequent calls (e.g. service.Operation() instead of the client?