Remote RPC over HTTP for python (v0.1.2) - With remote exceptions support
Setup:
pip install remotipy
In module data.dto (example) describe the transfer objects (DTO):
@serializable
class UserInfo(object):
def __init__(self, params={}):
self.first_name = params.get('first_name')
self.last_name = params.get('last_name')
self.email = params.get('email')
@serializable
class Result(object):
def __init__(self, msg = None):
self.message = msg
Note: share this file both on the client and the server
Use the decorator @remote to specify the rest endpoint and the module containing the models:
from data import models
@remote("http://localhost:5000/method_dispatcher", models)
class RemoteController(object):
def my_remote_method(self, user):
pass
Note: @remote supports custom HTTP headers using this format:
@remote("http://localhost:5000/method_dispatcher", data.models, headers={
'X-Authentication-token': TokenGenerator.generate({'key': 123456789})
})
Implement the actual logic
class Controller(object):
def my_remote_method(self, user):
# all your logic here
return Result(user.email + ' DONE!')
You can use any python rest server to dispatch the body of the request to the invoked method. In this example we are using the Flask format.
@app.route('/method_dispatcher', methods=['POST'])
def query():
# check http header, cookies, etc
# dispatch format: controller_class, models_module, raw_body
result = rpc.dispatch(Controller, models, request.get_data())
return response(result)
Note: the function response is required to serialize back the response
On the client now you can call:
result = Controller().my_remote_method(user)
Just check the tests
module for different test cases.
The constructor def __init__(self, [ params={}, ... ] )
of the serializable objects (step 1) MUST support the empty call.
- How can I handle a remote exception?
Remote exception are raised on the client side with type
remotipy.rpc.RemoteException
and you have access to the original message (.message
) and the original class name (.cls
) - I get
MethodNotFound: <my_remote_method>
. Why? Check the interface on the client side and the implementation on the server side have the same methods signatures: steps 2/3. (You could even copy same file on the client because the methods body is ignored) - I'm using App Engine and I get
TypeError('expected httplib.Message)
. Why? This is a known issue of urllib3&Python 2.7, to fix this go in<lib_dir_>/urllib3/util/response.py
and remove from line 47 to 49.