diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-12-05 11:19:07 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-12-05 11:19:07 +0100 |
commit | 31b65e41043900c0cadd80961f4b22cdfc171e7d (patch) | |
tree | cdeceac026a2d1e0fe8c00af5d0f867767d17ef4 /python/lib/yamlrpc.py | |
parent | 5cf52c74e9eb6bf8a82af4509ff3eb5106f928f9 (diff) | |
download | dabmod-31b65e41043900c0cadd80961f4b22cdfc171e7d.tar.gz dabmod-31b65e41043900c0cadd80961f4b22cdfc171e7d.tar.bz2 dabmod-31b65e41043900c0cadd80961f4b22cdfc171e7d.zip |
Get GUI to communicate with DPDCE
Diffstat (limited to 'python/lib/yamlrpc.py')
-rw-r--r-- | python/lib/yamlrpc.py | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/python/lib/yamlrpc.py b/python/lib/yamlrpc.py index bd61569..d963601 100644 --- a/python/lib/yamlrpc.py +++ b/python/lib/yamlrpc.py @@ -30,6 +30,11 @@ import yaml import socket import struct +class ResponseError(Exception): + """The response contains an error""" + def __init__(self, message): + self.message = message + def request(request_id: int, method: str, params) -> bytes: r = { 'yamlrpc': YAMLRPC_VERSION, @@ -42,14 +47,12 @@ def response_success(request_id: int, result) -> bytes: r = { 'yamlrpc': YAMLRPC_VERSION, 'result': result, - 'error': None, 'id': request_id} return yaml.dump(r).encode() def response_error(request_id: int, error) -> bytes: r = { 'yamlrpc': YAMLRPC_VERSION, - 'result': None, 'error': error, 'id': request_id} return yaml.dump(r).encode() @@ -66,9 +69,58 @@ class Socket: self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) if bind_port > 0: self.socket.bind(('127.0.0.1', bind_port)) + self.socket.settimeout(3) + self._last_request_id = 0 + + def send_request(self, dest_port: int, method: str, params) -> int: + addr = ("127.0.0.1", dest_port) + self._last_request_id += 1 + self.socket.sendto(request(self._last_request_id, method, params), addr) + return self._last_request_id + + def receive_response(self, expected_msg_id: int): + try: + data, addr = self.socket.recvfrom(512) + except socket.timeout as to: + raise TimeoutError("Timeout: " + str(to)) + + y = yaml.load(data.decode()) + + if 'yamlrpc' not in y: + raise ValueError("Message is not yamlrpc") + if y['yamlrpc'] != YAMLRPC_VERSION: + raise ValueError("Invalid yamlrpc version") + + # expect a response, with either 'error' or 'result' non-null + try: + msg_id = y['id'] + except KeyError: + raise ValueError("Response is missing id") + + if msg_id != expected_msg_id: + raise ValueError("Response id does not match request") + + try: + result = y['result'] + except KeyError: + try: + error = y['error'] + raise ResponseError(error) + except KeyError: + raise ValueError("response is null") + return result + + def call_rpc_method(self, dest_port: int, method: str, params): + msg_id = self.send_request(dest_port, method, params) + return self.receive_response(msg_id) + def receive_request(self): - data, addr = self.socket.recvfrom(512) + try: + data, addr = self.socket.recvfrom(512) + except socket.timeout as to: + raise TimeoutError("Timeout: " + str(to)) + y = yaml.load(data.decode()) if 'yamlrpc' not in y: |