Changes between Version 7 and Version 8 of Jsonrpc


Ignore:
Timestamp:
Jun 19, 2009, 3:16:46 AM (16 years ago)
Author:
lkcl
Comment:

add jsonrpc.py from pyjamas

Legend:

Unmodified
Added
Removed
Modified
  • Jsonrpc

    v7 v8  
    182182        else:
    183183            return self.generate_smd()
     184}}}
     185
     186== Alternative JsonRpc Implementation ==
     187
     188This is the proven and working JSON-RPC Django handler developed incrementally since 2007 and deployed in production Pyjamas Web 2.0 applications.  It is much shorter, simpler, easier to use and less cumbersome than the above, although it does not have support for GET (to view a list of methods) and does not have the same level of configurability.  Importantly, the original request object is passed to all functions in the JSONRPC service, thus allowing the application to gain access to Django session information, and cookies etc.
     189
     190Usage examples are included inline in the source.  Note in particular that the JSONRPCService class instance itself is handed to urlpatterns, and so all POST requests result in JSONRPCService's {{{__call__}}} method being called, resulting in a much simpler approach than the above.
     191
     192This code is maintained at http://groups.google.com/group/pyjamas-dev/files and a version is included in http://pyjs.org
     193
     194{{{
     195# jsonrpc.py
     196#   original code: http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas
     197#   also from: http://www.pimentech.fr/technologies/outils
     198from django.utils import simplejson
     199import sys
     200
     201# JSONRPCService and jsonremote are used in combination to drastically
     202# simplify the provision of JSONRPC services.  use as follows:
     203#
     204# from jsonrpc import JSONRPCService, jsonremote
     205#
     206# jsonservice = JSONRPCService()
     207#
     208# @jsonremote(jsonservice)
     209# def test(request, echo_param):
     210#     return "echoing the param back: %s", echo_param
     211#
     212# then dump jsonservice into urlpatterns:
     213#  (r'^service1/$', 'djangoapp.views.jsonservice'),
     214
     215def response(id, result):
     216    return simplejson.dumps({'version': '1.1', 'id':id,
     217                             'result':result, 'error':None})
     218def error(id, code, message):
     219    return simplejson.dumps({'id': id, 'version': '1.1',
     220                             'error': {'name': 'JSONRPCError',
     221                                       'code': code,
     222                                       'message': message
     223                                       }
     224                                 })
     225
     226class JSONRPCService:
     227    def __init__(self, method_map={}):
     228        self.method_map = method_map
     229
     230    def add_method(self, name, method):
     231        self.method_map[name] = method
     232
     233    def __call__(self, request, extra=None):
     234        # We do not yet support GET requests, something pyjamas does
     235        # not use anyways.
     236        data = simplejson.loads(request.raw_post_data)
     237        # Altered to forward the request parameter when a member method
     238        # is invocated <julien@pimentech.net>
     239        id, method, params = data["id"],data["method"],[request,]+data["params"]
     240        if method in self.method_map:
     241            try:
     242                result = self.method_map[method](*params)
     243                return response(id, result)
     244            except BaseException:
     245                etype, eval, etb = sys.exc_info()
     246                return error(id, 100, '%s: %s' %(etype.__name__, eval))
     247            except:
     248                etype, eval, etb = sys.exc_info()
     249                return error(id, 100, 'Exception %s: %s' %(etype, eval))
     250        else:
     251            return error(id, 100, 'method "%s" does not exist' % method)
     252
     253
     254def jsonremote(service):
     255    """Make JSONRPCService a decorator so that you can write :
     256   
     257    from jsonrpc import JSONRPCService
     258    chatservice = JSONRPCService()
     259
     260    @jsonremote(chatservice)
     261    def login(request, user_name):
     262        (...)
     263    """
     264    def remotify(func):
     265        if isinstance(service, JSONRPCService):
     266            service.add_method(func.__name__, func)
     267        else:
     268            emsg = 'Service "%s" not found' % str(service.__name__)
     269            raise NotImplementedError, emsg
     270        return func
     271    return remotify
     272
     273
     274}}}
Back to Top