def _send_string_message(cmd : str, recv_binary : bool=False, args : str=None) -> Union[str, memoryview]: """ Generates a RequestMessage encapsulating command and requesting user information, sends it to the Arkouda server, and returns either a string or binary depending upon the message format. Parameters ---------- cmd : str The name of the command to be executed by the Arkouda server recv_binary : bool, defaults to False Indicates if the return message will be a string or binary data args : str A delimited string containing 1..n command arguments Returns ------- Union[str,memoryview] The response string or binary data sent back from the Arkouda server Raises ------ RuntimeError Raised if the return message contains the word "Error", indicating a server-side error was thrown ValueError Raised if the return message is malformed JSON or is missing 1..n expected fields """ message = RequestMessage(user=username, token=token, cmd=cmd, format=MessageFormat.STRING, args=args) logger.debug('sending message {}'.format(message)) socket.send_string(json.dumps(message.asdict())) if recv_binary: frame = socket.recv(copy=False) view = frame.buffer # raise errors sent back from the server if bytes(view[0:len(b"Error:")]) == b"Error:": raise RuntimeError(frame.bytes.decode()) return view else: raw_message = socket.recv_string() try: return_message = ReplyMessage.fromdict(json.loads(raw_message)) # raise errors or warnings sent back from the server if return_message.msgType == MessageType.ERROR: raise RuntimeError(return_message.msg) elif return_message.msgType == MessageType.WARNING: warnings.warn(return_message.msg) return return_message.msg except KeyError as ke: raise ValueError('Return message is missing the {} field'.format(ke)) except json.decoder.JSONDecodeError: raise ValueError('Return message is not valid JSON: {}'.\ format(raw_message))
def testReplyMessage(self): msg = ReplyMessage(msg='normal result', msgType=MessageType.NORMAL, user='******') msgDupe = ReplyMessage(msg='normal result', msgType=MessageType.NORMAL, user='******') msgNonDupe = ReplyMessage(msg='normal result 2', msgType=MessageType.NORMAL, user='******') self.assertEqual(msg, msgDupe) self.assertNotEqual(msg, msgNonDupe) self.assertEqual( "ReplyMessage(msg='normal result', msgType=NORMAL, user='******')", str(msg)) self.assertEqual( "ReplyMessage(msg='normal result', msgType=NORMAL, user='******')", repr(msg)) newMsg = ReplyMessage.fromdict({ 'msg': 'normal result', 'msgType': 'NORMAL', 'user': '******' }) self.assertEqual(msg, newMsg) self.assertEqual( "ReplyMessage(msg='normal result', msgType=NORMAL, user='******')", str(newMsg)) self.assertEqual( "ReplyMessage(msg='normal result', msgType=NORMAL, user='******')", repr(newMsg)) with self.assertRaises(ValueError): ReplyMessage.fromdict({ 'msg': 'normal result', 'msgType': 'NORMAL' })
def _send_binary_message(cmd : str, payload : bytes, recv_bytes : bool=False, args : str=None) -> Union[str, bytes]: """ Generates a RequestMessage encapsulating command and requesting user information, information prepends the binary payload, sends the binary request to the Arkouda server, and returns either a string or binary depending upon the message format. Parameters ---------- cmd : str The name of the command to be executed by the Arkouda server payload : bytes The bytes to be converted to a pdarray, Strings, or Categorical object on the Arkouda server recv_bytes : bool, defaults to False A boolean indicating whether the return message will be in bytes as opposed to a string args : str A delimited string containing 1..n command arguments Returns ------- Union[str,bytes] The response string or byte array sent back from the Arkouda server Raises ------ RuntimeError Raised if the return message contains the word "Error", indicating a server-side error was thrown ValueError Raised if the return message is malformed JSON or is missing 1..n expected fields """ message = RequestMessage(user=username, token=token, cmd=cmd, format=MessageFormat.BINARY, args=cast(str,args)) logger.debug('sending message {}'.format(message)) socket.send('{}BINARY_PAYLOAD'.\ format(json.dumps(message.asdict())).encode() + payload) if recv_bytes: binary_return_message = cast(bytes, socket.recv()) # raise errors or warnings sent back from the server if binary_return_message.startswith(b"Error:"): \ raise RuntimeError(binary_return_message.decode()) elif binary_return_message.startswith(b"Warning:"): \ warnings.warn(binary_return_message.decode()) return binary_return_message else: raw_message = socket.recv_string() try: return_message = ReplyMessage.fromdict(json.loads(raw_message)) # raise errors or warnings sent back from the server if return_message.msgType == MessageType.ERROR: raise RuntimeError(return_message.msg) elif return_message.msgType == MessageType.WARNING: warnings.warn(return_message.msg) return return_message.msg except KeyError as ke: raise ValueError('Return message is missing the {} field'.format(ke)) except json.decoder.JSONDecodeError: raise ValueError('{} is not valid JSON, may be server-side error'.\ format(raw_message))