zeepcisco-axl

zeep.exceptions.XMLSyntaxError:The root element found is html


I am trying to use Zeep to send SOAP request to a Cisco CM server to make MACD operation however getting the following error: zeep.exceptions.XMLSyntaxError: The XML returned by the server does not contain a valid {http://schemas.xmlsoap.org/soap/envelope/}Envelope root element. The root element found is html

Here is the traceback:

Traceback (most recent call last):
  File "zeepTest.py", line 39, in <module>
    resp = service.listPhone(searchCriteria={'name': 'CIPCDemo1'}, returnedTags={'name':'', 'description':''})
  File "My|project\Path\lib\site-packages\zeep\proxy.py", line 45, in __call__
    kwargs,
  File "My|project\Path\lib\site-packages\zeep\wsdl\bindings\soap.py", line 130, in send
    return self.process_reply(client, operation_obj, response)
  File "My|project\Path\lib\site-packages\zeep\wsdl\bindings\soap.py", line 197, in process_reply
    result = operation.process_reply(doc)
  File "My|project\Path\lib\site-packages\zeep\wsdl\bindings\soap.py", line 392, in process_reply
    % (envelope_qname.namespace, envelope.tag)
zeep.exceptions.XMLSyntaxError: The XML returned by the server does not contain a valid {http://schemas.xmlsoap.org/soap/envelope/}Envelope root element. The root element found is html

Since no hits on SO for this error,I have tried to understand zeep\wsdl\bindings\soap.py I have made the same SOAP request over Postman and it works. I have tried other libraries (SUDS) but they fail as the server is SSL secured.

Here is my code:

from zeep import Client
from zeep.cache import SqliteCache
from zeep.transports import Transport
from zeep.exceptions import Fault
from zeep.plugins import HistoryPlugin
from requests import Session
from requests.auth import HTTPBasicAuth
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning
from lxml import etree

disable_warnings(InsecureRequestWarning)

username = '<axlusername>'
password = '<password>'

host = '<IP address>'

wsdl = r'my/wsdl/file/path'

location = 'https://{host}:8443/axl'.format(host=host)
binding = r"{http://www.cisco.com/AXLAPIService/}AXLAPIBinding"

session = Session()
session.verify = False
session.auth = HTTPBasicAuth(username, password)

transport = Transport(cache=SqliteCache(), session=session, timeout=20)
history = HistoryPlugin()
client = Client(wsdl=wsdl, transport=transport, plugins=[history])
service = client.create_service( binding, location)

def show_history():
    for item in [history.last_sent, history.last_received]:
        print(etree.tostring(item["envelope"], encoding="unicode", pretty_print=True))

resp = service.listPhone(searchCriteria={'name': '<PhoneName'}, returnedTags={'name':'', 'description':''})

print(resp)

Expected results:

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns:getPhoneResponse xmlns:ns="http://www.cisco.com/AXL/API/10.5">
            <return>
                <phone ctiid="91" uuid="{A6A03D42-D167-4F64-BE68}">
                    <name>Phone Name</name>
                    ... data ommited...
                </phone>
            </return>
        </ns:getPhoneResponse>
    </soapenv:Body>
</soapenv:Envelope>     

Solution

  • It appears the AXL URL in your code is missing the trailing slash '/'. Can you try adding, i.e.:

    location = 'https://{host}:8443/axl/'.format(host=host)