mvantellingen / python-zeep

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

WSDL service element should be optional #106

Closed mattpepin closed 8 years ago

mattpepin commented 8 years ago

Using zeep, I can't parse the ONVIF devicemgmt.wsdl file:

python -m zeep http://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl

zeep.exceptions.XMLParseError: References from this schema ('http://www.onvif.org/ver10/schema') to components in the namespace 'http://www.w3.org/2001/XMLSchema' are not allowed, since not indicated by an import statement.

I'm pretty sure the ONVIF spec uses valid WSDL/XML.

mvantellingen commented 8 years ago

Could you give the master branch a try?

mattpepin commented 8 years ago

Yup, I just did. Not sure if it's me but I get:

Error while finding spec for 'zeep.__main__' (<class 'ImportError'>: No module named 'cached_property'); 'zeep' is a package and cannot be directly executed

mattpepin commented 8 years ago

Nevermind, I figured it out. Now I get:

ValueError: No services found in the WSDL. Are you using the correct URL?

It's better than a ParseError. Not sure if the no services message is right though.

mvantellingen commented 8 years ago

Yeah saw that too. So the wsdl doesn't define any service, but that might be valid. There should be an interface to define your own then. Are you able to propose something for that in a PR? :-)

mattpepin commented 8 years ago

I'm trying the master branch with a real IP camera. I'll keep you posted!

mattpepin commented 8 years ago

Ah I see, I looked at how python-onvif does it (I can't use that lib since it's not Python3-compatible). It uses suds and in the Client constructor, there is an additional location argument. It overrides the service port address URL defined in the WSDL. It looks like this is missing in zeep. The location for an IP camera is:

http://ip/onvif/device_service

mattpepin commented 8 years ago

OK, new error ;)

If I edit the WSDL to add the following:

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

I get the following error:

  File "/home/matt/a/lib/python3.5/site-packages/zeep/xsd/types.py", line 283, in signature
    part = element.signature()
  File "/home/matt/a/lib/python3.5/site-packages/zeep/xsd/elements.py", line 482, in signature
    parts.append('%s: %s' % (name, element.signature()))
RecursionError: maximum recursion depth exceeded
mattpepin commented 8 years ago

The Python client works though! Thanks :)

from zeep import Client
c = Client('devicemgmt.wsdl')
c.service.GetSystemDateAndTime()
{   'DateTimeType': 'Manual',
    'DaylightSavings': False,
    'Extension': None,
    'LocalDateTime': {   'Date': {'Day': 2, 'Month': 9, 'Year': 2015},
    'Time': {'Hour': 8, 'Minute': 2, 'Second': 18}},
    'TimeZone': {'TZ': 'CST-8:00:00'},
    'UTCDateTime': {   'Date': {'Day': 2, 'Month': 9, 'Year': 2015},
    'Time': {'Hour': 0, 'Minute': 2, 'Second': 18}}}
mvantellingen commented 8 years ago

The last master fixes (although it is currently more of a workaround) for the recursionerror

mattpepin commented 8 years ago

Wow that's awesome :) Can't wait to try it.

mattpepin commented 8 years ago

It works perfectly. I really like the new create_service(). Thanks.

Talkless commented 6 years ago

I still have this issue, but with create_message():

Traceback (most recent call last):
  File "/home/vincas/code/eclipse-workspace-python-zeep/zeep-test/main.py", line 33, in <module>
    onvif_manual_xml()
  File "/home/vincas/code/eclipse-workspace-python-zeep/zeep-test/main.py", line 30, in onvif_manual_xml
    print(client.create_message(service, 'AbsoluteMove', profile_token, position))
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/client.py", line 226, in create_message
    operation_name, args, kwargs, client=self)
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/wsdl/bindings/soap.py", line 77, in _create
    options = client.service._binding_options
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/client.py", line 151, in service
    "There is no default service defined. This is usually due to "
ValueError: There is no default service defined. This is usually due to missing wsdl:service definitions in the WSDL

Example code:

#!/usr/bin/env python3

from zeep import Client
from zeep.cache import SqliteCache
from zeep.transports import Transport
from zeep.wsse.username import UsernameToken

