Skip to main content

WSGI Framework for JSON RPC 2.0

Project description

.. -*- restructuredtext -*-

.. image:: https://drone.io/bitbucket.org/aodag/jsonrpc2/status.png
:target: https://drone.io/bitbucket.org/aodag/jsonrpc2/latest

jsonrpc2 is WSGI Framework for JSON RPC 2.0.

JSON RPC 2.0 Spec can be seen on http://www.jsonrpc.org/specification .

.. contents::

QuickStart
==========================================

install via pip::

$ pip install jsonrpc2

write your procedures in hello.py::

def greeting(name):
return dict(message="Hello, %s!" % name)

run jsonrpc2 server::

$ runjsonrpc2 hello


Integration with Paste Script
===============================================

create project with paste script template::

$ paster create -t paster_jsonrpc2 myrpc
$ cd myrpc

run server

$ paster serve run.ini

access http://localhost:8080/


Internal
===============================

::

>>> import json
>>> from jsonrpc2 import JsonRpcApplication

sample procedure::

>>> def greeting(name="world"):
... return "Hello, %s!" % name

create rpc application::

>>> app = JsonRpcApplication(rpcs=dict(greeting=greeting))

set up for test::

>>> from webtest import TestApp
>>> testapp = TestApp(app)

call procedure::

>>> call_values = {'jsonrpc':'2.0', 'method':'greeting', 'id':'greeting'}
>>> res = testapp.post('/', params=json.dumps(call_values), content_type="application/json")

got results::

>>> res.json
{u'jsonrpc': u'2.0', u'id': u'greeting', u'result': u'Hello, world!'}


lazy loading::

>>> app.rpc.methods['sample.add'] = 'tests.sample:add'
>>> call_values = {'jsonrpc':'2.0', 'method':'sample.add', 'id':'sample.add', 'params':[1, 2]}
>>> res = testapp.post('/', params=json.dumps(call_values), content_type="application/json")
>>> res.json
{u'jsonrpc': u'2.0', u'id': u'sample.add', u'result': 3}


extra vars
==================

::

>>> from jsonrpc2 import JsonRpc
>>> rpc = JsonRpc()
>>> rpc['add'] = lambda a, b: a + b
>>> rpc({'jsonrpc': '2.0', 'method': 'add', 'id': 'rpc-1', 'params': {'a': 2}}, b=3)
{'jsonrpc': '2.0', 'id': 'rpc-1', 'result': 5}

handle errors
=================

::

>>> from jsonrpc2 import JsonRpc
>>> class MyException(Exception):
... pass
>>> def my_rpc():
... raise MyException()
>>> rpc = JsonRpc({'call': my_rpc}, {MyException: -32001})
>>> rpc({'jsonrpc': '2.0', 'method': 'call', 'id': 'rpc-1', 'params': []})
{'jsonrpc': '2.0', 'id': 'rpc-1', 'error': {'message': '', 'code': -32001, 'data': '[]'}}


JSON-RPC2 Example
=====================================================

use raw rpc processor::

>>> from jsonrpc2 import JsonRpc
>>> rpc = JsonRpc()

sample procedures::

>>> def subtract(minuend, subtrahend):
... return minuend - subtrahend
>>> def update(*args):
... pass
>>> def foobar():
... pass

register procedures with dict interface::

>>> rpc['subtract'] = subtract
>>> rpc['update'] = update
>>> rpc['foobar'] = foobar

Procedure Call with positional parameters::

