[spyne] Complex data types and inheritance

Alex Railean ralienpp at gmail.com
Tue Jun 10 20:39:52 UTC 2014


Multiple inheritance seems to be the cause.

There are the data structures that replicate the behaviour:
class BaseOne(ComplexModel):
      requestId = Uuid

class BaseTwo(ComplexModel):
      unitType = Unicode
      unitValue = Unicode

class InheritedResponse(BaseOne):
      something = String
      poetic = String

class DualInheritedResponse(BaseOne, BaseTwo):
      anotherField = Unicode


Here is the code for a server that replicates the issue:
http://pastebin.com/1WHX6QtR

And a payload
```
POST / HTTP/1.1
Host: localhost
Content-Length: 30

{"DemoFunction":{"number": 5}}
```


The  response  is `{"anotherField": "Test"}`, neither of the inherited
attributes were included.



If I cascade them, then it works, here is what I mean:
class BaseTwo(ComplexModel):
        unitType = Unicode
        unitValue = Unicode

class CascadedA(BaseTwo):
        firstChild = Unicode
 
class CascadedB(CascadedA):
        lastChild = Unicode


i.e. the response of a function that returns CascadeB will include all
of these: unitType, unitValue, firstChild, lastChild.




These are my findings,
Alex






In  case pastebin ever goes down, I'm including the code here too, for
future archaeologists.

import logging
from uuid import uuid4
from spyne.application import Application
from spyne.decorator import rpc
from spyne.protocol.json import JsonDocument
from spyne.protocol.http import HttpRpc
from spyne.service import ServiceBase
from spyne.model.primitive import String, Integer, Uuid, Unicode
from spyne.model.complex import ComplexModel
from spyne.server.wsgi import WsgiApplication



class BaseOne(ComplexModel):
        requestId = Uuid

class BaseTwo(ComplexModel):
        unitType = Unicode
        unitValue = Unicode

class InheritedResponse(BaseOne):
        something = String
        poetic = String

class DualInheritedResponse(BaseOne, BaseTwo):
        anotherField = Unicode

########################
class CascadedA(BaseTwo):
        firstChild = Unicode

class CascadedB(CascadedA):
        lastChild = Unicode


class DemoService(ServiceBase):
        @rpc(Integer, _returns=DualInheritedResponse)
        def DemoFunction(ctx, number):
                response = DualInheritedResponse()
                response.requestId = uuid4()
                response.something = 'The Glasgow opening'
                response.poetic = 'revolutionized checkers'
                response.anotherField = 'Test'
                return response

        @rpc(Integer, _returns=lastChild)
        def DemoFunctionEx(ctx, number):

                response = CascadedB()
                response.unitType = 'type'
                response.unitValue = 'value'
                response.firstChild = 'The Glasgow opening'
                response.lastChild = 'revolutionized checkers'
                return response





if __name__ == '__main__':
        from wsgiref.simple_server import make_server
        logging.basicConfig(level=logging.DEBUG)

        application = Application([DemoService], 'SpyneDemo.http',
                                in_protocol=JsonDocument(validator='soft'),
                                out_protocol=JsonDocument(ignore_wrappers=True),
                )

        wsgi_application = WsgiApplication(application)

        server = make_server('', 8000, wsgi_application) #any interface

        logging.info("listening at all interfaces on port 8000")
        logging.info("wsdl is at: http://ANY:8000/?wsdl")

        server.serve_forever()



More information about the people mailing list