Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add execute_request method #881

Merged
merged 5 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions python/composio/client/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,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(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding method validation to ensure only valid HTTP methods are used:

valid_methods = {'GET', 'POST', 'PUT', 'DELETE', 'PATCH'}
if method.upper() not in valid_methods:
    raise ValueError(f"Invalid HTTP method: {method}. Must be one of {valid_methods}")

"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:
Expand Down
70 changes: 70 additions & 0 deletions python/composio/tools/toolset.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,76 @@ 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(
tushar-composio marked this conversation as resolved.
Show resolved Hide resolved
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:
"""
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
)

if connection_id is None:
raise ComposioSDKError(
"Please provide connection id or app name to execute a 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,
apps: t.Optional[t.Sequence[AppType]] = None,
Expand Down
Loading