def onvif_manual_xml():
    transport = Transport(cache=SqliteCache())

    client = Client('https://www.onvif.org/ver20/ptz/wsdl/ptz.wsdl',
                    transport=transport,
                    wsse=UsernameToken('admin', 'admin', use_digest=True))

    service = client.create_service('{http://www.onvif.org/ver20/ptz/wsdl}PTZBinding', 'http://192.168.1.108/onvif/ptz_service')

    f = client.type_factory('http://www.onvif.org/ver10/schema')

    profile_token = f.ReferenceToken(None)
    position = f.PTZVector(f.Vector2D(x=0, y=0), f.Vector1D(x=1.0))

    # Just testing
    #absolute_move_req_el = client.get_element('{http://www.onvif.org/ver20/ptz/wsdl}AbsoluteMove')
    #absolute_move_req = absolute_move_req_el(profile_token, position)
    #print(absolute_move_req)

    # This works
    #service.AbsoluteMove(profile_token, position)

    print(client.create_message(service, 'AbsoluteMove', profile_token, position))

if __name__ == '__main__':
    onvif_manual_xml()

Please note that service.AbsoluteMove(profile_token, position) does work.

zeeep 2.4.0 from pip, Python 3.6.3 via pyenv on Debian 8 (jessie)

return42 commented 6 years ago

Try client.wsdl.dump()or ..

>>> client.wsdl.services
OrderedDict()

it seems to me, that there is no service defined in the WSDL. Which is also what the message says:

ValueError: There is no default service defined. This is usually due to missing wsdl:service definitions in the WSDL
Talkless commented 6 years ago

Well, this bug is about

service element should be optional

, and it's marked as closed. So I was expecting it to work, especially as I have used create_service().

client.wsdl.dump() output:


Prefixes:
     xsd: http://www.w3.org/2001/XMLSchema
     ns0: http://www.onvif.org/ver20/ptz/wsdl
     ns1: http://www.onvif.org/ver10/schema
     ns2: http://www.w3.org/2005/05/xmlmime
     ns3: http://www.w3.org/2003/05/soap-envelope
     ns4: http://www.w3.org/XML/1998/namespace
     ns5: http://docs.oasis-open.org/wsn/b-2
     ns6: http://www.w3.org/2005/08/addressing
     ns7: http://docs.oasis-open.org/wsrf/bf-2
     ns8: http://docs.oasis-open.org/wsn/t-1
     ns9: http://www.w3.org/2004/08/xop/include

