pythonxmlsoapspyne

xsi:type attribute does not resolve to a type definition


Do you guys have any idea how to fix it? I've tried to pass the type_name as Lead, but It didn't work either.

xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/">soap11env:Bodysoap11env:Faultsoap11env:Client.SchemaValidationError:1:0:ERROR:SCHEMASV:SCHEMAV_CVC_ELT_4_2: Element '{http://soap.sforce.com/2005/09/outbound}sObject', attribute '{http://www.w3.org/2001/XMLSchema-instance}type': The QName value '{urn:sobject.enterprise.soap.sforce.com}Lead' of the xsi:type attribute does not resolve to a type definition.</soap11env:Fault></soap11env:Body></soap11env:Envelope>%

My Code:

import logging
from spyne.model.primitive import Unicode, String, Integer64
from spyne.model.complex import ComplexModel
from spyne.service import ServiceBase
from spyne.decorator import rpc

class SObjectType(ComplexModel):
    __namespace__ = 'urn:sobject.enterprise.soap.sforce.com'
    __type_name__ = 'sObject'
    Id = String
    Company_ID__C = Integer64
    Company_Size_Text__c = Unicode

class NotificationType(ComplexModel):
    Id = Unicode
    sObject = SObjectType

class notificationsType(ComplexModel):
    __namespace__ = 'http://soap.sforce.com/2005/09/outbound'
    __type_name__ = 'notifications'
    OrganizationId = Unicode
    ActionId = Unicode
    SessionId = String(nillable="true")
    Notification = NotificationType.customize(max_occurs='100')

class SomeService(ServiceBase):

    @rpc(notificationsType)
    def MyMethod(ctx, notificationsType):
        print(notificationsType)

if __name__ == '__main__':
    from spyne.application import Application
    from spyne.protocol.soap import Soap11
    from spyne.server.wsgi import WsgiApplication
    from wsgiref.simple_server import make_server

    logging.basicConfig(level=logging.DEBUG)
    logging.info('listening to http://127.0.0.1:8080')

    application = Application([SomeService],
                          tns='http://soap.sforce.com/2005/09/outbound',
                          in_protocol=Soap11(validator='lxml'),
                          out_protocol=Soap11())

    wsgi_application = WsgiApplication(application)
    server = make_server('127.0.0.1', 8080, wsgi_application)
    server.serve_forever()

This is the request:

curl --header "Content-Type: text/xml" --data @"/home/sample_request.xml" "http://127.0.0.1:8080/?wsdl"

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
   <OrganizationId>082342234242</OrganizationId>
   <ActionId>3432342DFSFDf343</ActionId>
   <SessionId xsi:nil="true"/>
   <Notification>
    <Id>34FG23234343irKYQAY</Id>
    <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>00Q4100000vNZBlEAO</sf:Id>
     <sf:Company_ID__C>4203320</sf:Company_ID__C>
     <sf:Company_Size_Text__c>501-1,000</sf:Company_Size_Text__c>
    </sObject>
   </Notification>
   <Notification>
    <Id>6565ffd45eewwe322323</Id>
    <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>3453453453453</sf:Id>
     <sf:Company_ID__C>4556456</sf:Company_ID__C>
     <sf:Company_Size_Text__c></sf:Company_Size_Text__c>
    </sObject>
   </Notification>
  </notifications>
 </soapenv:Body>
</soapenv:Envelope>

Solution

  • This answer comes in addition to what I'm already trying to explain to you here: https://github.com/arskom/spyne/discussions/686

    Your service definition is wrong. According to your request document, what you need is the following:

    class SomeService(ServiceBase):
        __tns__ = 'http://soap.sforce.com/2005/09/outbound'
    
        @rpc(sObject)
        def MyMethod(ctx, mymethodparam):
            print(mymethodparam)
    

    As for the error you are getting, it's actually pretty clear:

    QName value '{urn:sobject.enterprise.soap.sforce.com}Lead' of the xsi:type attribute does not resolve to a type definition
    

    You need to have an object named "Lead" in the "urn:sobject.enterprise.soap.sforce.com" namespace.

    The following fragment implies that this is a polymorphic request:

        <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
    

    To parse polymorphic requests, you first need to enable them by passing polymorphic=True to your inbound protocol instantiation.

    Then, you need to define all possible types that your system will accept.

    In this case, you need at least the definition for the Lead object.

    class SObjectType(ComplexModel):
        __namespace__ = 'urn:sobject.enterprise.soap.sforce.com'
        __type_name__ = 'sObject'
        Id = String
        Company_ID__C = Integer64
        Company_Size_Text__c = Unicode
    
    
    class Lead(SObjectType):
        __namespace__ = "urn:sobject.enterprise.soap.sforce.com"
    
        lead_field = Unicode
    
        # (...)
        # any additional fields that the lead object might have
    
    

    As far as I remember, for a type to register as subclass, it must have at least one field of its own in its definition (this could be a bug or a feature, depending who you ask)

    So if the Lead object has no additional fields, you need to have at least one field (called lead_field in this case) in its definition anyway. It's harmless as long as your code doesn't use it. However, if you already have additional fields in the Lead definition, you don't have to have it.