forked from joshmarshall/jsonrpctcp
-
Notifications
You must be signed in to change notification settings - Fork 0
A Python TCP socket implementation of JSON-RPC (v2)
sancelot/jsonrpctcp
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
JSONRPCTCP ========== This project is just an implementation of the JSON-RPC protocol over TCP. It supports the JSON-RPC 2.0 specification, but it is not (at this point) backwards-compatible with 1.0, because I like 2.0 more. :) It also supports basic encryption and decryption via pycrypto if it is installed. Alternatively, you can wrap your own cipher class as long as it utilizes the 'new', 'encrypt', and 'decrypt' methods in the same manner as the Crypto.Cipher classes in the pycrypto library. It's early on, so feedback is greatly desired. You can hit the Google Groups site at http://groups.google.com/group/jsonrpctcp or email jsonrpctcp@googlegroups.com if you have any questions, advice, patches, or just need a friend. :) JSONRPCTCP is licensed under the Apache Licence, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html). Requirements ============ * Python 2.5+ * SimpleJSON on Python < 2.6 * PyCrypto (optional) for encryption support Installation ============ python setup.py build sudo python setup.py install Tests ===== The jsonrpctcp library contains nearly-verbatim tests from the JSON-RPC 2.0 Specification Document. (http://groups.google.com/group/json-rpc/web/json-rpc-2-0) After installation, or from the same directory as the setup.py file and this README, you can run the tests like so: python -m jsonrpctcp.tests If all is well, you should see 13ish tests that ran successfully. Additionally, you can spin up a test server in one terminal and run a few test client methods in another with the following instructions. (These tests are not as detailed, but it's there for whatever purpose.) Start server (hit Ctrl-C or Ctrl-Break in Windows to stop): python -m jsonrpctcp.server Start client in another terminal: python -m jsonrpctcp.client The client terminal should print out a short list of tests it performed. Usage Examples ============== Below, you'll find simple uses of both client and server. I'd love to hear feedback on the usability of this interface, and whether certain controls / attributes should be more accessible. Client Usage ============ This should be pretty familiar to users of xmlrpclib, with only a few name differences. The connect method takes the IP address / machine name, the port of the service, and an optional key if encryption is desired. Encryption requires the pycrypto library or a cipher-like class as the config.crypt value. See configuration info below for details. Client examples: # Simple example from jsonrpctcp import connect conn = connect('localhost', 8001) # Optionally, you can add a third string parameter which is the # encryption key used on the server. conn = connect('localhost', 8001, '12345abcdef67890') # Just use simple dot-syntax to call methods. Don't use a method # that starts with an underscore -- those are automatically private. result = conn.add(1, 2) # ...and should be 3. :) # Notification example -- it uses the '_notification' attribute # of the client connection to flag that this request doesn't need # a response. conn._notification.add(5, 6) # Null response, because it's a notification. It actually closes the # connection after submitting the full request. # Batch example -- it uses the '_batch' method of the client # connection to return a new, batch-enabled connection. It # automatically orders the reponses and skips notifications. batch = conn._batch() batch.add(y=5, x=6) batch._notification.add(6,4) batch.namespace.echo("Repeat me!") result = batch() for i in result: print i # Should print out 11, and then "Repeat me!", skipping the # notification. # You can access the request and response data with # history.request and history.response . These are the # string values after any encryption / decryption, so you'll # need to use a JSON library to decode them. from jsonrpctcp import history result = conn.sum(5, 6) print history.request >>> {"params": [5, 6], "jsonrpc": "2.0", "method": "sum", "id": "2fa1a919-5a14-44a8-bb52-af16757b12ee"} print history.response >>> {"jsonrpc": "2.0", "result": 11, "id": "2fa1a919-5a14-44a8-bb52-af16757b12ee"} # You can also see the responses via the logger: from jsonrpctcp import logger import logging logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler()) result = conn.sum(5, 6) # The following prints out: CLIENT | REQUEST: {"params": [5, 6], "jsonrpc": "2.0", "method": "sum", "id": "734941ad-bc30-4572-9e5f-e974fd04ef1c"} CLIENT | RESPONSE: {"jsonrpc": "2.0", "result": 11, "id": "734941ad-bc30-4572-9e5f-e974fd04ef1c"} Server Usage ============ The server is bound to a socket, and the handler function(s) can be passed in manually one by one, or (preferred) you can subclass the Handler object and use that. It threads (not forks) the individual requests for you, but if you don't use the start_server() shortcut, you'll have to thread the actual server startup yourself if you want to do anything after it starts. All you should need to enable encrypted support is pycrypto installed, and to set the config.secret to an appropriate key string. See below for config details. Server examples: # Function handler example from jsonrpctcp.server import Server from jsonrpctcp import config config.verbose = True def add(x, y): return x+y def echo(message): return message server = Server(('localhost', 8001)) server.add_handler(add) server.add_handler(echo, 'namespace.echo') server.serve() # blocks ------------------ # Class handler example from jsonrpctcp import start_server from jsonrpctcp.handler import Handler import time class NewHandler(Handler): def echo(self, message): return message # This automatically threads the server instance. server = start_server('localhost', 8001, NewHandler) while True: # Do whatever you need for polling time.sleep(5) # You'll have to thread the start up yourself this way, if you need it. Configuration ============= There's a simple configuration object that has a few attributes. You can change them per the following: from jsonrpctcp import config config.verbose = True # default is False config.timeout = 30 # default is 5 config.buffer = 4096 # default is 1024 config.crypt = DES3 # default is AES if pycrypto is installed config.secret = '12345abcdef67890' # default is none, 'secret' indicates that the server should # decrypt requests and encrypt responses. These may not be the best defaults, any thoughts would be appreciated. Debugging ========= If you want to see the actual requests, responses, etc. you'll need to add a handler and set a level to the jsonrpctcp logger. This uses the basic python logging module, so it should be fairly familiar: import loggging from jsonrpctcp import logger logger.addHandler(logging.StreamHandler()) # sends to stdout logger.setLevel(logging.DEBUG) TODO ==== * Replace threaded socket requests with epoll / select fallback. * Stabilize and get on PyPI. * Add more unit tests. * Generally make more awesome.
About
A Python TCP socket implementation of JSON-RPC (v2)
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published
Languages
- Python 100.0%