Global elements:
     ns5:ConsumerReference(ns6:EndpointReferenceType)
     ns5:CreatePullPoint(_value_1: ANY[], _attr_1: {})
     ns5:CreatePullPointResponse(PullPoint: ns6:EndpointReferenceType, _value_1: ANY[], _attr_1: {})
     ns5:CreationTime(xsd:dateTime)
     ns5:CurrentTime(xsd:dateTime)
     ns5:DestroyPullPoint(_value_1: ANY[], _attr_1: {})
     ns5:DestroyPullPointResponse(_value_1: ANY[], _attr_1: {})
     ns5:Filter(ns5:FilterType)
     ns5:FixedTopicSet(xsd:boolean)
     ns5:GetCurrentMessage(Topic: ns5:TopicExpressionType, _value_1: ANY[])
     ns5:GetCurrentMessageResponse(_value_1: ANY[])
     ns5:GetMessages(MaximumNumber: xsd:nonNegativeInteger, _value_1: ANY[], _attr_1: {})
     ns5:GetMessagesResponse(NotificationMessage: ns5:NotificationMessageHolderType[], _value_1: ANY[], _attr_1: {})
     ns5:InvalidFilterFault(ns5:InvalidFilterFaultType)
     ns5:InvalidMessageContentExpressionFault(ns5:InvalidMessageContentExpressionFaultType)
     ns5:InvalidProducerPropertiesExpressionFault(ns5:InvalidProducerPropertiesExpressionFaultType)
     ns5:InvalidTopicExpressionFault(ns5:InvalidTopicExpressionFaultType)
     ns5:MessageContent(ns5:QueryExpressionType)
     ns5:MultipleTopicsSpecifiedFault(ns5:MultipleTopicsSpecifiedFaultType)
     ns5:NoCurrentMessageOnTopicFault(ns5:NoCurrentMessageOnTopicFaultType)
     ns5:NotificationMessage(ns5:NotificationMessageHolderType)
     ns5:NotificationProducerRP(TopicExpression: ns5:TopicExpressionType[], FixedTopicSet: xsd:boolean, TopicExpressionDialect: xsd:anyURI[], TopicSet: ns8:TopicSetType)
     ns5:Notify(NotificationMessage: ns5:NotificationMessageHolderType[], _value_1: ANY[])
     ns5:NotifyMessageNotSupportedFault(ns5:NotifyMessageNotSupportedFaultType)
     ns5:PauseFailedFault(ns5:PauseFailedFaultType)
     ns5:PauseSubscription(_value_1: ANY[])
     ns5:PauseSubscriptionResponse(_value_1: ANY[])
     ns5:ProducerProperties(ns5:QueryExpressionType)
     ns5:ProducerReference(ns6:EndpointReferenceType)
     ns5:Renew(TerminationTime: , _value_1: ANY[])
     ns5:RenewResponse(TerminationTime: xsd:dateTime, CurrentTime: xsd:dateTime, _value_1: ANY[])
     ns5:ResumeFailedFault(ns5:ResumeFailedFaultType)
     ns5:ResumeSubscription(_value_1: ANY[])
     ns5:ResumeSubscriptionResponse(_value_1: ANY[])
     ns5:Subscribe(ConsumerReference: ns6:EndpointReferenceType, Filter: ns5:FilterType, InitialTerminationTime: , SubscriptionPolicy: {_value_1: ANY[]}, _value_1: ANY[])
     ns5:SubscribeCreationFailedFault(ns5:SubscribeCreationFailedFaultType)
     ns5:SubscribeResponse(SubscriptionReference: ns6:EndpointReferenceType, CurrentTime: xsd:dateTime, TerminationTime: xsd:dateTime, _value_1: ANY[])
     ns5:SubscriptionManagerRP(ConsumerReference: ns6:EndpointReferenceType, Filter: ns5:FilterType, SubscriptionPolicy: ns5:SubscriptionPolicyType, CreationTime: xsd:dateTime)
     ns5:SubscriptionPolicy(ns5:SubscriptionPolicyType)
     ns5:SubscriptionReference(ns6:EndpointReferenceType)
     ns5:TerminationTime(xsd:dateTime)
     ns5:Topic(ns5:TopicExpressionType)
     ns5:TopicExpression(ns5:TopicExpressionType)
     ns5:TopicExpressionDialect(xsd:anyURI)
     ns5:TopicExpressionDialectUnknownFault(ns5:TopicExpressionDialectUnknownFaultType)
     ns5:TopicNotSupportedFault(ns5:TopicNotSupportedFaultType)
     ns5:UnableToCreatePullPointFault(ns5:UnableToCreatePullPointFaultType)
     ns5:UnableToDestroyPullPointFault(ns5:UnableToDestroyPullPointFaultType)
     ns5:UnableToDestroySubscriptionFault(ns5:UnableToDestroySubscriptionFaultType)
     ns5:UnableToGetMessagesFault(ns5:UnableToGetMessagesFaultType)
     ns5:UnacceptableInitialTerminationTimeFault(ns5:UnacceptableInitialTerminationTimeFaultType)
     ns5:UnacceptableTerminationTimeFault(ns5:UnacceptableTerminationTimeFaultType)
     ns5:UnrecognizedPolicyRequestFault(ns5:UnrecognizedPolicyRequestFaultType)
     ns5:Unsubscribe(_value_1: ANY[])
     ns5:UnsubscribeResponse(_value_1: ANY[])
     ns5:UnsupportedPolicyRequestFault(ns5:UnsupportedPolicyRequestFaultType)
     ns5:UseRaw()
     ns8:TopicNamespace(ns8:TopicNamespaceType)
     ns8:TopicSet(ns8:TopicSetType)
     ns7:BaseFault(ns7:BaseFaultType)
     ns1:AudioDecoderConfiguration(ns1:AudioDecoderConfiguration)
     ns1:AudioEncoderConfiguration(ns1:AudioEncoderConfiguration)
     ns1:AudioOutputConfiguration(ns1:AudioOutputConfiguration)
     ns1:AudioSourceConfiguration(ns1:AudioSourceConfiguration)
     ns1:Message(Source: ns1:ItemList, Key: ns1:ItemList, Data: ns1:ItemList, Extension: ns1:MessageExtension, UtcTime: xsd:dateTime, PropertyOperation: ns1:PropertyOperation, _attr_1: {})
     ns1:MetadataConfiguration(ns1:MetadataConfiguration)
     ns1:PTZConfiguration(ns1:PTZConfiguration)
     ns1:Polygon(ns1:Polygon)
     ns1:Polyline(ns1:Polyline)
     ns1:VideoAnalyticsConfiguration(ns1:VideoAnalyticsConfiguration)
     ns1:VideoEncoderConfiguration(ns1:VideoEncoderConfiguration)
     ns1:VideoSourceConfiguration(ns1:VideoSourceConfiguration)
     ns0:AbsoluteMove(ProfileToken: ns1:ReferenceToken, Position: ns1:PTZVector, Speed: ns1:PTZSpeed)
     ns0:AbsoluteMoveResponse()
     ns0:Capabilities(ns0:Capabilities)
     ns0:ContinuousMove(ProfileToken: ns1:ReferenceToken, Velocity: ns1:PTZSpeed, Timeout: xsd:duration)
     ns0:ContinuousMoveResponse()
     ns0:CreatePresetTour(ProfileToken: ns1:ReferenceToken)
     ns0:CreatePresetTourResponse(PresetTourToken: ns1:ReferenceToken)
     ns0:GeoMove(ProfileToken: ns1:ReferenceToken, Target: ns1:GeoLocation, Speed: ns1:PTZSpeed, AreaHeight: xsd:float, AreaWidth: xsd:float)
     ns0:GeoMoveResponse()
     ns0:GetCompatibleConfigurations(ProfileToken: ns1:ReferenceToken)
     ns0:GetCompatibleConfigurationsResponse(PTZConfiguration: ns1:PTZConfiguration[])
     ns0:GetConfiguration(PTZConfigurationToken: ns1:ReferenceToken)
     ns0:GetConfigurationOptions(ConfigurationToken: ns1:ReferenceToken)
     ns0:GetConfigurationOptionsResponse(PTZConfigurationOptions: ns1:PTZConfigurationOptions)
     ns0:GetConfigurationResponse(PTZConfiguration: ns1:PTZConfiguration)
     ns0:GetConfigurations()
     ns0:GetConfigurationsResponse(PTZConfiguration: ns1:PTZConfiguration[])
     ns0:GetNode(NodeToken: ns1:ReferenceToken)
     ns0:GetNodeResponse(PTZNode: ns1:PTZNode)
     ns0:GetNodes()
     ns0:GetNodesResponse(PTZNode: ns1:PTZNode[])
     ns0:GetPresetTour(ProfileToken: ns1:ReferenceToken, PresetTourToken: ns1:ReferenceToken)
     ns0:GetPresetTourOptions(ProfileToken: ns1:ReferenceToken, PresetTourToken: ns1:ReferenceToken)
     ns0:GetPresetTourOptionsResponse(Options: ns1:PTZPresetTourOptions)
     ns0:GetPresetTourResponse(PresetTour: ns1:PresetTour)
     ns0:GetPresetTours(ProfileToken: ns1:ReferenceToken)
     ns0:GetPresetToursResponse(PresetTour: ns1:PresetTour[])
     ns0:GetPresets(ProfileToken: ns1:ReferenceToken)
     ns0:GetPresetsResponse(Preset: ns1:PTZPreset[])
     ns0:GetServiceCapabilities()
     ns0:GetServiceCapabilitiesResponse(Capabilities: ns0:Capabilities)
     ns0:GetStatus(ProfileToken: ns1:ReferenceToken)
     ns0:GetStatusResponse(PTZStatus: ns1:PTZStatus)
     ns0:GotoHomePosition(ProfileToken: ns1:ReferenceToken, Speed: ns1:PTZSpeed)
     ns0:GotoHomePositionResponse()
     ns0:GotoPreset(ProfileToken: ns1:ReferenceToken, PresetToken: ns1:ReferenceToken, Speed: ns1:PTZSpeed)
     ns0:GotoPresetResponse()
     ns0:ModifyPresetTour(ProfileToken: ns1:ReferenceToken, PresetTour: ns1:PresetTour)
     ns0:ModifyPresetTourResponse()
     ns0:OperatePresetTour(ProfileToken: ns1:ReferenceToken, PresetTourToken: ns1:ReferenceToken, Operation: ns1:PTZPresetTourOperation)
     ns0:OperatePresetTourResponse()
     ns0:RelativeMove(ProfileToken: ns1:ReferenceToken, Translation: ns1:PTZVector, Speed: ns1:PTZSpeed)
     ns0:RelativeMoveResponse()
     ns0:RemovePreset(ProfileToken: ns1:ReferenceToken, PresetToken: ns1:ReferenceToken)
     ns0:RemovePresetResponse()
     ns0:RemovePresetTour(ProfileToken: ns1:ReferenceToken, PresetTourToken: ns1:ReferenceToken)
     ns0:RemovePresetTourResponse()
     ns0:SendAuxiliaryCommand(ProfileToken: ns1:ReferenceToken, AuxiliaryData: ns1:AuxiliaryData)
     ns0:SendAuxiliaryCommandResponse(AuxiliaryResponse: ns1:AuxiliaryData)
     ns0:SetConfiguration(PTZConfiguration: ns1:PTZConfiguration, ForcePersistence: xsd:boolean)
     ns0:SetConfigurationResponse()
     ns0:SetHomePosition(ProfileToken: ns1:ReferenceToken)
     ns0:SetHomePositionResponse()
     ns0:SetPreset(ProfileToken: ns1:ReferenceToken, PresetName: xsd:string, PresetToken: ns1:ReferenceToken)
     ns0:SetPresetResponse(PresetToken: ns1:ReferenceToken)
     ns0:Stop(ProfileToken: ns1:ReferenceToken, PanTilt: xsd:boolean, Zoom: xsd:boolean)
     ns0:StopResponse()

     ns3:Body(ns3:Body)
     ns3:Envelope(ns3:Envelope)
     ns3:Fault(ns3:Fault)
     ns3:Header(ns3:Header)
     ns3:NotUnderstood(ns3:NotUnderstoodType)
     ns3:Upgrade(ns3:UpgradeType)
     ns9:Include(ns9:Include)
     ns6:Action(ns6:AttributedURIType)
     ns6:EndpointReference(ns6:EndpointReferenceType)
     ns6:FaultTo(ns6:EndpointReferenceType)
     ns6:From(ns6:EndpointReferenceType)
     ns6:MessageID(ns6:AttributedURIType)
     ns6:Metadata(ns6:MetadataType)
     ns6:ProblemAction(ns6:ProblemActionType)
     ns6:ProblemHeader(ns6:AttributedAnyType)
     ns6:ProblemHeaderQName(ns6:AttributedQNameType)
     ns6:ProblemIRI(ns6:AttributedURIType)
     ns6:RelatesTo(ns6:RelatesToType)
     ns6:ReplyTo(ns6:EndpointReferenceType)
     ns6:RetryAfter(ns6:AttributedUnsignedLongType)
     ns6:To(ns6:AttributedURIType)

