mvantellingen / python-zeep

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

Invalid xsd type: xsd:Array #1111

Open poisonedPawn opened 4 years ago

poisonedPawn commented 4 years ago
  1. Zeep version: 3.
  2. The WSDL you are using: 3º part wsdl
  3. I found a problem parsing a WSDL file, the problem is in the next function of parser.py
 def parse_abstract_message(wsdl, xmlelement) 

when it try parse xsd:Array tags of messages, Zeep show me the next error:

UserWarning: The wsdl:message for '{URN:XXXXXXX}getFunctionRequest' contains an invalid part ('nameOfPart'): invalid xsd type or elements  warnings.warn(str(exc))

Do you know if "xsd:Array" xsd type can be parsing with Zeep?

Thx for help

da1910 commented 4 years ago

Zeep definitely does handle xsd:Array just fine, you will need to provide the relevant information from the wsdl and an example of the server response you're getting. Check here for steps to extract the response xml.

poisonedPawn commented 4 years ago

Hi,thx for the response, you are right. Its problem of WSDL file that don't include element part in the messages description. In the next lanes i will try explain the problem that I found debuggin Zeep:

messages def without element tag.

My WSDL message part have that format; you will notice the absence of elemnt part:

<message name="setMessageName"><part name="partName" type="xsd:Array"/></message>

The next funcition in the file parse.py, lanes 19 to 68, don't handle messages tags without element part,

def parse_abstract_message(wsdl, xmlelement):
.
. more code
.
        try:
            if part_element is not None:
                part_element = wsdl.types.get_element(part_element)
            if part_type is not None:
                part_type = wsdl.types.get_type(part_type)

        except (NamespaceError, LookupError):
            raise IncompleteMessage(
                (
                    "The wsdl:message for %r contains an invalid part (%r): "
                    "invalid xsd type or elements"
                )
                % (message_name.text, part_name)
            )
.
. more code
.

Trace: parser.py(l 150), wsdl.py (l 338,l 185, l 85)

I think it is the cause of the following two problems:

  1. definitions.py:137 The wsdl:operation 'operationName' was not found in the wsdl:portType '{URN:SERVICE}SERVICE_PortType'
  2. definitions.py:157 No such operation 'operationName' on '{URN:SERVICE}SERVICE_Binding

Maybe It's related with #106

da1910 commented 4 years ago

I encountered the same problem with a part that has no element, I have a suggested fix for issue #1115 which I will put in a PR this evening, give that a try and see if it sorts out the problem for you.

poisonedPawn commented 4 years ago

Really thx @da1910 :) I try it but that fix doesn't work for me T,t

I'm debuggin Zeep and my WSDL and I think It's problem of WSDL (and service) because it uses SOAP 1.1 with types of SOAP 1.2, then it isn't possible to parse the WSDL.

I know it becouse meanwhile debuggin the get_component function in schema.py l 585 to 605:

def _get_component(self, qname, items, item_name):
    try:
        return items[qname]
    except KeyError:
        known_items = ", ".join(items.keys())
        raise exceptions.LookupError(
            (
                "No %(item_name)s '%(localname)s' in namespace %(namespace)s. "
                + "Available %(item_name_plural)s are: %(known_items)s"
            )
            % {
                "item_name": item_name,
                "item_name_plural": item_name + "s",
                "localname": qname.localname,
                "namespace": qname.namespace,
                "known_items": known_items or " - ",
            },
            qname=qname,
            item_name=item_name,
            location=self._location,
        )

I saw that the URL for schema it's
http://schemas.xmlsoap.org/soap/encoding/ instead of https://www.w3.org/2003/05/soap-encoding

blackhold commented 3 months ago

Hi! I have the same problem, the wsdl file I have the type definition is to "xsd:Array". I'm trying the possibility to pass a schema to enable this type (https://schemas.xmlsoap.org/soap/encoding/) but I don't know if is the correct way.

My provider offers me the service like this. I will try if he can fix this, but I think is so complicated.

Where can I go now? if I load a custom wsdl file changing Array to string, zeep loads services OK, but then if I try to send a string formated as array it returns error:

(Pdb) client.service.getLineas('"user": "XXXX", "pass": "XXXX"') '0003'

Some help will be grateful!

Thanks you much.

update

I have changed message types xsd:String to xsd:string and xsd:Array to SOAP-ENC:Array and now -mzeep is able to parse wsdl file. I have uploaded this modified file to an internet location and zeep is able to use all services in wsdl file. Now I have the problem that receiving a different error from the server I'm connecting:

(Pdb) client.service.getLineas(datos)
{
    '_value_1': '0002',
    'arrayType': None,
    'offset': None,
    'id': None,
    'href': None,
    '_attr_1': None
}

This is the code I'm using to do the tests:

from requests import Session
from requests.auth import HTTPBasicAuth
from zeep import Client
from zeep.transports import Transport

def new_client():
    #_wsdl = 'https://URL1/ws/mv/gestXXX_2.php?wsdl'
    _wsdl = 'https://URL2/wp-content/uploads/2024/07/xxx_wsdl2.txt'
    _username = "XXX"
    _password = "XXX"
    session = Session()
    session.auth = HTTPBasicAuth(_username, _password)
    client = Client(_wsdl, transport=Transport(session=session))
    return client

client = new_client()
client2 = client.bind('XXX_2', 'XXX_2Port')

datos = {"user": "xxx", "pass": "xxx"}
datos2 = dict([["user", "xxx"], ["pass", "xxx"]])  # trying to use an other method to create the array

client.service.getLineas(datos)
client.service.getLineas(datos2)

import pdb
pdb.set_trace()