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.
.. 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
Release history Release notifications | RSS feed
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)
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 45b774e06f4e91885f9340cc7c0a33542bf86eec74d796689fcafbed5f63716f |
|
MD5 | f3d7eb7bcb6dc7fc5c14821198b44af7 |
|
BLAKE2b-256 | 3623d4d0c2af6c8abe9560195b2833dfd5d64aca7483ce84826e8cd6d6db3c06 |
File details
Details for the file jsonrpc2-0.4-py2.py3-none-any.whl
.
File metadata
- Download URL: jsonrpc2-0.4-py2.py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 843068e8d64a8395383159822faa49a7d7e8cbb196133746ef2ce06b1ad51adf |
|
MD5 | 3ab3841c33711002446ef8828736a4a8 |
|
BLAKE2b-256 | 397409e920fb8bc732d3e6283af086092707296b0f9faf1d8516a3d40413c771 |