Global types:
     xsd:anyType
     ns5:FilterType(_value_1: ANY[])
Traceback (most recent call last):
  File "/home/vincas/code/eclipse-workspace-python-zeep/zeep-test/main.py", line 37, in <module>
    onvif_manual_xml()
  File "/home/vincas/code/eclipse-workspace-python-zeep/zeep-test/main.py", line 15, in onvif_manual_xml
    client.wsdl.dump()
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/wsdl/wsdl.py", line 108, in dump
    value = type_obj.signature(schema=self.types)
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/xsd/types/complex.py", line 444, in signature
    part = element.signature(schema, standalone=False)
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/xsd/elements/indicators.py", line 254, in signature
    value = element.signature(schema, standalone=False)
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/xsd/elements/element.py", line 263, in signature
    value = self.type.signature(schema, standalone=False)
  File "/home/vincas/opt/pyenv.git/versions/python-venv-zeep/lib/python3.6/site-packages/zeep/xsd/types/complex.py", line 451, in signature
    value = ', '.join(parts)
TypeError: sequence item 0: expected str instance, NoneType found
return42 commented 6 years ago

service element should be optional

Argh, sorry .. shame on me, you are right.

ThiefMaster commented 2 years ago

@Talkless Did you find a solution for your problem? I'm trying to access the API of an Axis camera (looking at your output you seem to be doing the same) and I'm getting the exact same error there...

Talkless commented 2 years ago

@ThiefMaster Sorry, I don't recall what I did. I'll could try to check on Tuesday when I will be at work, if I don't forget...

EmpireofKings commented 1 year ago

You can edit zeep/xsd/types/complex.py and replace the function signature with this below...

It simply, ignores the error, it does not solve the root issue of the problem, but will allow you to run the script.


def signature(self, schema=None, standalone=True):
        parts = []
        for name, element in self.elements_nested:
            part = element.signature(schema, standalone=standalone)
            parts.append(part)

        for name, attribute in self.attributes:
            part = "%s: %s" % (name, attribute.signature(schema, standalone=standalone))
            parts.append(part)
        try:
            value = ", ".join(parts)
        except:
            value = ""
        if standalone:
            return "%s(%s)" % (self.get_prefixed_name(schema), value)
        else:
            return value