Loading .gitignore 0 → 100644 +4 −0 Original line number Diff line number Diff line # Python stuff __pycache__/ .pytest_cache/ No newline at end of file README.md +61 −0 Original line number Diff line number Diff line # RSVP python This repo contains the implementation of the *RSVP (Request-and-Stream Variable Protocol)* for python. ## Dependencies | | | |-|-| | Poetry | >= 1.2.0 | Install python packages: ```bash poetry install ``` ## Quick start Here is an example of how to create a RSVP server running on TCP: ```py from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp # Define commands and their callbacks @RsvpServer.Command("START") def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: 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.run() ``` The main idea is to use the decorator to add callback based on command names to your server ```py @RsvpServer.Command(<COMMAND_NAME>) ``` Each callback will receive the user defined arguments and each callback must return a reply string in the form ```py return f"REPLY-<COMMAND_NAME>=ACK|NACK;ARGS|ERROR" ``` The general protocol is described in more details [here][1]. ## Usage examples In the *examples* folder you'll find some usage examples ## Run tests ```bash poetry run pytest -v -s tests ``` ## Add pyrsvp to your project [1]:https://labinfo.ing.he-arc.ch/gitlab/igib/documents-latex/rsvp-specs No newline at end of file examples/tcpclient.py +17 −15 Original line number Diff line number Diff line import socket import time if __name__ == "__main__": from pyrsvp.rsvpclient import RsvpClientTcp, RsvpClientNotAck from pyrsvp.rsvptypes import * sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1.0) sock.connect(("localhost", 8080)) def start_cb(status : str): print(status) if __name__ == "__main__": sock.sendall("START;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) client = RsvpClientTcp() sock.sendall("START;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN;TEST(STR)=test\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) args = [ RsvpInteger("INTEGER", 1), RsvpDouble("DOUBLE", 2.0), RsvpBool("BOOL", True), RsvpString("STRING", "hello world"), RsvpVectorDouble("DOUBLE_VEC", {"X": 1.0, "Y": 2.0, "Z": 3.0}), RsvpStringVector("STRING_VEC", ["Hello", "World"]) ] sock.sendall("STOP;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) client.send_command("START", args, callback=start_cb) No newline at end of file examples/tcpserver.py +3 −3 Original line number Diff line number Diff line Loading @@ -2,10 +2,10 @@ from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp # Define commands and their callbacks @RsvpServer.Command("START") def start(status: str, t: float, count: int, user: str) -> str: def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: print(f"STATUS: {status}, T: {t}, COUNT: {count}, USER: {user}") return "REPLY-START=ACK" print(f"a: {a}, b: {b}, c: {c}, d: {d}, e: {e}, f: {f}") return f"REPLY-START=ACK;STATUS=PASS" if __name__ == "__main__": Loading poetry.lock +16 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,17 @@ python-versions = ">=3.8" dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyserial" version = "3.5" description = "Python Serial Port Extension" category = "main" optional = false python-versions = "*" [package.extras] cp2110 = ["hidapi"] [[package]] name = "pytest" version = "7.4.4" Loading Loading @@ -75,7 +86,7 @@ python-versions = ">=3.7" [metadata] lock-version = "1.1" python-versions = "^3.10" content-hash = "334ca3729df67309ee26943ac8d66d80f2eeae73afba636e5dad7e2f9f1bb6c1" content-hash = "6d413f6dd3e7271659a47c02ba0a6715d2c5511894de71fc24c0a061d11a9ab5" [metadata.files] colorama = [ Loading @@ -98,6 +109,10 @@ pluggy = [ {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] pyserial = [ {file = "pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"}, {file = "pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb"}, ] pytest = [ {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, Loading Loading
.gitignore 0 → 100644 +4 −0 Original line number Diff line number Diff line # Python stuff __pycache__/ .pytest_cache/ No newline at end of file
README.md +61 −0 Original line number Diff line number Diff line # RSVP python This repo contains the implementation of the *RSVP (Request-and-Stream Variable Protocol)* for python. ## Dependencies | | | |-|-| | Poetry | >= 1.2.0 | Install python packages: ```bash poetry install ``` ## Quick start Here is an example of how to create a RSVP server running on TCP: ```py from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp # Define commands and their callbacks @RsvpServer.Command("START") def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: 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.run() ``` The main idea is to use the decorator to add callback based on command names to your server ```py @RsvpServer.Command(<COMMAND_NAME>) ``` Each callback will receive the user defined arguments and each callback must return a reply string in the form ```py return f"REPLY-<COMMAND_NAME>=ACK|NACK;ARGS|ERROR" ``` The general protocol is described in more details [here][1]. ## Usage examples In the *examples* folder you'll find some usage examples ## Run tests ```bash poetry run pytest -v -s tests ``` ## Add pyrsvp to your project [1]:https://labinfo.ing.he-arc.ch/gitlab/igib/documents-latex/rsvp-specs No newline at end of file
examples/tcpclient.py +17 −15 Original line number Diff line number Diff line import socket import time if __name__ == "__main__": from pyrsvp.rsvpclient import RsvpClientTcp, RsvpClientNotAck from pyrsvp.rsvptypes import * sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1.0) sock.connect(("localhost", 8080)) def start_cb(status : str): print(status) if __name__ == "__main__": sock.sendall("START;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) client = RsvpClientTcp() sock.sendall("START;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN;TEST(STR)=test\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) args = [ RsvpInteger("INTEGER", 1), RsvpDouble("DOUBLE", 2.0), RsvpBool("BOOL", True), RsvpString("STRING", "hello world"), RsvpVectorDouble("DOUBLE_VEC", {"X": 1.0, "Y": 2.0, "Z": 3.0}), RsvpStringVector("STRING_VEC", ["Hello", "World"]) ] sock.sendall("STOP;STATUS=PASS;T(DBL)=4.5;COUNT(INT)=3;USER(STR)=JEAN\r\n".encode()) buf = sock.recv(1024) print(buf.decode()) client.send_command("START", args, callback=start_cb) No newline at end of file
examples/tcpserver.py +3 −3 Original line number Diff line number Diff line Loading @@ -2,10 +2,10 @@ from pyrsvp.rsvpserver import RsvpServer, RsvpServerTcp # Define commands and their callbacks @RsvpServer.Command("START") def start(status: str, t: float, count: int, user: str) -> str: def start(a: int, b: float, c: bool, d: str, e: dict, f: list) -> str: print(f"STATUS: {status}, T: {t}, COUNT: {count}, USER: {user}") return "REPLY-START=ACK" print(f"a: {a}, b: {b}, c: {c}, d: {d}, e: {e}, f: {f}") return f"REPLY-START=ACK;STATUS=PASS" if __name__ == "__main__": Loading
poetry.lock +16 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,17 @@ python-versions = ">=3.8" dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyserial" version = "3.5" description = "Python Serial Port Extension" category = "main" optional = false python-versions = "*" [package.extras] cp2110 = ["hidapi"] [[package]] name = "pytest" version = "7.4.4" Loading Loading @@ -75,7 +86,7 @@ python-versions = ">=3.7" [metadata] lock-version = "1.1" python-versions = "^3.10" content-hash = "334ca3729df67309ee26943ac8d66d80f2eeae73afba636e5dad7e2f9f1bb6c1" content-hash = "6d413f6dd3e7271659a47c02ba0a6715d2c5511894de71fc24c0a061d11a9ab5" [metadata.files] colorama = [ Loading @@ -98,6 +109,10 @@ pluggy = [ {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] pyserial = [ {file = "pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"}, {file = "pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb"}, ] pytest = [ {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, Loading