Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #173 from plq/master

MessagePack integration.
  • Loading branch information...
commit 1fbafe96f60519bce6d5ddb5496dc8b6f5b0736f 2 parents 61a1945 + 66c8300
@ugurcan377 ugurcan377 authored
View
2  CHANGELOG.rst
@@ -5,6 +5,8 @@ rpclib-2.8.0-rc -> spyne-2.8.0-rc
---------------------------------
* Rpclib is dead. Long live Spyne!
* Add support for JsonObject protocol. This initial version is expremental.
+ * Add support for MessagePackObject and MessagePackRpc protocols. These
+ initial versions are expremental.
* Make DateTime string format customizable.
* Implement TwistedWebResource that exposes an ``Application`` instance as a
``twisted.web.resource.Resource`` child.
View
4 doc/source/comparison.rst
@@ -29,11 +29,11 @@ Discussion thread: https://answers.launchpad.net/ladon/+question/171664
to do with the ugliness of a raw wsdl document.
* Does not support ZeroMQ.
* Uses standard python tools for xml parsing which is good for pure-python
- deployments. Spyne uses lxml, due to its excellent namespace support and
+ deployments. Spyne uses lxml, due to its excellent xml namespace support and
speed. So Spyne-based solutions are easier to develop and faster to work with
but more difficult to deploy.
* Does not do declarative input validation. Traditional (imperative) input
- validation is possible via a code injection mechanism similar to spyne's
+ validation is possible via a code injection mechanism similar to Spyne's
events.
* Does not support HttpRpc.
* Does not have a Soap client.
View
79 doc/source/manual/helloworld.rst
@@ -32,7 +32,7 @@ The simpler version of this example is available here: http://github.com/arskom/
@srpc(String, Integer, _returns=Iterable(String))
def say_hello(name, times):
'''
- Docstrings for service methods appear as documentation in the wsdl
+ Docstrings for service methods appear as documentation in the wsdl.
<b>what fun</b>
@param name the name to say hello to
@param the number of times to say hello
@@ -73,24 +73,12 @@ function gets a spyne.MethodContext instance as first argument. ::
from spyne.decorator import srpc
-We are going to expose the service definitions using the Wsdl 1.1 document
-standard. The methods will use Soap 1.1 protocol to communicate with the outside
+The methods will use Soap 1.1 protocol to communicate with the outside
world. They're instantiated and passed to the Application constructor. You need
to pass fresh instances to each application instance. ::
from spyne.protocol.soap import Soap11
-For the sake of this tutorial, we are going to use HttpRpc as well. It's a
-rest-like protocol, but it doesn't care about HTTP verbs (yet). ::
-
- from spyne.protocol.http import HttpRpc
-
-The HttpRpc serializer does not support complex types. So we will use the
-XmlObject serializer as the out_protocol to prevent the clients from dealing
-with Soap cruft. ::
-
- from spyne.protocol.http import XmlObject
-
ServiceBase is the base class for all service definitions. ::
from spyne.service import ServiceBase
@@ -130,8 +118,8 @@ and return types are standard python objects::
When returning an iterable, you can use any type of python iterable. Here, we
chose to use generators.
-Deploying the service using SOAP
---------------------------------
+Deploying the service using Soap via Wsgi
+-----------------------------------------
Now that we have defined our service, we are ready to share it with the outside
world.
@@ -180,13 +168,12 @@ the http server: ::
server.serve_forever()
-
.. NOTE::
- * **Django users:** See this gist for a django wrapper example: https://gist.github.com/1242760
- * **Twisted users:** See the this example that illustrates deploying an
- Spyne application using twisted: http://github.com/arskom/spyne/blob/master/examples/helloworld_soap_twisted.py
+ * **Django users:** See django wrapper example: https://github.com/arskom/spyne/blob/master/examples/django
+ * **Twisted users:** See the these examples that illustrate two ways of
+ deploying a Spyne application using Twisted: http://github.com/arskom/spyne/blob/master/examples/twisted
-You can test your service using suds. Suds is a separate project for building
+You can test your service using suds. Suds is a separate project for implementing
pure-python soap clients. To learn more visit the project's page:
https://fedorahosted.org/suds/. You can simply install it using
``easy_install suds``.
@@ -197,43 +184,51 @@ So here's how you can use suds to test your new spyne service:
from suds.client import Client
hello_client = Client('http://localhost:7789/?wsdl')
- result = hello_client.service.say_hello("Dave", 5)
- print result
+ print hello_client.service.say_hello("Punk", 5)
The script's output would be as follows: ::
(stringArray){
string[] =
- "Hello, Dave",
- "Hello, Dave",
- "Hello, Dave",
- "Hello, Dave",
- "Hello, Dave",
+ "Hello, Punk",
+ "Hello, Punk",
+ "Hello, Punk",
+ "Hello, Punk",
+ "Hello, Punk",
}
-Deploying service using HttpRpc
--------------------------------
+Deploying service using HttpRpc via Wsgi
+----------------------------------------
This example is available here: http://github.com/arskom/spyne/blob/master/examples/helloworld_http.py.
-The only difference between the SOAP and the HTTP version is the application
-instantiation line: ::
+
+For the sake of this tutorial, we are going to use HttpRpc as well. HttpRpc is
+a rest-like protocol, but it doesn't care about HTTP verbs (yet). ::
+
+ from spyne.protocol.http import HttpRpc
+
+The HttpRpc serializer does not support complex types. So we will use the
+XmlObject serializer as the out_protocol to prevent the clients from dealing
+with Soap cruft. ::
+
+ from spyne.protocol.http import XmlObject
+
+Besides the imports, the only difference between the SOAP and the HTTP version
+is the application instantiation line: ::
application = Application([HelloWorldService], 'spyne.examples.hello.http',
in_protocol=HttpRpc(), out_protocol=XmlObject())
-We still want to keep Xml as the output protocol as the HttpRpc protocol is
-not able to handle complex types.
-
Here's how you can test your service using curl: ::
- curl "http://localhost:7789/say_hello?times=5&name=Dave"
+ curl "http://localhost:7789/say_hello?times=5&name=Punk"
If you have HtmlTidy installed, you can use this command to get a more readable
output. ::
- curl "http://localhost:7789/say_hello?times=5&name=Dave" | tidy -xml -indent
+ curl "http://localhost:7789/say_hello?times=5&name=Punk" | tidy -xml -indent
The command's output would be as follows: ::
@@ -241,11 +236,11 @@ The command's output would be as follows: ::
<ns1:say_helloResponse xmlns:ns1="spyne.examples.hello.http"
xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
<ns1:say_helloResult>
- <ns1:string>Hello, Dave</ns1:string>
- <ns1:string>Hello, Dave</ns1:string>
- <ns1:string>Hello, Dave</ns1:string>
- <ns1:string>Hello, Dave</ns1:string>
- <ns1:string>Hello, Dave</ns1:string>
+ <ns1:string>Hello, Punk</ns1:string>
+ <ns1:string>Hello, Punk</ns1:string>
+ <ns1:string>Hello, Punk</ns1:string>
+ <ns1:string>Hello, Punk</ns1:string>
+ <ns1:string>Hello, Punk</ns1:string>
</ns1:say_helloResult>
</ns1:say_helloResponse>
View
67 doc/source/manual/usermanager.rst
@@ -25,7 +25,7 @@ here: http://github.com/arskom/spyne/blob/master/examples/user_manager/server_ba
from spyne.decorator import rpc
from spyne.interface.wsdl import Wsdl11
from spyne.protocol.soap import Soap11
- from spyne.model.primitive import String
+ from spyne.model.primitive import Unicode
from spyne.model.primitive import Integer
from spyne.model.complex import Array
from spyne.model.complex import Iterable
@@ -39,16 +39,16 @@ here: http://github.com/arskom/spyne/blob/master/examples/user_manager/server_ba
class Permission(ComplexModel):
__namespace__ = 'spyne.examples.user_manager'
- application = String
- operation = String
+ application = Unicode
+ operation = Unicode
class User(ComplexModel):
__namespace__ = 'spyne.examples.user_manager'
user_id = Integer
- user_name = String
- first_name = String
- last_name = String
+ user_name = Unicode
+ first_name = Unicode
+ last_name = Unicode
permissions = Array(Permission)
class UserManagerService(ServiceBase):
@@ -108,37 +108,38 @@ here: http://github.com/arskom/spyne/blob/master/examples/user_manager/server_ba
server.serve_forever()
-Juping into what's new: Spyne uses ``ComplexModel`` as a general type that when extended will produce complex
-serializable types that can be used in a public service. The ``Permission`` class is a
-fairly simple class with just two members: ::
+Jumping into what's new: Spyne uses ``ComplexModel`` as a general type that,
+when subclassed, will produce complex serializable types that can be used in a
+public service. The ``Permission`` class is a fairly simple class with just
+two members: ::
class Permission(ComplexModel):
- application = String
- feature = String
+ application = Unicode
+ feature = Unicode
Let's also look at the ``User`` class: ::
class User(ComplexModel):
user_id = Integer
- username = String
- firstname = String
- lastname = String
+ username = Unicode
+ firstname = Unicode
+ lastname = Unicode
Nothing new so far.
Below, you can see that the ``email`` member which has a regular expression
-restriction defined. The String type accepts other restrictions, please refer to
-the :class:`spyne.model.primitive.String` documentation for more information: ::
+restriction defined. The ``Unicode`` type accepts other restrictions, please refer to
+the :class:`spyne.model.primitive.Unicode` documentation for more information: ::
- email = String(pattern=r'\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[A-Z]{2,4}\b')
+ email = Unicode(pattern=r'\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[A-Z]{2,4}\b')
The ``permissions`` attribute is an array, whose native type is a ``list`` of ``Permission``
objects. ::
permissions = Array(Permission)
-The following is deserialized as a generator, but looks the same from the protocol and
-interface points of view: ::
+The following is deserialized as a generator, but looks the same from the
+points of view of protocol and interface documents: ::
permissions = Iterable(Permission)
@@ -148,16 +149,21 @@ representations. ::
permissions = Permission.customize(max_occurs='unbounded')
+With the ``Array`` and ``Iterable`` types, a container class wraps multiple
+occurences of the inner data type.
+
Here, we need to use the :func:`spyne.model._base.ModelBase.customize` call
-because calling a ``ComplexModel`` child instantiates that class, whereas
-calling a ``SimpleModel`` child returns a duplicate of that class. The
-``customize`` function just sets given arguments as class attributes to
+because calling a ``ComplexModel`` subclass instantiates that class, whereas
+calling a ``SimpleModel`` child implicitly calls the ``.customize`` method of
+that class.
+
+The ``customize`` function just sets given arguments as class attributes to
``cls.Attributes`` class. You can refer to the documentation of each class to
see which member of the ``Attributes`` class is used for the given object.
Here, we define a function to be called for every method call. It instantiates
the ``UserDefinedContext`` class and sets it to the context object's ``udc``
-attribute, which is in fact short for 'user defined context'. ::
+attribute, which is in fact short for 'User Defined Context'. ::
def _on_method_call(ctx):
ctx.udc = UserDefinedContext()
@@ -167,11 +173,19 @@ We register it to the application's 'method_call' handler. ::
application.event_manager.add_listener('method_call', _on_method_call)
Note that registering it to the service definition's event manager would have
-the same effect: ::
+the same effect, but it'd have to be set for every service definition: ::
UserManagerService.event_manager.add_listener('method_call', _on_method_call)
-Here, we define the UserDefinedContext object. It's just a regular python class
+You can also prefer to define your own ``ServiceBase`` class and use it as a
+base class throughout your projects: ::
+
+ class MyServiceBase(ServiceBase):
+ pass
+
+ MyServiceBase.event_manager.add_listener('method_call', _on_method_call)
+
+Next, we define the UserDefinedContext object. It's just a regular python class
with no specific api it should adhere to, other than your own. ::
class UserDefinedContext(object):
@@ -195,7 +209,7 @@ events to measure method performance)
What's next?
------------
-This tutorial walks you through what you need to know to expose basic
+This tutorial walks you through what you need to know to expose more complex
services. You can read the :ref:`manual-sqlalchemy` document where the
:class:`spyne.model.table.TableModel` class and its helpers are introduced.
You can also have look at the :ref:`manual-metadata` section where service
@@ -203,4 +217,3 @@ metadata management apis are introduced.
Otherwise, please refer to the rest of the documentation or the mailing list
if you have further questions.
-
View
51 examples/twisted/_service.py
@@ -31,75 +31,38 @@
import logging
import time
-import sys
from twisted.python import log
-from twisted.web.server import Site
-from twisted.web.static import File
-from twisted.internet import reactor
-from twisted.python import log
from spyne.application import Application
from spyne.decorator import srpc
from spyne.protocol.http import HttpRpc
-from spyne.protocol.json import JsonObject
from spyne.protocol.xml import XmlObject
from spyne.service import ServiceBase
-from spyne.model.complex import Array
from spyne.model.primitive import Integer
-from spyne.model.primitive import String
-from spyne.server.wsgi import WsgiApplication
-from spyne.server.twisted import TwistedWebResource
-from spyne.util.wsgi_wrapper import run_twisted
-
-'''
-This is the HelloWorld example running in a single-process twisted setup.
-'''
host = '127.0.0.1'
port = 9752
class SomeService(ServiceBase):
- @srpc(String, Integer, _returns=Array(String))
- def say_hello(name, times):
- '''Docstrings for service methods appear as documentation in the wsdl.
-
- @param name the name to say hello to
- @param the number of times to say hello
- @return the completed array
- '''
- results = []
- for i in range(0, times):
- results.append('Hello, %s' % name)
-
- return results
-
@srpc(Integer)
def block(seconds):
"""Blocks the reactor for given number of seconds."""
time.sleep(seconds)
-
-if __name__=='__main__':
+def initialize():
logging.basicConfig(level=logging.DEBUG)
logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
- application = Application([SomeService], 'spyne.examples.hello.twisted',
- in_protocol=HttpRpc(), out_protocol=XmlObject())
-
- application.interface.nsmap[None] = application.interface.nsmap['tns']
- application.interface.prefmap[application.interface.nsmap['tns']] = None
- del application.interface.nsmap['tns']
-
observer = log.PythonLoggingObserver('twisted')
log.startLoggingWithObserver(observer.emit, setStdout=False)
- wr = TwistedWebResource(application)
- site = Site(wr)
- reactor.listenTCP(port, site)
+ application = Application([SomeService], 'spyne.examples.hello.twisted',
+ in_protocol=HttpRpc(), out_protocol=XmlObject())
- logging.info("listening on: %s:%d" % (host,port))
- logging.info('wsdl is at: http://0.0.0.0:7789/?wsdl')
+ application.interface.nsmap[None] = application.interface.nsmap['tns']
+ application.interface.prefmap[application.interface.nsmap['tns']] = None
+ del application.interface.nsmap['tns']
- sys.exit(reactor.run())
+ return application
View
50 examples/twisted/resource.py
@@ -30,29 +30,16 @@
#
import logging
-import time
import sys
-from twisted.python import log
-from twisted.web.server import Site
-from twisted.web.static import File
from twisted.internet import reactor
-from twisted.python import log
-
-from spyne.application import Application
-from spyne.decorator import srpc
-from spyne.protocol.http import HttpRpc
-from spyne.protocol.json import JsonObject
-from spyne.protocol.xml import XmlObject
-from spyne.service import ServiceBase
-from spyne.model.complex import Array
-from spyne.model.primitive import Integer
-from spyne.model.primitive import String
-from spyne.server.wsgi import WsgiApplication
+from twisted.web.server import Site
+
+
from spyne.server.twisted import TwistedWebResource
-from spyne.util.wsgi_wrapper import run_twisted
-from _service import SomeService
+
+from _service import initialize
'''
This is a blocking example running in a single-process twisted setup.
@@ -61,7 +48,8 @@
code fully adheres to the asynchronous programming principles, you can block
the reactor loop.
- $ time curl -s "http://localhost:9752/block?seconds=10" > /dev/null & time curl -s "http://localhost:9752/block?seconds=10" > /dev/null&
+ $ time curl -s "http://localhost:9757/block?seconds=10" > /dev/null & \
+ time curl -s "http://localhost:9757/block?seconds=10" > /dev/null &
[1] 27559
[2] 27560
@@ -72,32 +60,20 @@
real 0m20.045s
user 0m0.009s
sys 0m0.005s
-
'''
-host = '127.0.0.1'
-port = 9752
+host = '0.0.0.O'
+port = 9758
if __name__=='__main__':
- logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
-
- application = Application([SomeService], 'spyne.examples.hello.twisted',
- in_protocol=HttpRpc(), out_protocol=XmlObject())
-
- application.interface.nsmap[None] = application.interface.nsmap['tns']
- application.interface.prefmap[application.interface.nsmap['tns']] = None
- del application.interface.nsmap['tns']
-
- observer = log.PythonLoggingObserver('twisted')
- log.startLoggingWithObserver(observer.emit, setStdout=False)
+ application = initialize()
+ resource = TwistedWebResource(application)
+ site = Site(resource)
- wr = TwistedWebResource(application)
- site = Site(wr)
reactor.listenTCP(port, site)
logging.info("listening on: %s:%d" % (host,port))
- logging.info('wsdl is at: http://0.0.0.0:7789/?wsdl')
+ logging.info('wsdl is at: http://%s:%d/?wsdl' % (host, port))
sys.exit(reactor.run())
View
53 examples/twisted/wsgi.py
@@ -30,28 +30,26 @@
#
import logging
+import sys
+
+from twisted.internet import reactor
+from twisted.web.server import Site
+from twisted.web.wsgi import WSGIResource
-from spyne.application import Application
-from spyne.decorator import srpc
-from spyne.protocol.http import HttpRpc
-from spyne.protocol.xml import XmlObject
-from spyne.service import ServiceBase
-from spyne.model.complex import Array
-from spyne.model.primitive import Integer
-from spyne.model.primitive import String
from spyne.server.wsgi import WsgiApplication
-from spyne.util.wsgi_wrapper import run_twisted
-from _service import SomeService
+
+from _service import initialize
'''
-This is the HelloWorld example running via twisted's wsgi wrapping machinery.
+This is a blocking example running in a multi-thread twisted setup.
-This is merely a way of weakly integrating with the twisted framework. Every
-request still runs in its own thread. This way, you can still use other features
-of twisted and not have to rewrite your otherwise synchronous code.
+This is a way of weakly integrating with the twisted framework -- every request
+still runs in its own thread. This way, you can still use other features of
+twisted and not have to rewrite your otherwise synchronous code.
- $ time curl -s "http://localhost:9752/app/block?seconds=10" > /dev/null & time curl -s "http://localhost:9752/app/block?seconds=10" > /dev/null&
+ $ time curl -s "http://localhost:9757/block?seconds=10" > /dev/null & \
+ time curl -s "http://localhost:9757/block?seconds=10" > /dev/null &
[1] 27537
[2] 27538
@@ -64,23 +62,18 @@
sys 0m0.006s
'''
-host = "0.0.0.0"
-port = 9752
+host = '0.0.0.0'
+port = 9757
if __name__=='__main__':
- logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
-
- application = Application([SomeService], 'spyne.examples.hello.twisted',
- in_protocol=HttpRpc(), out_protocol=XmlObject())
-
- application.interface.nsmap[None] = application.interface.nsmap['tns']
- application.interface.prefmap[application.interface.nsmap['tns']] = None
- del application.interface.nsmap['tns']
+ application = initialize()
+ wsgi_application = WsgiApplication(application)
+ resource = WSGIResource(reactor, reactor, wsgi_application)
+ site = Site(resource)
- wsgi_app = WsgiApplication(application)
+ reactor.listenTCP(port, site)
- logging.info('listening on %s:%d' % (host,port))
- logging.info('wsdl is at: http://%s:%d/app/?wsdl' % (host, port))
+ logging.info('listening on: %s:%d' % (host,port))
+ logging.info('wsdl is at: http://%s:%d/?wsdl' % (host, port))
- run_twisted(((wsgi_app, "app"),), port)
+ sys.exit(reactor.run())
View
2  spyne/model/complex.py
@@ -419,6 +419,7 @@ def customize(cls, **kwargs):
return retval
+
class ComplexModel(ComplexModelBase):
"""The general complexType factory. The __call__ method of this class will
return instances, contrary to primivites where the same call will result in
@@ -494,5 +495,6 @@ class Iterable(Array):
implementation, this is just a marker.
"""
+
class Alias(ComplexModel):
"""Different type_name, same _type_info."""
View
8 spyne/model/fault.py
@@ -42,3 +42,11 @@ def __repr__(self):
@classmethod
def to_string_iterable(cls, value):
return [value.faultcode, '\n\n', value.faultstring]
+
+ @classmethod
+ def to_dict(cls, value):
+ return {cls.get_type_name(): {
+ "faultcode": value.faultcode,
+ "faultstring": value.faultstring,
+ "detail": value.detail,
+ }}
View
18 spyne/model/primitive.py
@@ -69,9 +69,11 @@
r'(?:(?P<seconds>\d+(.\d+)?)S)?)?'
)
+
_ns_xs = spyne.const.xml_ns.xsd
_ns_xsi = spyne.const.xml_ns.xsi
+
class AnyXml(SimpleModel):
"""An xml node that can contain any number of sub nodes. It's represented by
an ElementTree object."""
@@ -98,6 +100,7 @@ def from_string(cls, string):
except etree.XMLSyntaxError:
raise ValidationError(string)
+
class AnyDict(SimpleModel):
"""An xml node that can contain any number of sub nodes. It's represented by
a dict instance that can contain other dicts or iterables of strings as
@@ -119,6 +122,7 @@ def from_string(cls, string):
except:
raise ValidationError(string)
+
class Unicode(SimpleModel):
"""The type to represent human-readable data. Its native format is `unicode`.
or `str` with given encoding.
@@ -214,7 +218,6 @@ def from_string(cls, value):
String = Unicode
-# FIXME: Support this for soft validation
class AnyUri(String):
"""A special kind of String type designed to hold an uri."""
@@ -271,12 +274,12 @@ def is_default(cls):
@staticmethod
def validate_native(cls, value):
- return ( SimpleModel.validate_native(cls, value) and
- value is None or (
- value > cls.Attributes.gt and
- value >= cls.Attributes.ge and
- value < cls.Attributes.lt and
- value <= cls.Attributes.le
+ return SimpleModel.validate_native(cls, value) and (
+ value is None or (
+ value > cls.Attributes.gt and
+ value >= cls.Attributes.ge and
+ value < cls.Attributes.lt and
+ value <= cls.Attributes.le
))
@classmethod
@@ -672,6 +675,7 @@ class Mandatory(object):
String = String(type_name="mandatory_string", min_occurs=1, nillable=False, min_len=1)
Unicode = Unicode(type_name="mandatory_string", min_occurs=1, nillable=False, min_len=1)
+ Decimal = Decimal(type_name="mandatory_integer", min_occurs=1, nillable=False)
Integer = Integer(type_name="mandatory_integer", min_occurs=1, nillable=False)
Date = Date(type_name="mandatory_date", min_occurs=1, nillable=False)
DateTime = DateTime(type_name="mandatory_date_time", min_occurs=1, nillable=False)
View
3  spyne/protocol/__init__.py
@@ -18,3 +18,6 @@
#
from spyne.protocol._base import ProtocolBase
+from spyne.protocol._base import unwrap_instance
+from spyne.protocol._base import unwrap_messages
+from spyne.protocol._dictobj import DictObject
View
12 spyne/protocol/_base.py
@@ -26,7 +26,7 @@
from copy import copy
-from spyne._base import EventManager
+from spyne import EventManager
from spyne.const.http import HTTP_400
from spyne.const.http import HTTP_404
@@ -47,9 +47,11 @@
def unwrap_messages(cls, skip_depth):
out_type = cls
- for i in range(skip_depth):
- if len(out_type._type_info) == 1:
+ for _ in range(skip_depth):
+ if hasattr(out_type, "_type_info") and len(out_type._type_info) == 1:
out_type = out_type._type_info[0]
+ else:
+ break
return out_type
@@ -58,8 +60,8 @@ def unwrap_instance(cls, inst, skip_depth):
out_type = cls
out_instance = inst
- for i in range(skip_depth):
- if len(out_type._type_info) == 1:
+ for _ in range(skip_depth):
+ if hasattr(out_type, "_type_info") and len(out_type._type_info) == 1:
(k, out_type), = out_type._type_info.items()
if issubclass(out_type, ComplexModelBase):
out_instance = getattr(out_instance, k)
View
301 spyne/protocol/_dictobj.py
@@ -0,0 +1,301 @@
+
+#
+# spyne - Copyright (C) Spyne contributors.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+#
+
+"""Abstract protocol that deals with dicts as {in,out}_documents."""
+
+import logging
+logger = logging.getLogger(__name__)
+
+from spyne.error import ValidationError
+
+from spyne.model.fault import Fault
+from spyne.model.complex import ComplexModelBase
+from spyne.model.complex import Array
+from spyne.model.primitive import DateTime
+from spyne.model.primitive import Decimal
+from spyne.model.primitive import String
+from spyne.model.primitive import Unicode
+
+from spyne.protocol import ProtocolBase
+from spyne.protocol._base import unwrap_messages
+from spyne.protocol._base import unwrap_instance
+
+
+class DictObject(ProtocolBase):
+ """An abstract protocol that uses dicts as input and output documents.
+
+ Implement ``create_in_document`` and ``create_out_string`` to use this.
+ """
+
+ def create_in_document(self, ctx, in_string_encoding=None):
+ raise NotImplementedError()
+
+ def create_out_string(self, ctx, out_string_encoding='utf8'):
+ raise NotImplementedError()
+
+ def set_validator(self, validator):
+ """Sets the validator for the protocol.
+
+ :param validator: one of ('soft', None)
+ """
+
+ if validator == 'soft' or validator is self.SOFT_VALIDATION:
+ self.validator = self.SOFT_VALIDATION
+ elif validator is None:
+ self.validator = None
+ else:
+ raise ValueError(validator)
+
+ def decompose_incoming_envelope(self, ctx, message):
+ """Sets ``ctx.in_body_doc``, ``ctx.in_header_doc`` and
+ ``ctx.method_request_string`` using ``ctx.in_document``.
+ """
+
+ assert message in (ProtocolBase.REQUEST, ProtocolBase.RESPONSE)
+
+ # set ctx.in_header
+ ctx.transport.in_header_doc = None # use an rpc protocol if you want headers.
+
+ doc = ctx.in_document
+
+ ctx.in_header_doc = None
+ ctx.in_body_doc = doc
+
+ if len(doc) == 0:
+ raise Fault("Client", "Empty request")
+
+ # set ctx.method_request_string
+ ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(),
+ doc.keys()[0])
+
+ logger.debug('\theader : %r' % (ctx.in_header_doc))
+ logger.debug('\tbody : %r' % (ctx.in_body_doc))
+
+ def _doc_to_object(self, cls, doc):
+ if doc is None:
+ return []
+
+ if issubclass(cls, Array):
+ retval = [ ]
+ (serializer,) = cls._type_info.values()
+
+ for child in doc:
+ retval.append(self._from_dict_value(serializer, child))
+
+ return retval
+
+ inst = cls.get_deserialization_instance()
+
+ # get all class attributes, including the ones coming from parent classes.
+ flat_type_info = cls.get_flat_type_info(cls)
+
+ # initialize instance
+ for k in flat_type_info:
+ setattr(inst, k, None)
+
+ # this is for validating cls.Attributes.{min,max}_occurs
+ frequencies = {}
+
+ try:
+ items = doc.items()
+ except AttributeError:
+ items = zip(cls._type_info.keys(), doc)
+
+ # parse input to set incoming data to related attributes.
+ for k,v in items:
+ freq = frequencies.get(k, 0)
+ freq += 1
+ frequencies[k] = freq
+
+ member = flat_type_info.get(k, None)
+ if member is None:
+ continue
+
+ mo = member.Attributes.max_occurs
+ if mo > 1:
+ value = getattr(inst, k, None)
+ if value is None:
+ value = []
+
+ for a in v:
+ value.append(self._from_dict_value(member, a))
+
+ else:
+ value = self._from_dict_value(member, v)
+
+ setattr(inst, k, value)
+
+ if self.validator is self.SOFT_VALIDATION:
+ for k, v in flat_type_info.items():
+ val = frequencies.get(k, 0)
+ if (val < v.Attributes.min_occurs or val > v.Attributes.max_occurs):
+ raise Fault('Client.ValidationError',
+ '%r member does not respect frequency constraints.' % k)
+
+ return inst
+
+ def deserialize(self, ctx, message):
+ assert message in (self.REQUEST, self.RESPONSE)
+
+ self.event_manager.fire_event('before_deserialize', ctx)
+
+ if ctx.descriptor is None:
+ raise Fault("Client", "Method %r not found." %
+ ctx.method_request_string)
+
+ # instantiate the result message
+ if message is self.REQUEST:
+ body_class = unwrap_messages(ctx.descriptor.in_message,
+ self.skip_depth)
+ elif message is self.RESPONSE:
+ body_class = unwrap_messages(ctx.descriptor.out_message,
+ self.skip_depth)
+ if body_class:
+ # assign raw result to its wrapper, result_message
+ result_message_class = ctx.descriptor.in_message
+ value = ctx.in_body_doc.get(result_message_class.get_type_name(), None)
+ result_message = self._doc_to_object(result_message_class, value)
+
+ ctx.in_object = result_message
+
+ else:
+ ctx.in_object = []
+
+ self.event_manager.fire_event('after_deserialize', ctx)
+
+ def serialize(self, ctx, message):
+ assert message in (self.REQUEST, self.RESPONSE)
+
+ self.event_manager.fire_event('before_serialize', ctx)
+
+ if ctx.out_error is not None:
+ ctx.out_document = [ctx.out_error.to_dict(ctx.out_error)]
+
+ else:
+ # get the result message
+ if message is self.REQUEST:
+ out_type = ctx.descriptor.in_message
+ elif message is self.RESPONSE:
+ out_type = ctx.descriptor.out_message
+ if out_type is None:
+ return
+
+ out_type_info = out_type._type_info
+
+ # instantiate the result message
+ out_instance = out_type()
+
+ # assign raw result to its wrapper, result_message
+ for i in range(len(out_type_info)):
+ attr_name = out_type_info.keys()[i]
+ setattr(out_instance, attr_name, ctx.out_object[i])
+
+ # strip the wrappers if asked for
+ out_type, out_instance = unwrap_instance(out_type, out_instance,
+ self.skip_depth)
+
+ # arrays get wrapped in [], whereas other objects get wrapped in
+ # {object_name: ...}
+ wrapper_name = None
+ if not issubclass(out_type, Array):
+ wrapper_name = out_type.get_type_name()
+
+ # transform the results into a dict:
+ if out_type.Attributes.max_occurs > 1:
+ ctx.out_document = (self._to_value(out_type, inst, wrapper_name)
+ for inst in out_instance)
+ else:
+ ctx.out_document = [self._to_value(out_type, out_instance, wrapper_name)]
+
+ self.event_manager.fire_event('after_serialize', ctx)
+
+ def _from_dict_value(self, cls, value):
+ # validate raw input
+ if self.validator is self.SOFT_VALIDATION:
+ if issubclass(cls, Unicode) and not isinstance(value, unicode):
+ if not (issubclass(cls, String) and isinstance(value, str)):
+ raise ValidationError(value)
+
+ elif issubclass(cls, Decimal) and not isinstance(value, (int, long, float)):
+ raise ValidationError(value)
+
+ elif issubclass(cls, DateTime) and not (isinstance(value, unicode) and
+ cls.validate_string(cls, value)):
+ raise ValidationError(value)
+
+ # get native type
+ if issubclass(cls, ComplexModelBase):
+ retval = self._doc_to_object(cls, value)
+
+ elif issubclass(cls, DateTime):
+ retval = cls.from_string(value)
+
+ else:
+ retval = value
+
+ # validate native type
+ if self.validator is self.SOFT_VALIDATION and \
+ not cls.validate_native(cls, retval):
+ raise ValidationError(retval)
+
+ return retval
+
+ def _get_member_pairs(self, cls, inst):
+ parent_cls = getattr(cls, '__extends__', None)
+ if not (parent_cls is None):
+ for r in self._get_member_pairs(parent_cls, inst):
+ yield r
+
+ for k, v in cls._type_info.items():
+ try:
+ sub_value = getattr(inst, k, None)
+ except Exception, e: # to guard against e.g. sqlalchemy throwing NoSuchColumnError
+ logger.error("Error getting %r: %r" %(k,e))
+ sub_value = None
+
+ if v.Attributes.max_occurs > 1:
+ if sub_value != None:
+ yield (k, [self._to_value(v,sv) for sv in sub_value])
+
+ else:
+ yield (k, self._to_value(v, sub_value))
+
+ def _to_value(self, cls, value, k=None):
+ if issubclass(cls, ComplexModelBase):
+ return self._to_dict(cls, value, k)
+
+ if issubclass(cls, DateTime):
+ return cls.to_string(value)
+
+ if issubclass(cls, Decimal):
+ if cls.Attributes.format is None:
+ return value
+ else:
+ return cls.to_string(value)
+
+ return value
+
+ def _to_dict(self, cls, inst, field_name=None):
+ inst = cls.get_serialization_instance(inst)
+
+ retval = dict(self._get_member_pairs(cls, inst))
+ if field_name is None:
+ return retval
+ else:
+ return {field_name: retval}
View
253 spyne/protocol/json/__init__.py
@@ -50,30 +50,18 @@
from spyne.model.primitive import Unicode
from spyne.protocol import ProtocolBase
-from spyne.protocol._base import unwrap_messages
-from spyne.protocol._base import unwrap_instance
+from spyne.protocol import DictObject
+from spyne.protocol import unwrap_messages
+from spyne.protocol import unwrap_instance
-class JsonObject(ProtocolBase):
+class JsonObject(DictObject):
"""An implementation of the json protocol that uses simplejson or json
packages.
"""
mime_type = 'application/json'
- def set_validator(self, validator):
- """Sets the validator for the protocol.
-
- :param validator: one of ('soft', None)
- """
-
- if validator == 'soft' or validator is self.SOFT_VALIDATION:
- self.validator = self.SOFT_VALIDATION
- elif validator is None:
- self.validator = None
- else:
- raise ValueError(validator)
-
def create_in_document(self, ctx, in_string_encoding=None):
"""Sets ``ctx.in_document``, using ``ctx.in_string``."""
@@ -86,238 +74,5 @@ def create_in_document(self, ctx, in_string_encoding=None):
except JSONDecodeError, e:
raise Fault('Client.JsonDecodeError', repr(e))
- def decompose_incoming_envelope(self, ctx, message):
- """Sets ``ctx.in_body_doc``, ``ctx.in_header_doc`` and
- ``ctx.method_request_string`` using ``ctx.in_document``.
- """
-
- # set ctx.in_header
- ctx.transport.in_header_doc = None # use an rpc protocol if you want headers.
-
- doc = ctx.in_document
-
- ctx.in_header_doc = None
- ctx.in_body_doc = doc
-
- if len(doc) == 0:
- raise Fault("Client", "Empty request")
-
- # set ctx.method_request_string
- ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(),
- doc.keys()[0])
-
- logger.debug('\theader : %r' % (ctx.in_header_doc))
- logger.debug('\tbody : %r' % (ctx.in_body_doc))
-
- def _doc_to_object(self, cls, doc):
- if doc is None:
- return []
-
- if issubclass(cls, Array):
- retval = [ ]
- (serializer,) = cls._type_info.values()
-
- for child in doc:
- retval.append(self._from_dict_value(serializer, child))
-
- return retval
-
- inst = cls.get_deserialization_instance()
-
- # get all class attributes, including the ones coming from parent classes.
- flat_type_info = cls.get_flat_type_info(cls)
-
- # initialize instance
- for k in flat_type_info:
- setattr(inst, k, None)
-
- # this is for validating cls.Attributes.{min,max}_occurs
- frequencies = {}
-
- try:
- items = doc.items()
- except AttributeError:
- items = zip(cls._type_info.keys(), doc)
-
- # parse input to set incoming data to related attributes.
- for k,v in items:
- freq = frequencies.get(k, 0)
- freq += 1
- frequencies[k] = freq
-
- member = flat_type_info.get(k, None)
- if member is None:
- continue
-
- mo = member.Attributes.max_occurs
- if mo > 1:
- value = getattr(inst, k, None)
- if value is None:
- value = []
-
- for a in v:
- value.append(self._from_dict_value(member, a))
-
- else:
- value = self._from_dict_value(member, v)
-
- setattr(inst, k, value)
-
- if self.validator is self.SOFT_VALIDATION:
- for k, v in flat_type_info.items():
- val = frequencies.get(k, 0)
- if (val < v.Attributes.min_occurs or val > v.Attributes.max_occurs):
- raise Fault('Client.ValidationError',
- '%r member does not respect frequency constraints.' % k)
-
- return inst
-
- def deserialize(self, ctx, message):
- assert message in (self.REQUEST, self.RESPONSE)
-
- self.event_manager.fire_event('before_deserialize', ctx)
-
- if ctx.descriptor is None:
- raise Fault("Client", "Method %r not found." %
- ctx.method_request_string)
-
- # instantiate the result message
- if message is self.REQUEST:
- body_class = unwrap_messages(ctx.descriptor.in_message,
- self.skip_depth)
- elif message is self.RESPONSE:
- body_class = unwrap_messages(ctx.descriptor.out_message,
- self.skip_depth)
- if body_class:
- # assign raw result to its wrapper, result_message
- result_message_class = ctx.descriptor.in_message
- value = ctx.in_body_doc.get(result_message_class.get_type_name(), None)
- result_message = self._doc_to_object(result_message_class, value)
-
- ctx.in_object = result_message
- self.event_manager.fire_event('after_deserialize', ctx)
-
- else:
- ctx.in_object = []
-
- def serialize(self, ctx, message):
- assert message in (self.REQUEST, self.RESPONSE)
-
- self.event_manager.fire_event('before_serialize', ctx)
-
- if ctx.out_error is not None:
- # FIXME: There's no way to alter soap response headers for the user.
- ctx.out_document = [ctx.out_error._to_dict(ctx.out_error)]
-
- else:
- # get the result message
- if message is self.REQUEST:
- out_type = ctx.descriptor.in_message
- elif message is self.RESPONSE:
- out_type = ctx.descriptor.out_message
- if out_type is None:
- return
-
- out_type_info = out_type._type_info
-
- # instantiate the result message
- out_instance = out_type()
-
- # assign raw result to its wrapper, result_message
- for i in range(len(out_type_info)):
- attr_name = out_type_info.keys()[i]
- setattr(out_instance, attr_name, ctx.out_object[i])
-
- # strip the wrappers if asked for
- out_type, out_instance = unwrap_instance(out_type, out_instance, self.skip_depth)
-
- # arrays get wrapped in [], whereas other objects get wrapped in
- # {object_name: ...}
- wrapper_name = None
- if not issubclass(out_type, Array):
- wrapper_name = out_type.get_type_name()
-
- # transform the results into a dict:
- if out_type.Attributes.max_occurs > 1:
- ctx.out_document = (self._to_value(out_type, inst, wrapper_name) for inst in out_instance)
- else:
- ctx.out_document = [self._to_value(out_type, out_instance, wrapper_name)]
-
- self.event_manager.fire_event('after_serialize', ctx)
-
def create_out_string(self, ctx, out_string_encoding='utf8'):
ctx.out_string = (json.dumps(o) for o in ctx.out_document)
-
- def _from_dict_value(self, cls, value):
- # validate raw input
- if self.validator is self.SOFT_VALIDATION:
- if issubclass(cls, Unicode) and not isinstance(value, unicode):
- raise ValidationError(value)
-
- if issubclass(cls, Decimal) and not isinstance(value, (int, long, float)):
- raise ValidationError(value)
-
- if issubclass(cls, DateTime) and not (isinstance(value, unicode) and
- cls.validate_string(cls, value)):
- raise ValidationError(value)
-
- # get native type
- if issubclass(cls, ComplexModelBase):
- retval = self._doc_to_object(cls, value)
-
- elif issubclass(cls, DateTime):
- retval = cls.from_string(value)
-
- else:
- retval = value
-
- # validate native type
- if self.validator is self.SOFT_VALIDATION and \
- not cls.validate_native(cls, retval):
- raise ValidationError(retval)
-
- return retval
-
- def _get_member_pairs(self, cls, inst):
- parent_cls = getattr(cls, '__extends__', None)
- if not (parent_cls is None):
- for r in self._get_member_pairs(parent_cls, inst):
- yield r
-
- for k, v in cls._type_info.items():
- try:
- sub_value = getattr(inst, k, None)
- except Exception, e: # to guard against e.g. sqlalchemy throwing NoSuchColumnError
- logger.error("Error getting %r: %r" %(k,e))
- sub_value = None
-
- if v.Attributes.max_occurs > 1:
- if sub_value != None:
- yield (k, [self._to_value(v,sv) for sv in sub_value])
-
- else:
- yield (k, self._to_value(v, sub_value))
-
- def _to_value(self, cls, value, k=None):
- if issubclass(cls, ComplexModelBase):
- return self._to_dict(cls, value, k)
-
- if issubclass(cls, DateTime):
- return cls.to_string(value)
-
- if issubclass(cls, Decimal):
- if cls.Attributes.format is None:
- return value
- else:
- return cls.to_string(value)
-
- return value
-
- def _to_dict(self, cls, inst, field_name=None):
- inst = cls.get_serialization_instance(inst)
-
- retval = dict(self._get_member_pairs(cls, inst))
- if field_name is None:
- return retval
- else:
- return {field_name: retval}
View
191 spyne/protocol/msgpack/__init__.py
@@ -0,0 +1,191 @@
+
+#
+# spyne - Copyright (C) Spyne contributors.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+#
+
+"""This module contains implementations for protocols that use MessagePack as
+serializer.
+
+This protocol is EXPERIMENTAL.
+"""
+
+import logging
+logger = logging.getLogger(__name__)
+
+import msgpack
+
+from spyne.model.complex import Array
+from spyne.model.fault import Fault
+from spyne.protocol import ProtocolBase
+from spyne.protocol import DictObject
+
+
+class MessagePackDecodeError(Fault):
+ def __init__(self, data=None):
+ Fault.__init__(self, "Client.MessagePackDecodeError", data)
+
+
+class MessagePackObject(DictObject):
+ """An integration class for the msgpack protocol."""
+
+ mime_type = 'application/x-msgpack'
+
+ def create_in_document(self, ctx, in_string_encoding=None):
+ """Sets ``ctx.in_document``, using ``ctx.in_string``.
+ :param ctx: The MethodContext object
+ :param in_string_encoding: MessagePack is a binary protocol. So this
+ argument is ignored.
+ """
+
+ ctx.in_document = msgpack.unpackb(''.join(ctx.in_string))
+
+ if not isinstance(ctx.in_document, dict):
+ raise MessagePackDecodeError("Request object must be a dictionary")
+
+ def create_out_string(self, ctx, out_string_encoding='utf8'):
+ ctx.out_string = (msgpack.packb(o) for o in ctx.out_document)
+
+
+class MessagePackRpc(MessagePackObject):
+ """An integration class for the msgpack-rpc protocol."""
+
+ mime_type = 'application/x-msgpack'
+
+ MSGPACK_REQUEST = 0
+ MSGPACK_RESPONSE = 1
+ MSGPACK_NOTIFY = 2
+
+ def create_in_document(self, ctx, in_string_encoding=None):
+ """Sets ``ctx.in_document``, using ``ctx.in_string``.
+ :param ctx: The MethodContext object
+ :param in_string_encoding: MessagePack is a binary protocol. So this
+ argument is ignored.
+ """
+
+ # TODO: Use feed api
+ ctx.in_document = msgpack.unpackb(''.join(ctx.in_string))
+
+ try:
+ len(ctx.in_document)
+ except TypeError:
+ raise MessagePackDecodeError("Input must be an itearble.")
+
+ if not (3 <= len(ctx.in_document) <= 4):
+ raise MessagePackDecodeError("Length of input iterable must be "
+ "either 3 or 4")
+
+ def decompose_incoming_envelope(self, ctx, message):
+ # FIXME: For example: {0: 0, 1: 0, 2: "some_call", 3: [1,2,3]} will also
+ # work. Is this a problem?
+
+ # FIXME: Msgid is ignored. Is this a problem?
+ msgparams = []
+ if len(ctx.in_document) == 3:
+ msgtype, msgid, msgname = ctx.in_document
+
+ elif len(ctx.in_document) == 4:
+ msgtype, msgid, msgname, msgparams = ctx.in_document
+
+ if msgtype == MessagePackRpc.MSGPACK_REQUEST:
+ assert message == MessagePackRpc.REQUEST
+
+ elif msgtype == MessagePackRpc.MSGPACK_RESPONSE:
+ assert message == MessagePackRpc.RESPONSE
+
+ elif msgtype == MessagePackRpc.MSGPACK_NOTIFY:
+ raise NotImplementedError()
+
+ else:
+ raise MessagePackDecodeError("Unknown message type %r" % msgtype)
+
+ ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(),
+ msgname)
+
+ ctx.in_header_doc = None # MessagePackRpc does not seem to have Header support
+ ctx.in_body_doc = msgparams
+
+ logger.debug('\theader : %r' % (ctx.in_header_doc))
+ logger.debug('\tbody : %r' % (ctx.in_body_doc))
+
+ def deserialize(self, ctx, message):
+ assert message in (self.REQUEST, self.RESPONSE)
+
+ self.event_manager.fire_event('before_deserialize', ctx)
+
+ if ctx.descriptor is None:
+ raise Fault("Client", "Method %r not found." %
+ ctx.method_request_string)
+
+ # instantiate the result message
+ if message is self.REQUEST:
+ body_class = ctx.descriptor.in_message
+ elif message is self.RESPONSE:
+ body_class = ctx.descriptor.out_message
+
+ if body_class:
+ ctx.in_object = body_class.get_serialization_instance(ctx.in_body_doc)
+
+ else:
+ ctx.in_object = []
+
+ self.event_manager.fire_event('after_deserialize', ctx)
+
+ def serialize(self, ctx, message):
+ assert message in (self.REQUEST, self.RESPONSE)
+
+ self.event_manager.fire_event('before_serialize', ctx)
+
+ if ctx.out_error is not None:
+ ctx.out_document = [MessagePackRpc.MSGPACK_RESPONSE, 0,
+ ctx.out_error.to_dict(ctx.out_error)]
+
+ else:
+ # get the result message
+ if message is self.REQUEST:
+ out_type = ctx.descriptor.in_message
+ elif message is self.RESPONSE:
+ out_type = ctx.descriptor.out_message
+
+ if out_type is None:
+ return
+
+ out_type_info = out_type._type_info
+
+ # instantiate the result message
+ out_instance = out_type()
+
+ # assign raw result to its wrapper, result_message
+ for i in range(len(out_type_info)):
+ attr_name = out_type_info.keys()[i]
+ setattr(out_instance, attr_name, ctx.out_object[i])
+
+ wrapper_name = None
+ if not issubclass(out_type, Array):
+ wrapper_name = out_type.get_type_name()
+
+ # transform the results into a dict:
+ if out_type.Attributes.max_occurs > 1:
+ ctx.out_document = [[MessagePackRpc.MSGPACK_RESPONSE, 0, None,
+ (self._to_value(out_type, inst, wrapper_name)
+ for inst in out_instance)
+ ]]
+ else:
+ ctx.out_document = [[MessagePackRpc.MSGPACK_RESPONSE, 0, None,
+ self._to_value(out_type, out_instance, wrapper_name)
+ ]]
+
+ self.event_manager.fire_event('after_serialize', ctx)
View
4 spyne/protocol/xml/_base.py
@@ -145,9 +145,9 @@ def from_element(self, cls, element):
handler = self.deserialization_handlers[cls]
return handler(self, cls, element)
- def to_parent_element(self, cls, value, tns, parent_elt, * args, ** kwargs):
+ def to_parent_element(self, cls, value, tns, parent_elt, *args, **kwargs):
handler = self.serialization_handlers[cls]
- handler(self, cls, value, tns, parent_elt, * args, ** kwargs)
+ handler(self, cls, value, tns, parent_elt, *args, **kwargs)
def validate_body(self, ctx, message):
"""Sets ctx.method_request_string and calls :func:`generate_contexts`
View
6 spyne/server/twisted/__init__.py
@@ -17,6 +17,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
+
"""This module contains a server implementation that uses a Twisted Web Resource
as transport.
@@ -52,8 +53,7 @@
def _reconstruct_url(request):
server_name = request.getRequestHostname()
server_port = request.getHost().port
- if (bool(request.isSecure()), server_port) not in [
- (True, 443), (False, 80)]:
+ if (bool(request.isSecure()), server_port) not in [(True, 443), (False, 80)]:
server_name = '%s:%d' % (server_name, server_port)
if request.isSecure():
@@ -105,6 +105,7 @@ def stopProducing(self):
Exception("Consumer asked us to stop producing"))
self.deferred = None
+
class TwistedHttpTransport(HttpBase):
@staticmethod
def decompose_incoming_envelope(prot, ctx, message):
@@ -123,6 +124,7 @@ def decompose_incoming_envelope(prot, ctx, message):
ctx.in_header_doc = request.headers
ctx.in_body_doc = request.args
+
class TwistedWebResource(Resource):
"""A server transport that exposes the application as a twisted web
Resource.
View
8 spyne/test/interop/_test_soap_client_base.py
@@ -40,16 +40,16 @@ def test_port_open(port):
def run_server(server_type):
if server_type == 'http':
from spyne.test.interop.server.soap_http_basic import main
- from spyne.test.interop.server.soap_http_basic import PORT
+ from spyne.test.interop.server.soap_http_basic import port
elif server_type == 'zeromq':
from spyne.test.interop.server.soap_zeromq import main
- from spyne.test.interop.server.soap_zeromq import PORT
+ from spyne.test.interop.server.soap_zeromq import port
else:
raise ValueError(server_type)
- if server_started.get(PORT, None) is None:
+ if server_started.get(port, None) is None:
def run_server():
main()
@@ -59,7 +59,7 @@ def run_server():
# FIXME: Does anybody have a better idea?
time.sleep(2)
- server_started[PORT] = test_port_open(PORT)
+ server_started[port] = test_port_open(port)
class SpyneClientTestBase(object):
View
182 spyne/test/interop/wsi-report-spyne.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="wsi-test-tools/common/xsl/report.xsl" type="text/xsl" ?>
-<report name="WS-I Basic Profile Conformance Report." timestamp="2012-07-12T11:22:12.273"
+<report name="WS-I Basic Profile Conformance Report." timestamp="2012-08-06T11:59:49.270"
xmlns="http://www.ws-i.org/testing/2004/07/report/"
xmlns:wsi-report="http://www.ws-i.org/testing/2004/07/report/"
xmlns:wsi-log="http://www.ws-i.org/testing/2003/03/log/"
@@ -141,7 +141,7 @@
<assertionResult id="SSBP2403" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerInHeaderMsg">
+ <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerOutHeaderMsg">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
@@ -153,7 +153,7 @@
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerOutHeaderMsg">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerOutHeaderMsg">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
@@ -165,13 +165,13 @@
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerOutHeaderMsg">
+ <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerInHeaderMsg">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerInHeaderMsg">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerInHeaderMsg">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
@@ -445,265 +445,265 @@
<assertionResult id="BP2014" result="notApplicable">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_date_time_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_stringResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}Fault">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_integer">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}return_binary_data">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_enum">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}soap_exception">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_duration">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_floatResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_attachmentResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_class_with_self_reference">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_date_time_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_classResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}huge_numberResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}python_exceptionResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}return_invalid_dataResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}return_invalid_data">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_date_time_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}return_other_class_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_attachment_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_any">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}custom_messages">
+ <entry type="message" referenceID="{spyne.test.interop.server}documented_exception">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_booleanResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}do_something_else">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_anyResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}complex_return">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_float">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}long_stringResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}documented_exceptionResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_double_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_boolean_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}multi_param">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_string_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}return_other_class_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_boolean_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}return_binary_dataResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_class_with_self_referenceResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_classResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}multi_paramResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_double_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_integerResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_boolean_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}return_other_class_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_enumResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}return_invalid_data">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_array_in_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_headerResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}non_nillableResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_any_as_dict">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_boolean">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_extension_class">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_integer_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_any">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_class_with_self_reference">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}huge_number">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_array_in_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_boolean_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}non_nillable">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_datetime">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_float">
+ <entry type="message" referenceID="{spyne.test.interop.server}python_exception">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_integer">
+ <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_header">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}documented_exceptionResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_booleanResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}getCustomMessagesMsgOut">
+ <entry type="message" referenceID="{spyne.test.interop.server}custom_messages">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_datetime">
+ <entry type="message" referenceID="{spyne.test.interop.server}long_stringResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}do_something_else">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_enumResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}test_empty">
+ <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_headerResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_duration">
+ <entry type="message" referenceID="{spyne.test.interop.server}return_other_class_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_extension_classResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_durationResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}non_nillable">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_double_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}huge_number">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
@@ -715,205 +715,205 @@
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_array_in_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_string_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}Fault">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}soap_exceptionResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_float_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_headerResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_floatResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}send_out_complex_header">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_any_as_dictResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_anyResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_extension_classResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_float_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_header">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_doubleResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}complex_returnResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_headerResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_integerResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_string_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_any_as_dictResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}test_emptyResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_class_with_self_referenceResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}non_nillableResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_nested_class">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_stringResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_extension_class">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_boolean_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}do_something_elseResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}huge_numberResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_array_in_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}do_something_elseResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}python_exceptionResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_boolean_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class_array">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_float_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_complex_header">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_simple_class">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}complex_returnResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_in_header">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_attachment">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_doubleResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}send_out_headerResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}soap_exceptionResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_in_header">
+ <entry type="message" referenceID="{spyne.test.interop.server}test_empty">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}test_emptyResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_double">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_string_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_attachment_arrayResponse">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}python_exception">
+ <entry type="message" referenceID="{spyne.test.interop.server}multi_param">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_any_as_dict">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_date_time_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_integer_arrayResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}getCustomMessagesMsgOut">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}multi_paramResponse">
+ <entry type="message" referenceID="{spyne.test.interop.server}echo_double_array">
<assertionResult id="BP2115" result="passed">
</assertionResult>
<assertionResult id="BP2116" result="passed">
</assertionResult>
</entry>
- <entry type="message" referenceID="{spyne.test.interop.server}echo_integer_array">
+ <entry type="