Package: damn-simple-jsonrpc-server
JSON-RPC Server for PythonThis is damn simple, framework-agnostic JSON-RPC v2.0 server for Python.This package has no dependencies.You can build service API without thinking about any framework nor toolkit, and even without thinking about HTTP itself.
This package is an implementation of JSON-RPC protocol only, following rules described onhttp://www.jsonrpc.org/specificationWhat is JSON-RPC?JSON-RPC is a protocor similar to XML-RPC, but simpler and very lightweight.
There is no necessary to generate nor parse XML documents by using heavy librariers.You can build easily remote services and call them using clients implemented in many languages.
JSON-RPC services are always exposed using HTTP(S) protocol.For more information please read JSON-RPC v2.0 specification:http://www.jsonrpc.org/specificationGetting startedInstallationUsesetuptoolsorpip:easy_install damn-simple-jsonrpc-serverorpip install damn-simple-jsonrpc-serverCalculator service exampleLet's make calculator service which supportsaddandsubtractoperations.(calculator_service.py)importjsonrpcserverasrpccalculator=rpc.Service()@calculator.methoddefadd(x,y):returnx+y@calculator.method('subtract')defsub(x,y):returnx-yWell... it's done. But where it is accessible? Nowhere!
You can access it directly bycalculatorvariable, but this is nonsense.
This is an API for HTTP adapters, but not for humans.Exposing JSON-RPC service via HTTPSimplest way to exposecalculatorservice is to use well-known HTTP framework.
It may be a Django, for example:(urls.py)fromdjango.conf.urlsimportpatterns,include,urlfrom.calculator_serviceimportcalculatordefcalculator_service_view(request):returncalculator.handle_request_body(request.body)urlpatterns=patterns('',url(r'^$',calculator_service_view,name='calculator'),)But there is a simpler way! :)Using existing adaptorsIf you need quickly expose your service using Django, just usedamn simple JSON-RPC Django adaptor,
which contains ready to use adaptor:(urls.py)fromdjango.conf.urlsimportpatterns,include,urlfromcalculator_serviceimportcalculatorurlpatterns=patterns('',url(r'^$','jsonrpcdjango.serve',kwargs={'service':calculator},name='calculator'),)That's all. Nothing more, nothing less!Writing custom adaptorsJSON-RPCServiceclass has very simple API based on str/unicode or request-like object.
You may use one of the following methods available inServiceclass:handle_request_bodyhandle_http_requestThehandle_request_bodymethod expects that input string will be a representation of a JSON-RPC Request object.Thehandle_http_requestmethod expects that request-like object will be passed as an argument.
In that case request-like objectmustcontainbodyattribute with string representation
of JSON-RPC request.Return value ofhandle_request_bodyandhandle_http_requestis always a str/unicode
with a JSON-RPC Response object representation (success and error responses are returned
same way, as described inhttp://www.jsonrpc.org/specification, but will containresultanderrorkeys respectively).Authentication, CSRF, other stuff...Authentication and CSRF are HTTP-related topics.
You may implement them in adaptors or just use tools from your favourite HTTP framework.
For Django framework you may simply decorate whole service:(urls.py)importjsonrpcdjangoasrpc[...]urlpatterns=patterns('',url(r'^$',login_required(rpc.serve),kwargs={'service':calculator},name='calculator'),To enable or disable CSRF just use specific adaptor:jsonrpcdjango.servefor CSRF-less handlerjsonrpcdjango.csrf_servefor CSRF-protected handleror use disrectly Django's decoratorscsrf_exempt,csrf_protector enableCsrfViewMiddleware(readhttps://docs.djangoproject.com/en/dev/ref/csrf/for details)Currently there is no possibility to decorate specific methods of the service withjsonrpcdjangoadaptor.AuthorizationIf you want add authorization to your method you should use similar solution as for authentication.
For Django framework you may simply decorate whole service:(urls.py)importjsonrpcdjangoasrpc[...]urlpatterns=patterns('',url(r'^$',permission_required('can_use_rpc')(rpc.serve),kwargs={'service':calculator},name='calculator'),Currently there is no possibility to decorate specific methods of the service withjsonrpcdjangoadaptor.Accessing original HTTP request inside service methodsSometimes you may need access to specific request data added somewhere
in middleware stack. In that case you can register JSON-RPC method with
additional argumenttakes_http_request=True. Originalrequestobject
will be passed as first argument.If you're using Django as an HTTP framework andjsonrpcdjangoadaptor,
you can provide access to Django'sHttpRequestobject inside service method
without any hacks. Just declaretakes_http_request=Trueat registering
time. This will make your service dependend on Django, but will add more flexibility.(calculator_service.py)calculator=rpc.Service()[...]@calculator.method(takes_http_request=True)defbeast_add(request,x,y):ifrequest.user.is_superuser:returnx+yelse:return666