JSON-RPC¶
pyramid_rpc
supports
JSON-RPC 2.0 Specification .
from pyramid.config import Configurator
from pyramid_rpc.jsonrpc import jsonrpc_method
@jsonrpc_method(endpoint='api')
def say_hello(request, name):
return 'hello, %s!' % name
def main(global_conf, **settings):
config = Configurator(settings=settings)
config.include('pyramid_rpc.jsonrpc')
config.add_jsonrpc_endpoint('api', '/api')
config.scan(__name__)
return config.make_wsgi_app()
if __name__ == '__main__':
from paste.httpserver import serve
app = main({})
serve(app, 'localhost', 8080)
Setup¶
Use the includeme
via pyramid.config.Configurator.include()
:
config.include('pyramid_rpc.jsonrpc')
Once activated, the following happens:
- The
pyramid_rpc.jsonrpc.add_jsonrpc_endpoint()
directive is added to theconfig
instance. - The
pyramid_rpc.jsonrpc.add_jsonrpc_method()
directive is added to theconfig
instance. - An exception view is registered for
pyramid_rpc.jsonrpc.JsonRpcError
exceptions.
Usage¶
After including the pyramid_rpc.jsonrpc
package in your project, you can
add an endpoint for handling incoming requests. After that, attach
several methods to the endpoint to handle specific functions within your api.
Adding a JSON-RPC Endpoint¶
An endpoint is added via the
add_jsonrpc_endpoint()
directive on the
config
instance.
Example:
config = Configurator()
config.include('pyramid_rpc.jsonrpc')
config.add_jsonrpc_endpoint('api', '/api/jsonrpc')
It is possible to add multiple endpoints as well as pass extra arguments to
add_jsonrpc_endpoint()
to handle traversal, which
can assist in adding security to your RPC API.
Exposing JSON-RPC Methods¶
Methods on your API are exposed by attaching views to an endpoint.
Methods may be attached via the
add_jsonrpc_method()
which is a thin wrapper
around pyramid.config.Configurator.add_view()
method.
Example:
def say_hello(request, name):
return 'Hello, ' + name
config.add_jsonrpc_method(say_hello, endpoint='api', method='say_hello')
If you prefer, you can use the jsonrpc_method()
view decorator to declare your methods closer to your actual code.
Remember when using this lazy configuration technique, it's always necessary
to call pyramid.config.Configurator.scan()
from within your setup code.
from pyramid_rpc.jsonrpc import jsonrpc_method
@jsonrpc_method(endpoint='api')
def say_hello(request, name):
return 'Hello, ' + name
config.scan()
To set the RPC method to something other than the name of the view, specify
the method
parameter:
from pyramid_rpc.jsonrpc import jsonrpc_method
@jsonrpc_method(method='say_hello', endpoint='api')
def say_hello_view(request, name):
return 'Hello, ' + name
config.scan()
Because methods are a thin layer around Pyramid's views, it is possible to add
extra view predicates to the method, as well as permission
requirements.
Custom Renderers¶
By default, responses are rendered using the Python standard library's
json.dumps()
. This can be changed the same way any renderer is
changed in Pyramid. See the Pyramid Renderers
chapter for extra details. As an example, let's update an endpoint to
use Pyramid 1.4's cool new pyramid.renderers.JSON
renderer which
supports custom adapters.
from pyramid.renderers import JSON
json_renderer = JSON()
json_renderer.add_adapter(datetime.datetime, lambda v, request: v.isoformat())
config.add_renderer('myjson', json_renderer)
config.add_jsonrpc_endpoint('api', '/api', default_renderer='myjson')
A default_renderer
can be specified on an endpoint, which will
propagate to all methods attached to the endpoint. Optionally, an individual
method can also override the renderer.
View Mappers¶
A view mapper is registered for JSON-RPC methods by default which will
match the arguments from request.rpc_args
to the parameters of the
view. Optional arguments are allowed and an error will be returned if too
many or too few arguments are supplied to the view.
This default view mapper may be overridden by setting the
default_mapper
option on add_jsonrpc_endpoint()
or the mapper
option when using jsonrpc_method()
or add_jsonrpc_method()
.
HTTP GET and POST Support¶
As of pyramid_rpc
version 0.5, JSON-RPC requests can be made using
HTTP GET. By default, an endpoint will accept requests from both GET
and POST
methods. This can be controlled on either the endpoint
or on an individual method by using the request_method
predicate. For
example, to limit requests to only POST
requests:
config.add_jsonrpc_endpoint('api', '/api', request_method='POST')
Handling JSONP Requests¶
Pyramid comes with a pyramid.renderers.JSONP
which can be registered
for the endpoint, using the method described within
Custom Renderers.
API¶
-
includeme
(config)[source]¶ Set up standard configurator registrations. Use via:
config = Configurator() config.include('pyramid_rpc.jsonrpc')
Once this function has been invoked, two new directives will be available on the configurator:
add_jsonrpc_endpoint
: Add an endpoint for handling JSON-RPC.add_jsonrpc_method
: Add a method to a JSON-RPC endpoint.
-
add_jsonrpc_endpoint
(config, name, *args, **kw)[source]¶ Add an endpoint for handling JSON-RPC.
name
The name of the endpoint.default_mapper
A default view mapper that will be passed as themapper
argument to each of the endpoint's methods.default_renderer
A default renderer that will be passed as therenderer
argument to each of the endpoint's methods. This should be the string name of the renderer, registered viapyramid.config.Configurator.add_renderer()
.A JSON-RPC method also accepts all of the arguments supplied to
pyramid.config.Configurator.add_route()
.
-
add_jsonrpc_method
(config, view, **kw)[source]¶ Add a method to a JSON-RPC endpoint.
endpoint
The name of the endpoint.method
The name of the method.A JSON-RPC method also accepts all of the arguments supplied to
pyramid.config.Configurator.add_view()
.A view mapper is registered by default which will match the
request.rpc_args
to parameters on the view. To override this behavior simply set themapper
argument to None or another view mapper.Note
An endpoint must be defined before methods may be added.
-
jsonrpc_method
(method=None, **kw)[source]¶ This decorator may be used with pyramid view callables to enable them to respond to JSON-RPC method calls.
If
method
is not supplied, then the callable name will be used for the method name._depth
may be specified when wrappingjsonrpc_method
in another decorator. The value should reflect how many stack frames are between the wrapped target andjsonrpc_method
. Thus a decorator one level deep would pass in_depth=1
.This is the lazy analog to the
add_jsonrpc_method`()
and accepts all of the same arguments.