diff --git a/bin/mutalyzer-json-service.wsgi b/bin/mutalyzer-json-service.wsgi index 052dbbb36111927d5c7ef3853af9610a1181b00f..4e2f98020a74e7c2bf80cbb4d7631c6cfa47cc78 100755 --- a/bin/mutalyzer-json-service.wsgi +++ b/bin/mutalyzer-json-service.wsgi @@ -23,7 +23,7 @@ To start the built-in HTTP server on port 8082: import sys from wsgiref.simple_server import make_server -from rpclib.server.wsgi import WsgiApplication +from spyne.server.wsgi import WsgiApplication from mutalyzer.services import json diff --git a/extras/pre-install.sh b/extras/pre-install.sh index 3641d10eaa55b8ff821fb3be868432fd69e5b9b3..34bb88a3c9ddbec68f87dd3b8e9850dae3c87e2e 100644 --- a/extras/pre-install.sh +++ b/extras/pre-install.sh @@ -44,13 +44,12 @@ apt-get install -y \ python-setuptools \ git-core -echo -e "${COLOR_INFO}Installing known-working rpclib from git master${COLOR_END}" +echo -e "${COLOR_INFO}Installing known-working spyne from git${COLOR_END}" -# For now we use a specific known-working version of rpclib. The project has -# in the meantime been renamed to Spyne and we should update some time. +# For now we use a specific known-working version of spyne. pushd $(mktemp -d) -git clone https://github.com/martijnvermaat/rpclib.git . -git checkout mutalyzer +git clone https://github.com/arskom/spyne.git . +git checkout -b mutalyzer 065e475fa216837cd714e046e92d01a1799f78c2 python setup.py install popd diff --git a/mutalyzer/__init__.py b/mutalyzer/__init__.py index 426c8e052daaa03fa46faf50a2aa0075ea008647..a6839ab59a19c0f66eace64cb28ee06930d89931 100644 --- a/mutalyzer/__init__.py +++ b/mutalyzer/__init__.py @@ -22,8 +22,8 @@ import os RELEASE = False -__version_info__ = ('2', '0', 'beta-21', 'dev') -__date__ = '11 Jul 2012' +__version_info__ = ('2', '0', 'beta-22', 'dev') +__date__ = '23 Jul 2012' __version__ = '.'.join(__version_info__) diff --git a/mutalyzer/models.py b/mutalyzer/models.py index 0dcc07ec440cc716e679611f825cce7c2e331ca8..5f2c342278f5b6b0663a7b8bea2f3f98a91263a5 100644 --- a/mutalyzer/models.py +++ b/mutalyzer/models.py @@ -1,13 +1,13 @@ """ Collection of serilizable objects used by the SOAP webservice. They extend -from the rpclib ClassModel. +from the spyne ClassModel. -Default attributes for the rpclib ClassModel: +Default attributes for the spyne ClassModel: - nillable = True - min_occurs = 0 - max_occurs = 1 -Additional attributes values for the rpclib String model: +Additional attributes values for the spyne String model: - min_len = 0 - max_len = 'unbounded' - pattern = None @@ -17,21 +17,21 @@ Additional attributes values for the rpclib String model: """ -from rpclib.model.primitive import String, Integer, Boolean, DateTime -from rpclib.model.complex import ComplexModel, Array +from spyne.model.primitive import String, Integer, Boolean, DateTime +from spyne.model.complex import ComplexModel, Array from mutalyzer import SOAP_NAMESPACE class Mandatory(object): """ - This is rpclib.model.primitive.Mandatory, but without min_length=1 for + This is spyne.model.primitive.Mandatory, but without min_length=1 for the String model. """ - String = String(min_occurs=1, nillable=False) - Integer = Integer(min_occurs=1, nillable=False) - Boolean = Boolean(min_occurs=1, nillable=False) - DateTime = DateTime(min_occurs=1, nillable=False) + String = String(type_name='mandatory_string', min_occurs=1, nillable=False) + Integer = Integer(type_name='mandatory_integer', min_occurs=1, nillable=False) + Boolean = Boolean(type_name='mandatory_boolean', min_occurs=1, nillable=False) + DateTime = DateTime(type_name='mandatory_date_time', min_occurs=1, nillable=False) #Mandatory diff --git a/mutalyzer/services/json.py b/mutalyzer/services/json.py index b1f46c313d6724a9f0b8f81d723fe692f1f9ad63..ae94a5032dc537656261aa60080d87f95710ac55 100644 --- a/mutalyzer/services/json.py +++ b/mutalyzer/services/json.py @@ -3,15 +3,21 @@ Mutalyzer webservice HTTP/RPC with JSON response payloads. """ -from rpclib.application import Application -from rpclib.protocol.http import HttpRpc -from rpclib.protocol.json import JsonObject +from mutalyzer.util import monkey_patch_spyne; monkey_patch_spyne() + +from spyne.application import Application +from spyne.protocol.http import HttpRpc +from spyne.protocol.json import JsonObject import mutalyzer from mutalyzer.services import rpc # HTTP/RPC application. +# Note that we originally provided skip_depth=2 to the JsonObject constructor +# to get rid of some annoying wrappers around the json results. However, this +# breaks methods returning a primitive datatype (e.g. just a string). Might +# file a bug about this on spyne. application = Application([rpc.MutalyzerService], tns=mutalyzer.SOAP_NAMESPACE, - in_protocol=HttpRpc(), out_protocol=JsonObject(skip_depth=2), + in_protocol=HttpRpc(), out_protocol=JsonObject(), name='Mutalyzer') diff --git a/mutalyzer/services/rpc.py b/mutalyzer/services/rpc.py index 4e4f87767df4797af31fce18bb60b64735d3f3d3..e8e05596bd67e5df73aef286a05e0d7014374936 100644 --- a/mutalyzer/services/rpc.py +++ b/mutalyzer/services/rpc.py @@ -8,11 +8,11 @@ Mutalyzer RPC services. """ -from rpclib.decorator import srpc -from rpclib.service import ServiceBase -from rpclib.model.primitive import String, Integer, Boolean, DateTime -from rpclib.model.complex import Array -from rpclib.model.fault import Fault +from spyne.decorator import srpc +from spyne.service import ServiceBase +from spyne.model.primitive import String, Integer, Boolean, DateTime +from spyne.model.complex import Array +from spyne.model.fault import Fault import os import socket from operator import itemgetter, attrgetter @@ -677,7 +677,7 @@ class MutalyzerService(ServiceBase): result.molecule = O.getIndexedOutput('molecule', 0) # We force the results to strings here, because some results - # may be of type Bio.Seq.Seq which rpclib doesn't like. + # may be of type Bio.Seq.Seq which spyne doesn't like. # # todo: We might have to also do this elsewhere. diff --git a/mutalyzer/services/soap.py b/mutalyzer/services/soap.py index 31bb4e67d99376e8504c26af1a694dce1f19976d..e442b9d0f7b7fd045bdb505d1ac02379f89ba591 100644 --- a/mutalyzer/services/soap.py +++ b/mutalyzer/services/soap.py @@ -3,9 +3,9 @@ Mutalyzer SOAP/1.1 webservice. """ -from rpclib.application import Application -from rpclib.protocol.soap import Soap11 -from rpclib.server.wsgi import WsgiApplication +from spyne.application import Application +from spyne.protocol.soap import Soap11 +from spyne.server.wsgi import WsgiApplication import mutalyzer from mutalyzer.services import rpc @@ -20,6 +20,6 @@ application = Application([rpc.MutalyzerService], tns=mutalyzer.SOAP_NAMESPACE, # Below we define WSGI applications for use with e.g. Apache/mod_wsgi. # Note: We would like to create the wsgi.Application instance only in the # bin/mutalyzer-webservice.wsgi script, but unfortunately this breaks the -# get_interface_document method of rpclib which we use to generate API +# get_interface_document method of spyne which we use to generate API # documentation in website.py. wsgi_application = WsgiApplication(application) diff --git a/mutalyzer/util.py b/mutalyzer/util.py index efca9b86c31d152ebe105e79110af6d41c4852b8..df26186a858043a597458de2e0933dcae2288973 100644 --- a/mutalyzer/util.py +++ b/mutalyzer/util.py @@ -861,7 +861,7 @@ def monkey_patch_suds(): Call this function before importing anything from the suds package. For example, start your file with the following: - import monkey; monkey.monkey_patch_suds() + from mutalyzer.util import monkey_patch_suds; monkey_patch_suds() from suds.client import Client """ from suds.xsd.sxbasic import Import @@ -879,3 +879,29 @@ def monkey_patch_suds(): Import.open = _import_open_patched Import.MUTALYZER_MONKEY_PATCHED = True #monkey_patch_suds + + +def monkey_patch_spyne(): + """ + Apply our monkey-patch for the spyne package. + + Fault objects cannot be serialized by the JsonObject output protocol, + this fixes it. + + Call this function before importing anything from the spyne package. For + example, start your file with the following: + + from mutalyzer.util import monkey_patch_spyne; monkey_patch_spyne() + from spyne.protocol.json import JsonObject + """ + from spyne.model.fault import Fault + + if hasattr(Fault, '_to_dict'): + return + + def _to_dict(self, *args, **kwargs): + return dict(Fault=dict(faultcode=self.faultcode, + faultstring=self.faultstring)) + + Fault._to_dict = _to_dict +#monkey_patch_spyne diff --git a/mutalyzer/website.py b/mutalyzer/website.py index c738a6731bace7a6ffffb8147d89a6a814abb22e..4dc460404d30297424cfb49d4b707377e478e7c2 100644 --- a/mutalyzer/website.py +++ b/mutalyzer/website.py @@ -29,7 +29,7 @@ from lxml import etree from cStringIO import StringIO from simpletal import simpleTALES from simpletal import simpleTAL -from rpclib.interface.wsdl import Wsdl11 +from spyne.interface.wsdl import Wsdl11 import mutalyzer from mutalyzer import util diff --git a/tests/test_services_json.py b/tests/test_services_json.py index 6055a185aee5447062c14f7050b5f3ad907b4f76..f235adbf34a538b979e1c0a8603d1521e453b575 100644 --- a/tests/test_services_json.py +++ b/tests/test_services_json.py @@ -30,7 +30,7 @@ class TestServicesJson(): Running checkSyntax with a valid variant name should return True. """ r = call('checkSyntax', variant='AB026906.1:c.274G>T') - assert_equal(r['CheckSyntaxOutput']['valid'], True) + assert_equal(r['checkSyntaxResponse']['checkSyntaxResult']['valid'], True) def test_checksyntax_invalid(self): """ @@ -38,8 +38,8 @@ class TestServicesJson(): and give at least one error message. """ r = call('checkSyntax', variant='0:abcd') - assert_equal(r['CheckSyntaxOutput']['valid'], False) - assert len(r['CheckSyntaxOutput']['messages']['SoapMessage']) >= 1 + assert_equal(r['checkSyntaxResponse']['checkSyntaxResult']['valid'], False) + assert len(r['checkSyntaxResponse']['checkSyntaxResult']['messages']['SoapMessage']) >= 1 def test_checksyntax_empty(self): """ @@ -55,14 +55,14 @@ class TestServicesJson(): """ r = call('transcriptInfo', LOVD_ver='123', build='hg19', accNo='NM_002001.2') - assert_equal(r['Transcript']['trans_start'], -99) - assert_equal(r['Transcript']['trans_stop'], 1066) - assert_equal(r['Transcript']['CDS_stop'], 774) + assert_equal(r['transcriptInfoResponse']['transcriptInfoResult']['trans_start'], -99) + assert_equal(r['transcriptInfoResponse']['transcriptInfoResult']['trans_stop'], 1066) + assert_equal(r['transcriptInfoResponse']['transcriptInfoResult']['CDS_stop'], 774) def test_info(self): """ Running the info method should give us some version information. """ r = call('info') - assert_equal(type(r['InfoOutput']['versionParts']['string']), list) - assert_equal(r['InfoOutput']['version'], mutalyzer.__version__) + assert_equal(type(r['infoResponse']['infoResult']['versionParts']['string']), list) + assert_equal(r['infoResponse']['infoResult']['version'], mutalyzer.__version__)