diff --git a/autonomous_agent/.gitignore b/autonomous_agent/.gitignore new file mode 100644 index 000000000..c69b11e77 --- /dev/null +++ b/autonomous_agent/.gitignore @@ -0,0 +1 @@ +app.log \ No newline at end of file diff --git a/autonomous_agent/CHANGELOG.md b/autonomous_agent/CHANGELOG.md new file mode 100644 index 000000000..dc40f0edc --- /dev/null +++ b/autonomous_agent/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + + - Setup websocket client for autonomous agent service \ No newline at end of file diff --git a/autonomous_agent/README.md b/autonomous_agent/README.md new file mode 100644 index 000000000..3aa16a001 --- /dev/null +++ b/autonomous_agent/README.md @@ -0,0 +1,48 @@ + +# Autonomous Agent + +This is a python service for creating websocket connection with the central server using agent id. The agent pings the server periodically via the websocket connection. + +Requirments: + + - Python 3.12.2 + + - Poetry +## Setup Guide + +Clone the project + +```bash + git clone https://github.com/sireto/cardano-autonomous-agent +``` + +Go to the Autonomous Agent Directory + +```bash + cd autonomous_agent +``` + +Install dependencies via poetry. + +```bash + poetry install +``` +## Creating a new Agent. + +To create a new agent you need to send a post request to **api/create_agent** endpoint. Make sure that **autonomous_agent_api** backend service and **database** are running correctly. + +Copy the id from the post response . The id looks something similar to **c2d4c358-5171-4be8-b273-0147cc57c204.** + +## Running the service + +Activate the poetry virtual env inside **autonomous_agent** folder by running the following command. + +``` + poetry shell +``` +Now run the following command along with your agent id. + +``` +python connect-agent.py --agent_id < Your id here > +``` +After a successfull connection , you should see the periodic ping request and response in your terminal. \ No newline at end of file diff --git a/autonomous_agent/__init__.py b/autonomous_agent/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/autonomous_agent/connect-agent.py b/autonomous_agent/connect-agent.py new file mode 100644 index 000000000..4949863d3 --- /dev/null +++ b/autonomous_agent/connect-agent.py @@ -0,0 +1,39 @@ +import asyncio +import websockets +import argparse +from websockets.exceptions import ConnectionClosed + +default_ping_timeout = 10 # Sends a ping every 10 seconds + + +async def connect_to_server(agent_id): + uri = "ws://127.0.0.1:8000/api/agent/ws" + headers = {"agent_id": agent_id} + + try: + async with websockets.connect(uri, extra_headers=headers) as websocket: + while True: + try: + await websocket.send("PING") + response = await websocket.recv() + print("Received:", response) + await asyncio.sleep(default_ping_timeout) + except ConnectionClosed: + print("Connection closed by server") + break + except ConnectionError: + print("Failed to connect to the server") + + +async def main(agent_id): + await connect_to_server(agent_id) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Connect to Central WebSocket server with agent ID" + ) + parser.add_argument("--agent_id", help="Agent ID to connect with", required=True) + args = parser.parse_args() + + asyncio.run(main(args.agent_id)) diff --git a/autonomous_agent/poetry.lock b/autonomous_agent/poetry.lock new file mode 100644 index 000000000..cf80375fc --- /dev/null +++ b/autonomous_agent/poetry.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "websockets" +version = "12.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.12" +content-hash = "8bfed10760e92682d1726396e0df9aaa6d7baf0a3bd075107a9c663fb534a69e" diff --git a/autonomous_agent/pyproject.toml b/autonomous_agent/pyproject.toml new file mode 100644 index 000000000..07bd11f9d --- /dev/null +++ b/autonomous_agent/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "autonomous-agent" +version = "0.1.0" +description = "" +authors = ["Joseph Rana "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.12" +websockets = "^12.0" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/autonomous_agent_api/CHANGELOG.md b/autonomous_agent_api/CHANGELOG.md index 15d3310cd..4b71f410d 100644 --- a/autonomous_agent_api/CHANGELOG.md +++ b/autonomous_agent_api/CHANGELOG.md @@ -27,3 +27,6 @@ - Made table for Triggers - Created router,service,repository for trigger CRUD Action - Created the validation function for cron expression and kafka topic while creating the trigger by agent + +# TITLE - AGENT Websocket , DATE- 2024-04-09 + - Added websocket endpoint for agent websocket connection diff --git a/autonomous_agent_api/backend/app/controllers/agent_websocket.py b/autonomous_agent_api/backend/app/controllers/agent_websocket.py new file mode 100644 index 000000000..7684d3016 --- /dev/null +++ b/autonomous_agent_api/backend/app/controllers/agent_websocket.py @@ -0,0 +1,81 @@ +from fastapi import WebSocket, APIRouter, WebSocketDisconnect, WebSocketException +from backend.config.database import prisma_connection +from fastapi import status +from datetime import datetime +from backend.config.logger import logger + +router = APIRouter() + + +class WebSocket_Connection_Manager: + def __init__(self) -> None: + self.active_connections: dict[str, WebSocket] = {} + + async def connect_websocket(self, websocket_agent_id: str, websocket: WebSocket): + # Stores Websocket along with agent id in Key Value Pair : websocket_agent_id : Key , websocket : value + await websocket.accept() + self.active_connections[websocket_agent_id] = websocket + + async def disconnect_websocket(self, websocket_agent_id): + """Critical : Dont use .close() here as this will close the new connection when dealing with multiple web socket request for the same bot. + This is due to the nature of try/except code that gets called by the previous connection.""" + self.active_connections.pop(websocket_agent_id) + + async def send_message_to_websocket(self, websocket_agent_id: str, message: dict): + # Checks if agent is active , first then sends message + agent_active = await self.check_if_agent_active(websocket_agent_id) + if agent_active: + await self.active_connections[websocket_agent_id].send_json(message) + else: + logger.critical( + "Agent with the id {websocket_agent_id} does not exist in the active Connection list. Sending Message Failed!" + ) + + async def check_if_agent_active(self, websocket_agent_id: str): + # Checks if agent is present in active connection list. + return websocket_agent_id in self.active_connections + + async def remove_previous_agent_connection_if_exists(self, websocket_agent_id: str): + """ + If client requests websocket connection for an already active bot. + Removes the old connection and establishes a new one. + """ + if await self.check_if_agent_active(websocket_agent_id): + existing_websocket = self.active_connections.pop(websocket_agent_id) + await existing_websocket.close(code=1000, reason="establishing a new connection") + + +manager = WebSocket_Connection_Manager() + + +@router.websocket("/agent/ws") +async def agent_websocket_endpoint(websocket: WebSocket): + # todo: Cookies Authentication + + # Get agent id from the websocket header. + websocket_agent_id = websocket.headers.get("agent_id") + if websocket_agent_id == None: + raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) + + # Check if agent with the id exists. + agent_exists = await check_if_agent_exists_in_db(websocket_agent_id) + if agent_exists: + await manager.remove_previous_agent_connection_if_exists(websocket_agent_id) + await manager.connect_websocket(websocket_agent_id, websocket) + try: + while True: + data = await websocket.receive_text() + print(f"Received Data: {data} from {websocket_agent_id}") + await websocket.send_text(f"Ping recieved from {websocket_agent_id} at {datetime.now()}") + except WebSocketDisconnect: + await manager.disconnect_websocket(websocket_agent_id) + pass + else: + raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) + + +async def check_if_agent_exists_in_db(agent_id: str): + # Query agent with the agent id from the database -> reurns a boolean + async with prisma_connection: + agent_exists = await prisma_connection.prisma.agent.find_first(where={"id": agent_id, "deleted_at": None}) + return bool(agent_exists) diff --git a/autonomous_agent_api/backend/app/router.py b/autonomous_agent_api/backend/app/router.py index d3eee69b3..d7c1ab208 100644 --- a/autonomous_agent_api/backend/app/router.py +++ b/autonomous_agent_api/backend/app/router.py @@ -7,14 +7,22 @@ """ from fastapi import APIRouter -from backend.app.controllers import ready, demo, agent_router, trigger_router + +from backend.app.controllers import ready, demo, agent_router, trigger_router, agent_websocket root_api_router = APIRouter(prefix="/api") +# For ready status Api root_api_router.include_router(ready.router, tags=["ready"]) +# For Demo Ping APi root_api_router.include_router(demo.router, tags=["test"]) +# For Agent CRUD operations root_api_router.include_router(agent_router.AgentRouter().router, tags=["agent"]) +# For Agent Websocket connection +root_api_router.include_router(agent_websocket.router) + +# For Agent Trigger root_api_router.include_router(trigger_router.TriggerRouter().router, tags=["trigger"])