1

I am using Spyne with Django CMS. A web service is calling my system and I want to reply with the below. Can I use Spyne for customize response? Or do I have to go through models?

Please advise.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Header/>
 <soapenv:Body>
<tns:initTestQueryResponse xmlns:tns="http://test.com/interface/test/v2"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test.com/interface/test/v2 testQuery.xsd"
    xmlns:v21="http://test.com/model/generic-query/v2"
    xmlns:v22="http://test.com/model/common/v2">
    <tns:field key="ID" type="ID">
        <v21:description lang="en">Identifier</v21:description>
    </tns:field>
    <tns:field key="CUSTOMER_NAME" type="TEXT">
        <v21:description lang="en">Customer Name</v21:description>
        <v21:layoutOptions bold="true" italic="false" direction="HORIZONTAL"/>
    </tns:field>
    <tns:section key="CUSTOMER">
        <v21:description lang="en">Customer</v21:description>
    </tns:section>
    <tns:advancedQuery>
        <tns:criteriaGroup key="CUSTOMER" operator="OR">
            <v21:criterion key="ID" />
            <v21:criterion key="CUSTOMER_NAME" />
        </tns:criteriaGroup>
    </tns:advancedQuery>
    <tns:advanceQueryPerson>
        <tns:criteriaGroup key="CUSTOMER" operator="OR">
            <v21:criterion key="ID" />
            <v21:criterion key="CUSTOMER_NAME" />
        </tns:criteriaGroup>
    </tns:advanceQueryPerson>
    <tns:context>
        <v22:status>OK</v22:status>
    </tns:context>
</tns:initTestQueryResponse>
</soapenv:Body>
</soapenv:Envelope>

This the request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <p:initTestQueryRequest xmlns:p="http://test.com/interface/test/v2"
                             xmlns:p1="http://test.com/model/common/v2"
                             xmlns:p2="http://test.com/model/generic-query/v2"
                             xmlns:p3="http://test.com/model/test/v2"
                             xmlns:p4="http://test.com/model/service-fault/v2"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://test.com/interface/test/v2 ../service/test/v2/TestQuery.xsd "
                             xsi:type="anyType"/>
   </soapenv:Body>
</soapenv:Envelope>

1 Answers1

2

You have two options:

  1. Use a bare method named initTestQuery whose return type should be a class named "initTestQueryResponse" whose namespace is "http://test.com/interface/test/v2". You need to return an initTestQueryResponse instance from the initTestQuery function.

  2. Use a bare method named "initTestQuery" whose return type is AnyXml. You need to return an lxml.etree.Element() that contains the tags you need. Please consult the lxml documentation about how to do that.

If you want to "edit" requests after they are deserialized but before they are validated, you must subclass the protocol and override create_in_document.

class MyProtocol(Soap11):
    def create_in_document(self, ctx, charset=None):
        super(MyProt, self).create_in_document(ctx, charset=charset)
        # Do whatever you want with ctx.in_document


app = Application(in_protocol=MyProtocol(...), ...)

I hope this helps.

Burak Arslan
  • 7,671
  • 2
  • 15
  • 24
  • I have used the bare method and managed to reproduce the above result. But I get the following error: soap11env:Client.SchemaValidationError :11:0:ERROR:SCHEMASV:SCHEMAV_CVC_ELT_4_2: Element '{http://test.com/interface/test/v2}initTestQueryRequest', attribute '{http://www.w3.org/2001/XMLSchema-instance}type': The QName value 'anyType' of the xsi:type attribute does not resolve to a type definition. –  Jan 31 '19 at 10:12
  • I have updated the question with the request call. If I remove the xsi:type="anyType" (which is not an option) I dont get the above error and works ok... Any ideas? –  Jan 31 '19 at 10:19
  • Pass `parse_xsi_type=False` to the protocol init. See: https://github.com/arskom/spyne/blob/d64f971a128516705f545f256e4e22c9a701260c/spyne/protocol/xml.py#L204 – Burak Arslan Mar 01 '19 at 09:25