SUDS. Incorrect namespace for factory

44 views Asked by At

I hope I have formulated the question correctly. It's just that English is not my native language.

I am writing a SOAP client in Python using SUDS.

Here is the WSDL:

Service ( ApplicationManagementServiceBindingQSService ) tns="http://api.vetrf.ru/schema/cdm/application/service "
Prefixes (6)
ns0 = "http://api.vetrf.ru/schema/cdm/application"
ns1 = "http://api.vetrf.ru/schema/cdm/application/ws-definitions"
ns2 = "http://api.vetrf.ru/schema/cdm/base"
ns3 = "http://api.vetrf.ru/schema/cdm/dictionary/v2"
ns4 = "http://api.vetrf.ru/schema/cdm/mercury/g2b/applications/v2"
ns5 = "http://api.vetrf.ru/schema/cdm/mercury/vet-document/v2"
Ports (1):
(ApplicationManagementServiceBindingQSPort)
Methods (2):
receiveApplicationResult(ns0:APIKey apiKey, ns2:UUID issuerId, ns2:UUID applicationId)
submitApplicationRequest(ns0:APIKey apiKey, ns0:Application application)
Types (243):
...
ns0:APIKey
ns0:Application
ns0:ApplicationData
ns0:ApplicationDataWrapper
ns0:ApplicationResultData
ns0:ApplicationResultWrapper
ns4:GetVetDocumentListRequest
...

As you can see, there are 2 methods. To send a request and receive the result of the request. Here is submitApplicationRequest XML code:

<soapenv:Envelope
...
   <soapenv:Header/>
   <soapenv:Body>
      <ws:submitApplicationRequest>
         <ws:apiKey>***</ws:apiKey>
         <app:application>
            <app:serviceId>***</app:serviceId>
            <app:issuerId>***</app:issuerId>
            <app:issueDate>2024-02-24T16:58:15</app:issueDate>
            <app:data>
            <!--ANY ELEMENT-->
            </app:data>
         </app:application>
      </ws:submitApplicationRequest>
   </soapenv:Body>
</soapenv:Envelope>

I need to put the getVetDocumentListRequest request in <app: data> which looks like this:

<v2:getVetDocumentListRequest>
    <v2:localTransactionId>?</v2:localTransactionId>
    ...
    <v22:enterpriseGuid>***</v22:enterpriseGuid>
</v2:getVetDocumentListRequest>

and the final request should look like this:

<soapenv:Envelope
...
   <soapenv:Header/>
   <soapenv:Body>
      <ws:submitApplicationRequest>
         <ws:apiKey>***</ws:apiKey>
         <app:application>
            <app:serviceId>***</app:serviceId>
            <app:issuerId>***</app:issuerId>
            <app:issueDate>2024-02-24T16:58:15</app:issueDate>
            <app:data>
               <v2:getVetDocumentListRequest>
            <v2:localTransactionId>?</v2:localTransactionId>
            ...
            <v22:enterpriseGuid>***</v22:enterpriseGuid>
        </v2:getVetDocumentListRequest>
            </app:data>
         </app:application>
      </ws:submitApplicationRequest>
   </soapenv:Body>
</soapenv:Envelope>

In python, I created a factory ns4:GetVetDocumentListRequest:

application_data = client.factory.create('ns4:GetVetDocumentListRequest')
application_data['...'] = ...

Then I created a factory ns0:Application that I have to pass to submitApplicationRequest.

application = client.factory.create('ns0:Application')

and the problem lies in the filling application['data']. If I just assign application_data to it like this application['data'] = application_data

getVetDocumentListRequest tag will be lost in the final xml request and in data tag appear xsi:type:

<ns1:data xsi:type="ns4:GetVetDocumentListRequest">
<!-- The tag should have been here -->
     <ns4:localTransactionId>?</ns4:localTransactionId>
     ...
</ns1:data>

And if I assign it like this

application['data'] = {
    'getVetDocumentListRequest': application_data
}

the tag will appear but the namespace will be incorrect

<ns2:getVetDocumentListRequest>
    <ns3:localTransactionId>?</ns3:localTransactionId>
    ...
    <ns5:enterpriseGuid>***</ns5:enterpriseGuid>
</ns2:getVetDocumentListRequest>

there must be an ns3. If i put the final request in SOAPUI and change ns2 to ns3 the request will be accepted.

Please help me how to get suds to assign it the correct namespace

UPDATE: Python code

from suds.client import Client
from suds.transport.http import HttpAuthenticated

wsdl_url = 'http://api.vetrf.ru/schema/platform/services/2.1-RC-last/ams-mercury-g2b.service_v2.1_pilot.wsdl'
soap_login = '***'
soap_password = '***'
transport = HttpAuthenticated(username = soap_login, password = soap_password)

client = Client(wsdl_url, transport = transport, faults = False)
apiKey = '***'

application_data = client.factory.create('ns4:GetVetDocumentListRequest')
application_data['initiator']['login'] = '***'
application_data['listOptions'] = { 'count': 10, 'offset': 0 }
application_data['vetDocumentType'] = 'INCOMING'
application_data['vetDocumentStatus'] = 'UTILIZED'
application_data['enterpriseGuid'] = '***'

application = client.factory.create('ns0:Application')
application['serviceId'] = '***'
application['issuerId'] = '***'
application['issueDate'] = '2024-02-24T16:58:15'
application['data']['getVetDocumentListRequest'] = application_data

result = client.service.submitApplicationRequest(apiKey, application)

print client.last_sent()

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://api.vetrf.ru/schema/cdm/mercury/vet-document/v2" xmlns:ns2="http://api.vetrf.ru/schema/cdm/mercury/g2b/applications/v2" xmlns:ns3="http://api.vetrf.ru/schema/cdm/base" xmlns:ns4="http://api.vetrf.ru/schema/cdm/application/ws-definitions" xmlns:ns5="http://api.vetrf.ru/schema/cdm/application">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns4:submitApplicationRequest>
         <apiKey xmlns="http://api.vetrf.ru/schema/cdm/application/ws-definitions">***</apiKey>
         <application xmlns="http://api.vetrf.ru/schema/cdm/application/ws-definitions">
            <ns5:serviceId>***</ns5:serviceId>
            <ns5:issuerId>***</ns5:issuerId>
            <ns5:issueDate>2024-02-24T16:58:15</ns5:issueDate>
            <ns5:data>
               <ns5:getVetDocumentListRequest>
                  <ns2:localTransactionId/>
                  <ns2:initiator>
                     <ns1:login>***</ns1:login>
                  </ns2:initiator>
                  <ns2:listOptions>
                     <ns3:count>10</ns3:count>
                     <ns3:offset>0</ns3:offset>
                  </ns2:listOptions>
                  <ns2:vetDocumentType>INCOMING</ns2:vetDocumentType>
                  <ns2:vetDocumentStatus>UTILIZED</ns2:vetDocumentStatus>
                  <ns2:enterpriseGuid>***</ns2:enterpriseGuid>
               </ns5:getVetDocumentListRequest>
            </ns5:data>
         </application>
      </ns4:submitApplicationRequest>
   </ns0:Body>
</SOAP-ENV:Envelope>

Response:

<apl:errors xmlns:apl="http://api.vetrf.ru/schema/cdm/application">
<apl:error code="APLM0002">Unsupported application data format</apl:error>
</apl:errors>

Problem in the xml that suds sends in this case instead <ns5:getVetDocumentListRequest> should be <ns2:getVetDocumentListRequest>

if I take this xml and send it via SOAPUI, changing ns5 to ns2, then everything works.

0

There are 0 answers