Loading README.md +84 −11 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ This repo contains the implementation of the *RSVP (Request-and-Stream Variable Protocol)* for python. The general protocol is described in more details [here][1]. ## Dependencies | | | Loading @@ -16,36 +18,107 @@ poetry install ## Quick start Here is an example of how to create a RSVP server running on TCP: ### Server ```py from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp Here is an example of how to create a RSVP server running on TCP. The basic idea is to create an instance of the RsvpServer and add command callback functions that will be called when a specific command is received. ```py #Define commands and their callbacks # @RsvpServer.Command("EXCEPTION") def handle_exception(ex : Exception) -> str: error =f"{type(ex).__name__} {ex}" try: raise ex except Exception as ex: print(f"{type(ex).__name__}: {ex}") return RsvpServer.reply(False, [RsvpString("ERROR", error)]) @RsvpServer.Command("START") def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: def start(values : dict) -> str: print(values) return RsvpServer.reply(True, [RsvpInteger("CODE", 1)]) print(f"a: {a}, b: {b}, c: {c}, d: {d}, e: {e}, f: {f}") return f"REPLY-START=ACK;STATUS=PASS" if __name__ == "__main__": srv = RsvpServerTcp() srv = RsvpServerTcp("", port) srv.run() ``` The main idea is to use the decorator to add callback based on command names to your server To add a command put decorator above your function. All the function will get a dict containing the arguments sent by the client. ```py @RsvpServer.Command(<COMMAND_NAME>) def function(args : dict) ``` Each callback will receive the user defined arguments and each callback must return a reply string in the form Each callback must return a reply string using the following function ```py return f"REPLY-<COMMAND_NAME>=ACK|NACK;ARGS|ERROR" return RsvpServer.reply(ack : bool, args : list[RsvpBaseType]) ``` The general protocol is described in more details [here][1]. There is only one callback predefined with and it's called *"EXCEPTION"* it called if an exception is raised during the processing of the data. If this command is not defined the exception will be raises. ### Client The client can be used to exchange data with the server. ```py def start_cb(args : list): print(args) if __name__ == "__main__": client = RsvpClientTcp() args = [ RsvpInteger("ARG1", 1), RsvpDouble("ARG2", 2.0), ] try: print(client.send_command("START", args, callback=start_cb)) except Exception as ex: print(f"[{type(ex).__name__}] Error: {ex}") ``` A method called send data is available to send data to the server: ```py client.send_command(cmd_name: str, args: list[svpBaseType], function = None) ``` The function take the command name as a string, a list containing the arguments as RsvpBaseType and an optional callback function that will be called when the server answer. If the callback is not defined the function will return received data as a list. ### RsvpType classes To mitigate errors we encourage the use of the special types for arguments. Available types are: ```py RsvpInteger(name: str, value : int) RsvpDouble(name: str, value : float) RsvpBool(name: str value : bool) RsvpString(name: str, value: str) RsvpVectorDouble(name: str, value: dict[str, float]) RsvpVectorString(name: str, value: list[str]) ``` All type are checked when creating a new object and it will raise an *RsvpWrongTypeException* exception the *value* parameter is not of the correct type. ## Usage examples Loading examples/tcpserver.py +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp from pyrsvp.rsvptypes import * import argparse #Define commands and their callbacks # @RsvpServer.Command("EXCEPTION") def handle_exception(ex : Exception) -> str: Loading @@ -14,7 +16,6 @@ def handle_exception(ex : Exception) -> str: return RsvpServer.reply(False, [RsvpString("ERROR", error)]) #Define commands and their callbacks @RsvpServer.Command("START") def start(values : dict) -> str: Loading pyrsvp/rsvpserver.py +0 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ class RsvpServerTcp(RsvpServer): try: buf = self.server.socket.recv(1, socket.MSG_PEEK | socket.MSG_DONTWAIT) if buf == b'': print("Hello") continue except Exception as ex: print(ex) Loading Loading
README.md +84 −11 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ This repo contains the implementation of the *RSVP (Request-and-Stream Variable Protocol)* for python. The general protocol is described in more details [here][1]. ## Dependencies | | | Loading @@ -16,36 +18,107 @@ poetry install ## Quick start Here is an example of how to create a RSVP server running on TCP: ### Server ```py from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp Here is an example of how to create a RSVP server running on TCP. The basic idea is to create an instance of the RsvpServer and add command callback functions that will be called when a specific command is received. ```py #Define commands and their callbacks # @RsvpServer.Command("EXCEPTION") def handle_exception(ex : Exception) -> str: error =f"{type(ex).__name__} {ex}" try: raise ex except Exception as ex: print(f"{type(ex).__name__}: {ex}") return RsvpServer.reply(False, [RsvpString("ERROR", error)]) @RsvpServer.Command("START") def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: def start(values : dict) -> str: print(values) return RsvpServer.reply(True, [RsvpInteger("CODE", 1)]) print(f"a: {a}, b: {b}, c: {c}, d: {d}, e: {e}, f: {f}") return f"REPLY-START=ACK;STATUS=PASS" if __name__ == "__main__": srv = RsvpServerTcp() srv = RsvpServerTcp("", port) srv.run() ``` The main idea is to use the decorator to add callback based on command names to your server To add a command put decorator above your function. All the function will get a dict containing the arguments sent by the client. ```py @RsvpServer.Command(<COMMAND_NAME>) def function(args : dict) ``` Each callback will receive the user defined arguments and each callback must return a reply string in the form Each callback must return a reply string using the following function ```py return f"REPLY-<COMMAND_NAME>=ACK|NACK;ARGS|ERROR" return RsvpServer.reply(ack : bool, args : list[RsvpBaseType]) ``` The general protocol is described in more details [here][1]. There is only one callback predefined with and it's called *"EXCEPTION"* it called if an exception is raised during the processing of the data. If this command is not defined the exception will be raises. ### Client The client can be used to exchange data with the server. ```py def start_cb(args : list): print(args) if __name__ == "__main__": client = RsvpClientTcp() args = [ RsvpInteger("ARG1", 1), RsvpDouble("ARG2", 2.0), ] try: print(client.send_command("START", args, callback=start_cb)) except Exception as ex: print(f"[{type(ex).__name__}] Error: {ex}") ``` A method called send data is available to send data to the server: ```py client.send_command(cmd_name: str, args: list[svpBaseType], function = None) ``` The function take the command name as a string, a list containing the arguments as RsvpBaseType and an optional callback function that will be called when the server answer. If the callback is not defined the function will return received data as a list. ### RsvpType classes To mitigate errors we encourage the use of the special types for arguments. Available types are: ```py RsvpInteger(name: str, value : int) RsvpDouble(name: str, value : float) RsvpBool(name: str value : bool) RsvpString(name: str, value: str) RsvpVectorDouble(name: str, value: dict[str, float]) RsvpVectorString(name: str, value: list[str]) ``` All type are checked when creating a new object and it will raise an *RsvpWrongTypeException* exception the *value* parameter is not of the correct type. ## Usage examples Loading
examples/tcpserver.py +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp from pyrsvp.rsvptypes import * import argparse #Define commands and their callbacks # @RsvpServer.Command("EXCEPTION") def handle_exception(ex : Exception) -> str: Loading @@ -14,7 +16,6 @@ def handle_exception(ex : Exception) -> str: return RsvpServer.reply(False, [RsvpString("ERROR", error)]) #Define commands and their callbacks @RsvpServer.Command("START") def start(values : dict) -> str: Loading
pyrsvp/rsvpserver.py +0 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ class RsvpServerTcp(RsvpServer): try: buf = self.server.socket.recv(1, socket.MSG_PEEK | socket.MSG_DONTWAIT) if buf == b'': print("Hello") continue except Exception as ex: print(ex) Loading