From 972e46d01d9e88f17ab189c80813a3926bab7fb7 Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Thu, 21 Nov 2024 13:56:45 +0530 Subject: [PATCH 1/3] feat: add `execute_request` method --- python/composio/client/collections.py | 26 ++++++++++++++ python/composio/tools/toolset.py | 52 +++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/python/composio/client/collections.py b/python/composio/client/collections.py index fa44d6e2d0..ab71839c3b 100644 --- a/python/composio/client/collections.py +++ b/python/composio/client/collections.py @@ -1239,6 +1239,32 @@ def execute( ) ).json() + def request( + self, + connection_id: str, + endpoint: str, + method: str, + body: t.Optional[t.Dict] = None, + parameters: t.Optional[t.List[CustomAuthParameter]] = None, + ) -> t.Dict: + return self.client.http.post( + url=str(self.endpoint / "proxy"), + json={ + "connectedAccountId": connection_id, + "body": body, + "method": method.upper(), + "endpoint": endpoint, + "parameters": [ + { + "in": param["in_"], + "name": param["name"], + "value": param["value"], + } + for param in parameters or [] + ], + }, + ).json() + @staticmethod def _serialize_auth(auth: t.Optional[CustomAuthObject]) -> t.Optional[t.Dict]: if auth is None: diff --git a/python/composio/tools/toolset.py b/python/composio/tools/toolset.py index 8c472b1d87..ff41b6547b 100644 --- a/python/composio/tools/toolset.py +++ b/python/composio/tools/toolset.py @@ -781,6 +781,58 @@ def execute_action( self.logger.info(f"Got {response=} from {action=} with {params=}") return response + @t.overload + def execute_request( + self, + endpoint: str, + method: str, + body: t.Optional[t.Dict] = None, + parameters: t.Optional[t.List[CustomAuthParameter]] = None, + *, + connection_id: t.Optional[str] = None, + ) -> t.Dict: + pass + + @t.overload + def execute_request( + self, + endpoint: str, + method: str, + body: t.Optional[t.Dict] = None, + parameters: t.Optional[t.List[CustomAuthParameter]] = None, + *, + app: t.Optional[AppType] = None, + ) -> t.Dict: + pass + + def execute_request( + self, + endpoint: str, + method: str, + body: t.Optional[t.Dict] = None, + parameters: t.Optional[t.List[CustomAuthParameter]] = None, + *, + connection_id: t.Optional[str] = None, + app: t.Optional[AppType] = None, + ) -> t.Dict: + if app is not None and connection_id is None: + connection_id = ( + self.get_entity(id=self.entity_id).get_connection(app=app).id + ) + + if connection_id is None: + raise ComposioSDKError( + "Please provide connection id or app name to execute a request" + ) + + return self.client.actions.request( + connection_id=connection_id, + body=body, + method=method, + endpoint=endpoint, + parameters=parameters, + ) + def validate_tools( self, apps: t.Optional[t.Sequence[AppType]] = None, From 39a73e3fdec5732b31db7fe4ede7e88d9351d1bd Mon Sep 17 00:00:00 2001 From: tushar-composio Date: Thu, 21 Nov 2024 02:21:03 -0800 Subject: [PATCH 2/3] make body and parameters keyword-only --- python/composio/tools/toolset.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/composio/tools/toolset.py b/python/composio/tools/toolset.py index ff41b6547b..4ba9d42acc 100644 --- a/python/composio/tools/toolset.py +++ b/python/composio/tools/toolset.py @@ -786,9 +786,9 @@ def execute_request( self, endpoint: str, method: str, + *, body: t.Optional[t.Dict] = None, parameters: t.Optional[t.List[CustomAuthParameter]] = None, - *, connection_id: t.Optional[str] = None, ) -> t.Dict: pass @@ -798,9 +798,9 @@ def execute_request( self, endpoint: str, method: str, + *, body: t.Optional[t.Dict] = None, parameters: t.Optional[t.List[CustomAuthParameter]] = None, - *, app: t.Optional[AppType] = None, ) -> t.Dict: pass @@ -809,9 +809,9 @@ def execute_request( self, endpoint: str, method: str, + *, body: t.Optional[t.Dict] = None, parameters: t.Optional[t.List[CustomAuthParameter]] = None, - *, connection_id: t.Optional[str] = None, app: t.Optional[AppType] = None, ) -> t.Dict: From 2a89e0cd92ffed12f7137afa53b7305fe65d08dd Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Thu, 21 Nov 2024 16:16:58 +0530 Subject: [PATCH 3/3] chore: address comments --- python/composio/tools/toolset.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/python/composio/tools/toolset.py b/python/composio/tools/toolset.py index 4ba9d42acc..1b25aa2014 100644 --- a/python/composio/tools/toolset.py +++ b/python/composio/tools/toolset.py @@ -815,6 +815,19 @@ def execute_request( connection_id: t.Optional[str] = None, app: t.Optional[AppType] = None, ) -> t.Dict: + """ + Execute a proxy request to a connected account. + + :param endpoint: API endpoint to call + :param method: HTTP method to use (GET, POST, etc.) + :param body: Request body data + :param parameters: Additional auth parameters + :param connection_id: ID of the connected account + :param app: App type to use for connection lookup + + :returns: Response from the proxy request + :raises: ComposioSDKError: If neither connection_id nor app is provided + """ if app is not None and connection_id is None: connection_id = ( self.get_entity(id=self.entity_id).get_connection(app=app).id @@ -825,13 +838,18 @@ def execute_request( "Please provide connection id or app name to execute a request" ) - return self.client.actions.request( + self.logger.info( + f"Executing request to {endpoint} with method={method}, connection_id={connection_id}" + ) + response = self.client.actions.request( connection_id=connection_id, body=body, method=method, endpoint=endpoint, parameters=parameters, ) + self.logger.info(f"Got {response=}") + return response def validate_tools( self,