>>> rpc({"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1})
{'jsonrpc': '2.0', 'id': 1, 'result': 19}

>>> rpc({"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2})
{'jsonrpc': '2.0', 'id': 2, 'result': -19}

Procedure Call with named parameters::

>>> rpc({"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3})
{'jsonrpc': '2.0', 'id': 3, 'result': 19}

>>> rpc({"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4})
{'jsonrpc': '2.0', 'id': 4, 'result': 19}

Notification::

>>> rpc({"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]})
>>> rpc({"jsonrpc": "2.0", "method": "foobar"})

Procedure Call of non-existent procedure::

>>> del rpc['foobar']
>>> rpc({"jsonrpc": "2.0", "method": "foobar", "id": "1"})
{'jsonrpc': '2.0', 'id': '1', 'error': {'message': 'Method Not Found', 'code': -32601}}

Procedure Call with invalid JSON-RPC::

>>> rpc([1,2,3])
{'jsonrpc': '2.0', 'id': None, 'error': {'message': 'Invalid Request', 'code': -32600}}

>>> rpc({"jsonrpc": "2.0", "method": 1, "params": "bar"})
{'jsonrpc': '2.0', 'id': None, 'error': {'message': 'Invalid Request', 'code': -32600}}


Batched Call::

>>> rpc['sum'] = lambda *args: reduce(lambda a, b: a + b, args)
>>> def get_data():
... return ["hello", 5]
>>> rpc['get_data'] = get_data
>>> result = rpc ([ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
... {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
... {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
... {"foo": "boo"},
... {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
... {"jsonrpc": "2.0", "method": "get_data", "id": "9"} ])
>>> from pprint import pprint
>>> pprint(result)
[{'id': '1', 'jsonrpc': '2.0', 'result': 7},
{'error': {'code': -32601, 'message': 'Method Not Found'},
'id': None,
'jsonrpc': '2.0'},
{'id': '2', 'jsonrpc': '2.0', 'result': 19},
{'error': {'code': -32600, 'message': 'Invalid Request'},
'id': None,
'jsonrpc': '2.0'},
{'error': {'code': -32601, 'message': 'Method Not Found'},
'id': '5',
'jsonrpc': '2.0'},
{'id': '9', 'jsonrpc': '2.0', 'result': ['hello', 5]}]



ChangeLog
===================================================

0.4
-----------------------------------------------
feature

- added supporting py3
- added registering application errors

fixed bugs

- Dont raise internal error for server exceptions `#13 <https://bitbucket.org/aodag/jsonrpc2/issue/13/dont-raise-internal-error-for-server>`_
- incorrect Content-type `#15 https://bitbucket.org/aodag/jsonrpc2/issue/15/incorrect-content-type`_
- internal logging configuration broken `#16 <https://bitbucket.org/aodag/jsonrpc2/issue/16/internal-logging-configuration-broken>`_

0.3
-----------------------------------------------

- fix bugs
- Paste Scripte templates
- runjsonrpc2 command

0.3.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- fix bugs (content-type with charset)

0.3.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- enable to pass the extra vars to procedures

0.2
-----------------------------------------------

- remove dependency to WebOb
- split procedure call class from web application class

0.2.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- lazy loading from method name.

0.2.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- add dict interface.

0.2.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- fix: read body with CONTENT_LENGTH.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jsonrpc2-0.4.tar.gz (15.2 kB view details)

Uploaded Source

Built Distribution

jsonrpc2-0.4-py2.py3-none-any.whl (20.1 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file jsonrpc2-0.4.tar.gz.

File metadata

  • Download URL: jsonrpc2-0.4.tar.gz
  • Upload date:
  • Size: 15.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for jsonrpc2-0.4.tar.gz
Algorithm Hash digest
SHA256 45b774e06f4e91885f9340cc7c0a33542bf86eec74d796689fcafbed5f63716f
MD5 f3d7eb7bcb6dc7fc5c14821198b44af7
BLAKE2b-256 3623d4d0c2af6c8abe9560195b2833dfd5d64aca7483ce84826e8cd6d6db3c06

See more details on using hashes here.

File details

Details for the file jsonrpc2-0.4-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for jsonrpc2-0.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 843068e8d64a8395383159822faa49a7d7e8cbb196133746ef2ce06b1ad51adf
MD5 3ab3841c33711002446ef8828736a4a8
BLAKE2b-256 397409e920fb8bc732d3e6283af086092707296b0f9faf1d8516a3d40413c771

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page