chore: lint issues
This commit is contained in:
@@ -79,7 +79,9 @@ def main():
|
||||
|
||||
cursor.execute(payroll_query)
|
||||
|
||||
print(f"\n{'Department':<25} {'Employees':<12} {'Total Salary Cost':<20} {'Avg Salary':<15}")
|
||||
print(
|
||||
f"\n{'Department':<25} {'Employees':<12} {'Total Salary Cost':<20} {'Avg Salary':<15}"
|
||||
)
|
||||
print("-" * 80)
|
||||
|
||||
total_company_payroll = 0
|
||||
@@ -176,7 +178,11 @@ def main():
|
||||
print("=" * 80)
|
||||
print(f"✓ Total Employees: {total_employees}")
|
||||
print(f"✓ Total Company Payroll: ${total_company_payroll:,.2f}")
|
||||
print(f"✓ Average Employee Salary: ${total_company_payroll / total_employees:,.2f}" if total_employees > 0 else "N/A")
|
||||
print(
|
||||
f"✓ Average Employee Salary: ${total_company_payroll / total_employees:,.2f}"
|
||||
if total_employees > 0
|
||||
else "N/A"
|
||||
)
|
||||
print("=" * 80)
|
||||
print("\nPayroll analysis completed successfully!")
|
||||
|
||||
|
||||
@@ -89,7 +89,9 @@ def main():
|
||||
# Highlight the department with the highest average
|
||||
if avg_salary == highest_avg:
|
||||
# Use special formatting for the highest
|
||||
print(f"{'>>> ' + str(idx):<6} {department:<25} {avg_salary_str:<20} {emp_count:<12} ⭐ HIGHEST")
|
||||
print(
|
||||
f"{'>>> ' + str(idx):<6} {department:<25} {avg_salary_str:<20} {emp_count:<12} ⭐ HIGHEST"
|
||||
)
|
||||
else:
|
||||
print(f"{idx:<6} {department:<25} {avg_salary_str:<20} {emp_count:<12}")
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
Brevo tool credentials.
|
||||
Contains credentials for Brevo email and SMS integration.
|
||||
"""
|
||||
|
||||
from .base import CredentialSpec
|
||||
|
||||
BREVO_CREDENTIALS = {
|
||||
|
||||
@@ -76,7 +76,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
if not base_id or not table_name:
|
||||
return {"error": "base_id and table_name are required"}
|
||||
|
||||
@@ -127,7 +130,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
if not base_id or not table_name or not record_id:
|
||||
return {"error": "base_id, table_name, and record_id are required"}
|
||||
|
||||
@@ -158,7 +164,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
if not base_id or not table_name or not records:
|
||||
return {"error": "base_id, table_name, and records are required"}
|
||||
|
||||
@@ -186,10 +195,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
return {
|
||||
"result": "created",
|
||||
"count": len(created),
|
||||
"records": [
|
||||
{"id": r["id"], "fields": r.get("fields", {})}
|
||||
for r in created
|
||||
],
|
||||
"records": [{"id": r["id"], "fields": r.get("fields", {})} for r in created],
|
||||
}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -211,7 +217,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
if not base_id or not table_name or not records:
|
||||
return {"error": "base_id, table_name, and records are required"}
|
||||
|
||||
@@ -239,10 +248,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
return {
|
||||
"result": "updated",
|
||||
"count": len(updated),
|
||||
"records": [
|
||||
{"id": r["id"], "fields": r.get("fields", {})}
|
||||
for r in updated
|
||||
],
|
||||
"records": [{"id": r["id"], "fields": r.get("fields", {})} for r in updated],
|
||||
}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -250,7 +256,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""List all Airtable bases accessible with the current token."""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
|
||||
url = f"{BASE_URL}/meta/bases"
|
||||
data = _get(url, hdrs)
|
||||
@@ -281,7 +290,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
hdrs = _get_headers()
|
||||
if hdrs is None:
|
||||
return {"error": "AIRTABLE_PAT is required", "help": "Set AIRTABLE_PAT env var with your Airtable personal access token"}
|
||||
return {
|
||||
"error": "AIRTABLE_PAT is required",
|
||||
"help": "Set AIRTABLE_PAT env var with your Airtable personal access token",
|
||||
}
|
||||
if not base_id:
|
||||
return {"error": "base_id is required"}
|
||||
|
||||
|
||||
@@ -35,7 +35,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{APIFY_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{APIFY_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your APIFY_API_TOKEN."}
|
||||
if resp.status_code == 404:
|
||||
@@ -51,7 +53,9 @@ def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any
|
||||
|
||||
def _post(endpoint: str, token: str, body: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{APIFY_API}/{endpoint}", headers=_headers(token), json=body or {}, timeout=60.0)
|
||||
resp = httpx.post(
|
||||
f"{APIFY_API}/{endpoint}", headers=_headers(token), json=body or {}, timeout=60.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your APIFY_API_TOKEN."}
|
||||
if resp.status_code not in (200, 201):
|
||||
@@ -252,13 +256,15 @@ def register_tools(
|
||||
actors = []
|
||||
for a in data.get("data", {}).get("items", []):
|
||||
stats = a.get("stats", {})
|
||||
actors.append({
|
||||
"id": a.get("id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"title": a.get("title", ""),
|
||||
"description": (a.get("description", "") or "")[:200],
|
||||
"total_runs": stats.get("totalRuns", 0),
|
||||
})
|
||||
actors.append(
|
||||
{
|
||||
"id": a.get("id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"title": a.get("title", ""),
|
||||
"description": (a.get("description", "") or "")[:200],
|
||||
"total_runs": stats.get("totalRuns", 0),
|
||||
}
|
||||
)
|
||||
return {"actors": actors, "count": len(actors)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -290,14 +296,16 @@ def register_tools(
|
||||
|
||||
runs = []
|
||||
for r in data.get("data", {}).get("items", []):
|
||||
runs.append({
|
||||
"run_id": r.get("id", ""),
|
||||
"actor_id": r.get("actId", ""),
|
||||
"status": r.get("status", ""),
|
||||
"started_at": r.get("startedAt", ""),
|
||||
"finished_at": r.get("finishedAt", ""),
|
||||
"dataset_id": r.get("defaultDatasetId", ""),
|
||||
})
|
||||
runs.append(
|
||||
{
|
||||
"run_id": r.get("id", ""),
|
||||
"actor_id": r.get("actId", ""),
|
||||
"status": r.get("status", ""),
|
||||
"started_at": r.get("startedAt", ""),
|
||||
"finished_at": r.get("finishedAt", ""),
|
||||
"dataset_id": r.get("defaultDatasetId", ""),
|
||||
}
|
||||
)
|
||||
return {"runs": runs, "count": len(runs)}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -34,7 +34,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{ASANA_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{ASANA_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your ASANA_ACCESS_TOKEN."}
|
||||
if resp.status_code == 403:
|
||||
@@ -52,7 +54,12 @@ def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any
|
||||
|
||||
def _post(endpoint: str, token: str, body: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{ASANA_API}/{endpoint}", headers=_headers(token), json={"data": body or {}}, timeout=30.0)
|
||||
resp = httpx.post(
|
||||
f"{ASANA_API}/{endpoint}",
|
||||
headers=_headers(token),
|
||||
json={"data": body or {}},
|
||||
timeout=30.0,
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your ASANA_ACCESS_TOKEN."}
|
||||
if resp.status_code not in (200, 201):
|
||||
@@ -130,12 +137,14 @@ def register_tools(
|
||||
|
||||
projects = []
|
||||
for p in data.get("data", []):
|
||||
projects.append({
|
||||
"gid": p.get("gid", ""),
|
||||
"name": p.get("name", ""),
|
||||
"color": p.get("color", ""),
|
||||
"archived": p.get("archived", False),
|
||||
})
|
||||
projects.append(
|
||||
{
|
||||
"gid": p.get("gid", ""),
|
||||
"name": p.get("name", ""),
|
||||
"color": p.get("color", ""),
|
||||
"archived": p.get("archived", False),
|
||||
}
|
||||
)
|
||||
return {"projects": projects}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -180,13 +189,15 @@ def register_tools(
|
||||
tasks = []
|
||||
for t in data.get("data", []):
|
||||
assignee_obj = t.get("assignee") or {}
|
||||
tasks.append({
|
||||
"gid": t.get("gid", ""),
|
||||
"name": t.get("name", ""),
|
||||
"completed": t.get("completed", False),
|
||||
"due_on": t.get("due_on", ""),
|
||||
"assignee_name": assignee_obj.get("name", ""),
|
||||
})
|
||||
tasks.append(
|
||||
{
|
||||
"gid": t.get("gid", ""),
|
||||
"name": t.get("name", ""),
|
||||
"completed": t.get("completed", False),
|
||||
"due_on": t.get("due_on", ""),
|
||||
"assignee_name": assignee_obj.get("name", ""),
|
||||
}
|
||||
)
|
||||
return {"tasks": tasks, "count": len(tasks)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -206,7 +217,9 @@ def register_tools(
|
||||
if not task_gid:
|
||||
return {"error": "task_gid is required"}
|
||||
|
||||
params = {"opt_fields": "name,notes,completed,due_on,assignee.name,projects.name,tags.name,created_at,modified_at"}
|
||||
params = {
|
||||
"opt_fields": "name,notes,completed,due_on,assignee.name,projects.name,tags.name,created_at,modified_at"
|
||||
}
|
||||
data = _get(f"tasks/{task_gid}", token, params)
|
||||
if "error" in data:
|
||||
return data
|
||||
@@ -306,10 +319,12 @@ def register_tools(
|
||||
|
||||
tasks = []
|
||||
for t in data.get("data", []):
|
||||
tasks.append({
|
||||
"gid": t.get("gid", ""),
|
||||
"name": t.get("name", ""),
|
||||
"completed": t.get("completed", False),
|
||||
"due_on": t.get("due_on", ""),
|
||||
})
|
||||
tasks.append(
|
||||
{
|
||||
"gid": t.get("gid", ""),
|
||||
"name": t.get("name", ""),
|
||||
"completed": t.get("completed", False),
|
||||
"due_on": t.get("due_on", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "tasks": tasks}
|
||||
|
||||
@@ -121,9 +121,7 @@ class TestAttioClient:
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
params = {"matching_attribute": "email_addresses"}
|
||||
result = self.client._request(
|
||||
"PUT", "/objects/people/records", json_body={}, params=params
|
||||
)
|
||||
result = self.client._request("PUT", "/objects/people/records", json_body={}, params=params)
|
||||
|
||||
call_kwargs = mock_request.call_args.kwargs
|
||||
assert call_kwargs["params"] == params
|
||||
@@ -210,7 +208,10 @@ class TestAttioClient:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": {"record_id": "rec-123"}, "values": {"name": [{"first_name": "Updated"}]}}
|
||||
"data": {
|
||||
"id": {"record_id": "rec-123"},
|
||||
"values": {"name": [{"first_name": "Updated"}]},
|
||||
}
|
||||
}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
@@ -223,9 +224,7 @@ class TestAttioClient:
|
||||
def test_assert_record(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": {"record_id": "rec-upserted"}}
|
||||
}
|
||||
mock_response.json.return_value = {"data": {"id": {"record_id": "rec-upserted"}}}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
values = {"email_addresses": [{"email_address": "test@example.com"}]}
|
||||
@@ -241,9 +240,7 @@ class TestAttioClient:
|
||||
def test_list_lists(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "list-1", "name": "Sales Pipeline"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "list-1", "name": "Sales Pipeline"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.list_lists()
|
||||
@@ -255,9 +252,7 @@ class TestAttioClient:
|
||||
def test_get_entries(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "entry-1"}, {"id": "entry-2"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "entry-1"}, {"id": "entry-2"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.get_entries("list-1")
|
||||
@@ -332,9 +327,7 @@ class TestAttioClient:
|
||||
def test_list_tasks(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "task-1"}, {"id": "task-2"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "task-1"}, {"id": "task-2"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.list_tasks()
|
||||
@@ -346,9 +339,7 @@ class TestAttioClient:
|
||||
def test_get_task(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": "task-1", "content": "Call back"}
|
||||
}
|
||||
mock_response.json.return_value = {"data": {"id": "task-1", "content": "Call back"}}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.get_task("task-1")
|
||||
|
||||
@@ -26,7 +26,10 @@ def _get_config() -> tuple[str, str, str] | dict:
|
||||
secret_key = os.getenv("AWS_SECRET_ACCESS_KEY", "")
|
||||
region = os.getenv("AWS_REGION", "us-east-1")
|
||||
if not access_key or not secret_key:
|
||||
return {"error": "AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are required", "help": "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables"}
|
||||
return {
|
||||
"error": "AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are required",
|
||||
"help": "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables",
|
||||
}
|
||||
return access_key, secret_key, region
|
||||
|
||||
|
||||
@@ -72,9 +75,7 @@ def _sign_request(
|
||||
|
||||
# Canonical headers
|
||||
signed_header_names = sorted(headers.keys())
|
||||
canonical_headers = "".join(
|
||||
f"{k}:{headers[k].strip()}\n" for k in signed_header_names
|
||||
)
|
||||
canonical_headers = "".join(f"{k}:{headers[k].strip()}\n" for k in signed_header_names)
|
||||
signed_headers = ";".join(signed_header_names)
|
||||
|
||||
canonical_request = (
|
||||
@@ -131,7 +132,7 @@ def _parse_xml(text: str, ns: str = "") -> ET.Element:
|
||||
if ns:
|
||||
for elem in root.iter():
|
||||
if elem.tag.startswith(f"{{{ns}}}"):
|
||||
elem.tag = elem.tag[len(f"{{{ns}}}"):]
|
||||
elem.tag = elem.tag[len(f"{{{ns}}}") :]
|
||||
return root
|
||||
|
||||
|
||||
@@ -158,10 +159,12 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
for b in root.findall(".//Bucket"):
|
||||
name_el = b.find("Name")
|
||||
date_el = b.find("CreationDate")
|
||||
buckets.append({
|
||||
"name": name_el.text if name_el is not None else None,
|
||||
"creation_date": date_el.text if date_el is not None else None,
|
||||
})
|
||||
buckets.append(
|
||||
{
|
||||
"name": name_el.text if name_el is not None else None,
|
||||
"creation_date": date_el.text if date_el is not None else None,
|
||||
}
|
||||
)
|
||||
return {"count": len(buckets), "buckets": buckets}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -202,11 +205,13 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
key_el = c.find("Key")
|
||||
size_el = c.find("Size")
|
||||
modified_el = c.find("LastModified")
|
||||
objects.append({
|
||||
"key": key_el.text if key_el is not None else None,
|
||||
"size": int(size_el.text) if size_el is not None else 0,
|
||||
"last_modified": modified_el.text if modified_el is not None else None,
|
||||
})
|
||||
objects.append(
|
||||
{
|
||||
"key": key_el.text if key_el is not None else None,
|
||||
"size": int(size_el.text) if size_el is not None else 0,
|
||||
"last_modified": modified_el.text if modified_el is not None else None,
|
||||
}
|
||||
)
|
||||
prefixes = []
|
||||
for cp in root.findall("CommonPrefixes"):
|
||||
p_el = cp.find("Prefix")
|
||||
@@ -297,7 +302,9 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
body = content.encode("utf-8")
|
||||
extra = {"content-type": content_type}
|
||||
|
||||
resp = _s3_request("PUT", bucket, key, access_key, secret_key, region, body=body, extra_headers=extra)
|
||||
resp = _s3_request(
|
||||
"PUT", bucket, key, access_key, secret_key, region, body=body, extra_headers=extra
|
||||
)
|
||||
if resp.status_code >= 400:
|
||||
return {"error": f"HTTP {resp.status_code}: {resp.text[:500]}"}
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ def _get_config() -> tuple[dict, str] | dict:
|
||||
token = os.getenv("AZURE_SQL_ACCESS_TOKEN", "")
|
||||
sub_id = os.getenv("AZURE_SUBSCRIPTION_ID", "")
|
||||
if not token or not sub_id:
|
||||
return {"error": "AZURE_SQL_ACCESS_TOKEN and AZURE_SUBSCRIPTION_ID are required", "help": "Set AZURE_SQL_ACCESS_TOKEN and AZURE_SUBSCRIPTION_ID environment variables"}
|
||||
return {
|
||||
"error": "AZURE_SQL_ACCESS_TOKEN and AZURE_SUBSCRIPTION_ID are required",
|
||||
"help": "Set AZURE_SQL_ACCESS_TOKEN and AZURE_SUBSCRIPTION_ID environment variables",
|
||||
}
|
||||
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
||||
return headers, sub_id
|
||||
|
||||
@@ -149,9 +152,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
}
|
||||
|
||||
@mcp.tool()
|
||||
def azure_sql_get_database(
|
||||
resource_group: str, server_name: str, database_name: str
|
||||
) -> dict:
|
||||
def azure_sql_get_database(resource_group: str, server_name: str, database_name: str) -> dict:
|
||||
"""Get details of a specific Azure SQL database.
|
||||
|
||||
Args:
|
||||
@@ -174,9 +175,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
return _extract_database(data)
|
||||
|
||||
@mcp.tool()
|
||||
def azure_sql_list_firewall_rules(
|
||||
resource_group: str, server_name: str
|
||||
) -> dict:
|
||||
def azure_sql_list_firewall_rules(resource_group: str, server_name: str) -> dict:
|
||||
"""List firewall rules for an Azure SQL server.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -189,9 +189,7 @@ def register_tools(
|
||||
if credentials is not None:
|
||||
key = credentials.get("brevo")
|
||||
if key is not None and not isinstance(key, str):
|
||||
raise TypeError(
|
||||
f"Expected string from credentials, got {type(key).__name__}"
|
||||
)
|
||||
raise TypeError(f"Expected string from credentials, got {type(key).__name__}")
|
||||
return key
|
||||
return os.getenv("BREVO_API_KEY")
|
||||
|
||||
|
||||
@@ -46,7 +46,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "CALENDLY_PAT is required", "help": "Set CALENDLY_PAT environment variable"}
|
||||
return {
|
||||
"error": "CALENDLY_PAT is required",
|
||||
"help": "Set CALENDLY_PAT environment variable",
|
||||
}
|
||||
|
||||
data = _get("/users/me", headers)
|
||||
if "error" in data:
|
||||
@@ -77,7 +80,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "CALENDLY_PAT is required", "help": "Set CALENDLY_PAT environment variable"}
|
||||
return {
|
||||
"error": "CALENDLY_PAT is required",
|
||||
"help": "Set CALENDLY_PAT environment variable",
|
||||
}
|
||||
if not user_uri:
|
||||
return {"error": "user_uri is required"}
|
||||
|
||||
@@ -129,7 +135,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "CALENDLY_PAT is required", "help": "Set CALENDLY_PAT environment variable"}
|
||||
return {
|
||||
"error": "CALENDLY_PAT is required",
|
||||
"help": "Set CALENDLY_PAT environment variable",
|
||||
}
|
||||
if not user_uri:
|
||||
return {"error": "user_uri is required"}
|
||||
|
||||
@@ -175,7 +184,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "CALENDLY_PAT is required", "help": "Set CALENDLY_PAT environment variable"}
|
||||
return {
|
||||
"error": "CALENDLY_PAT is required",
|
||||
"help": "Set CALENDLY_PAT environment variable",
|
||||
}
|
||||
if not event_uri:
|
||||
return {"error": "event_uri is required"}
|
||||
|
||||
@@ -213,7 +225,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "CALENDLY_PAT is required", "help": "Set CALENDLY_PAT environment variable"}
|
||||
return {
|
||||
"error": "CALENDLY_PAT is required",
|
||||
"help": "Set CALENDLY_PAT environment variable",
|
||||
}
|
||||
if not event_uri:
|
||||
return {"error": "event_uri is required"}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ if TYPE_CHECKING:
|
||||
from aden_tools.credentials import CredentialStoreAdapter
|
||||
|
||||
|
||||
def _get_credentials(credentials: CredentialStoreAdapter | None) -> tuple[str | None, str | None, str | None]:
|
||||
def _get_credentials(
|
||||
credentials: CredentialStoreAdapter | None,
|
||||
) -> tuple[str | None, str | None, str | None]:
|
||||
"""Return (cloud_name, api_key, api_secret)."""
|
||||
if credentials is not None:
|
||||
cloud = credentials.get("cloudinary_cloud_name")
|
||||
@@ -45,9 +47,7 @@ def _auth_header(api_key: str, api_secret: str) -> str:
|
||||
return f"Basic {encoded}"
|
||||
|
||||
|
||||
def _request(
|
||||
method: str, url: str, api_key: str, api_secret: str, **kwargs: Any
|
||||
) -> dict[str, Any]:
|
||||
def _request(method: str, url: str, api_key: str, api_secret: str, **kwargs: Any) -> dict[str, Any]:
|
||||
"""Make a request to the Cloudinary API."""
|
||||
headers = kwargs.pop("headers", {})
|
||||
headers["Authorization"] = _auth_header(api_key, api_secret)
|
||||
@@ -165,15 +165,17 @@ def register_tools(
|
||||
|
||||
resources = []
|
||||
for r in data.get("resources", []):
|
||||
resources.append({
|
||||
"public_id": r.get("public_id", ""),
|
||||
"secure_url": r.get("secure_url", ""),
|
||||
"format": r.get("format", ""),
|
||||
"bytes": r.get("bytes", 0),
|
||||
"width": r.get("width"),
|
||||
"height": r.get("height"),
|
||||
"created_at": r.get("created_at", ""),
|
||||
})
|
||||
resources.append(
|
||||
{
|
||||
"public_id": r.get("public_id", ""),
|
||||
"secure_url": r.get("secure_url", ""),
|
||||
"format": r.get("format", ""),
|
||||
"bytes": r.get("bytes", 0),
|
||||
"width": r.get("width"),
|
||||
"height": r.get("height"),
|
||||
"created_at": r.get("created_at", ""),
|
||||
}
|
||||
)
|
||||
return {"resources": resources, "count": len(resources)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -269,20 +271,24 @@ def register_tools(
|
||||
"expression": expression,
|
||||
"max_results": max(1, min(max_results, 500)),
|
||||
}
|
||||
data = _request("post", url, key, secret, json=body, headers={"Content-Type": "application/json"})
|
||||
data = _request(
|
||||
"post", url, key, secret, json=body, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
if "error" in data:
|
||||
return data
|
||||
|
||||
resources = []
|
||||
for r in data.get("resources", []):
|
||||
resources.append({
|
||||
"public_id": r.get("public_id", ""),
|
||||
"secure_url": r.get("secure_url", ""),
|
||||
"format": r.get("format", ""),
|
||||
"resource_type": r.get("resource_type", ""),
|
||||
"bytes": r.get("bytes", 0),
|
||||
"created_at": r.get("created_at", ""),
|
||||
})
|
||||
resources.append(
|
||||
{
|
||||
"public_id": r.get("public_id", ""),
|
||||
"secure_url": r.get("secure_url", ""),
|
||||
"format": r.get("format", ""),
|
||||
"resource_type": r.get("resource_type", ""),
|
||||
"bytes": r.get("bytes", 0),
|
||||
"created_at": r.get("created_at", ""),
|
||||
}
|
||||
)
|
||||
return {
|
||||
"resources": resources,
|
||||
"total_count": data.get("total_count", 0),
|
||||
|
||||
@@ -22,7 +22,9 @@ if TYPE_CHECKING:
|
||||
from aden_tools.credentials import CredentialStoreAdapter
|
||||
|
||||
|
||||
def _get_credentials(credentials: CredentialStoreAdapter | None) -> tuple[str | None, str | None, str | None]:
|
||||
def _get_credentials(
|
||||
credentials: CredentialStoreAdapter | None,
|
||||
) -> tuple[str | None, str | None, str | None]:
|
||||
"""Return (domain, email, api_token)."""
|
||||
if credentials is not None:
|
||||
domain = credentials.get("confluence_domain")
|
||||
@@ -47,9 +49,7 @@ def _auth_header(email: str, token: str) -> str:
|
||||
return f"Basic {encoded}"
|
||||
|
||||
|
||||
def _request(
|
||||
method: str, url: str, email: str, token: str, **kwargs: Any
|
||||
) -> dict[str, Any]:
|
||||
def _request(method: str, url: str, email: str, token: str, **kwargs: Any) -> dict[str, Any]:
|
||||
"""Make a request to the Confluence API."""
|
||||
headers = {
|
||||
"Authorization": _auth_header(email, token),
|
||||
@@ -113,13 +113,15 @@ def register_tools(
|
||||
|
||||
spaces = []
|
||||
for s in data.get("results", []):
|
||||
spaces.append({
|
||||
"id": s.get("id", ""),
|
||||
"key": s.get("key", ""),
|
||||
"name": s.get("name", ""),
|
||||
"type": s.get("type", ""),
|
||||
"status": s.get("status", ""),
|
||||
})
|
||||
spaces.append(
|
||||
{
|
||||
"id": s.get("id", ""),
|
||||
"key": s.get("key", ""),
|
||||
"name": s.get("name", ""),
|
||||
"type": s.get("type", ""),
|
||||
"status": s.get("status", ""),
|
||||
}
|
||||
)
|
||||
return {"spaces": spaces, "count": len(spaces)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -159,14 +161,16 @@ def register_tools(
|
||||
pages = []
|
||||
for p in data.get("results", []):
|
||||
ver = p.get("version") or {}
|
||||
pages.append({
|
||||
"id": p.get("id", ""),
|
||||
"title": p.get("title", ""),
|
||||
"space_id": p.get("spaceId", ""),
|
||||
"status": p.get("status", ""),
|
||||
"version": ver.get("number", 0),
|
||||
"created_at": p.get("createdAt", ""),
|
||||
})
|
||||
pages.append(
|
||||
{
|
||||
"id": p.get("id", ""),
|
||||
"title": p.get("title", ""),
|
||||
"space_id": p.get("spaceId", ""),
|
||||
"status": p.get("status", ""),
|
||||
"version": ver.get("number", 0),
|
||||
"created_at": p.get("createdAt", ""),
|
||||
}
|
||||
)
|
||||
return {"pages": pages, "count": len(pages)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -294,10 +298,16 @@ def register_tools(
|
||||
cql = " AND ".join(cql_parts) + " ORDER BY lastModified desc"
|
||||
|
||||
url = f"{_base_url(domain)}/wiki/rest/api/search"
|
||||
data = _request("get", url, email, token, params={
|
||||
"cql": cql,
|
||||
"limit": max(1, min(limit, 50)),
|
||||
})
|
||||
data = _request(
|
||||
"get",
|
||||
url,
|
||||
email,
|
||||
token,
|
||||
params={
|
||||
"cql": cql,
|
||||
"limit": max(1, min(limit, 50)),
|
||||
},
|
||||
)
|
||||
if "error" in data:
|
||||
return data
|
||||
|
||||
@@ -305,12 +315,14 @@ def register_tools(
|
||||
for r in data.get("results", []):
|
||||
content = r.get("content") or {}
|
||||
space = content.get("space") or {}
|
||||
results.append({
|
||||
"title": r.get("title", ""),
|
||||
"excerpt": (r.get("excerpt", "") or "")[:300],
|
||||
"page_id": content.get("id", ""),
|
||||
"space_key": space.get("key", ""),
|
||||
"space_name": space.get("name", ""),
|
||||
"last_modified": r.get("lastModified", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"title": r.get("title", ""),
|
||||
"excerpt": (r.get("excerpt", "") or "")[:300],
|
||||
"page_id": content.get("id", ""),
|
||||
"space_key": space.get("key", ""),
|
||||
"space_name": space.get("name", ""),
|
||||
"last_modified": r.get("lastModified", ""),
|
||||
}
|
||||
)
|
||||
return {"results": results, "count": len(results)}
|
||||
|
||||
@@ -38,7 +38,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(host: str, endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{host}/api/2.0/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{host}/api/2.0/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your DATABRICKS_TOKEN."}
|
||||
if resp.status_code == 403:
|
||||
@@ -54,7 +56,9 @@ def _get(host: str, endpoint: str, token: str, params: dict | None = None) -> di
|
||||
|
||||
def _post(host: str, endpoint: str, token: str, body: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{host}/api/2.0/{endpoint}", headers=_headers(token), json=body or {}, timeout=60.0)
|
||||
resp = httpx.post(
|
||||
f"{host}/api/2.0/{endpoint}", headers=_headers(token), json=body or {}, timeout=60.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your DATABRICKS_TOKEN."}
|
||||
if resp.status_code not in (200, 201):
|
||||
@@ -165,12 +169,14 @@ def register_tools(
|
||||
jobs = []
|
||||
for job in data.get("jobs", []):
|
||||
settings = job.get("settings", {})
|
||||
jobs.append({
|
||||
"job_id": job.get("job_id", 0),
|
||||
"name": settings.get("name", ""),
|
||||
"creator": job.get("creator_user_name", ""),
|
||||
"created_time": job.get("created_time", 0),
|
||||
})
|
||||
jobs.append(
|
||||
{
|
||||
"job_id": job.get("job_id", 0),
|
||||
"name": settings.get("name", ""),
|
||||
"creator": job.get("creator_user_name", ""),
|
||||
"created_time": job.get("created_time", 0),
|
||||
}
|
||||
)
|
||||
return {"jobs": jobs}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -248,14 +254,16 @@ def register_tools(
|
||||
|
||||
clusters = []
|
||||
for c in data.get("clusters", []):
|
||||
clusters.append({
|
||||
"cluster_id": c.get("cluster_id", ""),
|
||||
"cluster_name": c.get("cluster_name", ""),
|
||||
"state": c.get("state", ""),
|
||||
"spark_version": c.get("spark_version", ""),
|
||||
"creator": c.get("creator_user_name", ""),
|
||||
"num_workers": c.get("num_workers", 0),
|
||||
})
|
||||
clusters.append(
|
||||
{
|
||||
"cluster_id": c.get("cluster_id", ""),
|
||||
"cluster_name": c.get("cluster_name", ""),
|
||||
"state": c.get("state", ""),
|
||||
"spark_version": c.get("spark_version", ""),
|
||||
"creator": c.get("creator_user_name", ""),
|
||||
"num_workers": c.get("num_workers", 0),
|
||||
}
|
||||
)
|
||||
return {"clusters": clusters}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -325,9 +333,11 @@ def register_tools(
|
||||
|
||||
objects = []
|
||||
for obj in data.get("objects", []):
|
||||
objects.append({
|
||||
"path": obj.get("path", ""),
|
||||
"object_type": obj.get("object_type", ""),
|
||||
"language": obj.get("language", ""),
|
||||
})
|
||||
objects.append(
|
||||
{
|
||||
"path": obj.get("path", ""),
|
||||
"object_type": obj.get("object_type", ""),
|
||||
"language": obj.get("language", ""),
|
||||
}
|
||||
)
|
||||
return {"path": path, "objects": objects}
|
||||
|
||||
@@ -35,7 +35,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{HUB_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{HUB_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your DOCKER_HUB_TOKEN."}
|
||||
if resp.status_code == 404:
|
||||
@@ -91,14 +93,16 @@ def register_tools(
|
||||
|
||||
results = []
|
||||
for r in data.get("results", []):
|
||||
results.append({
|
||||
"repo_name": r.get("repo_name", ""),
|
||||
"short_description": r.get("short_description", ""),
|
||||
"star_count": r.get("star_count", 0),
|
||||
"is_official": r.get("is_official", False),
|
||||
"is_automated": r.get("is_automated", False),
|
||||
"pull_count": r.get("pull_count", 0),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"repo_name": r.get("repo_name", ""),
|
||||
"short_description": r.get("short_description", ""),
|
||||
"star_count": r.get("star_count", 0),
|
||||
"is_official": r.get("is_official", False),
|
||||
"is_automated": r.get("is_automated", False),
|
||||
"pull_count": r.get("pull_count", 0),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": results}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -133,15 +137,17 @@ def register_tools(
|
||||
|
||||
repos = []
|
||||
for r in data.get("results", []):
|
||||
repos.append({
|
||||
"name": r.get("name", ""),
|
||||
"namespace": r.get("namespace", ""),
|
||||
"description": r.get("description", ""),
|
||||
"star_count": r.get("star_count", 0),
|
||||
"pull_count": r.get("pull_count", 0),
|
||||
"last_updated": r.get("last_updated", ""),
|
||||
"is_private": r.get("is_private", False),
|
||||
})
|
||||
repos.append(
|
||||
{
|
||||
"name": r.get("name", ""),
|
||||
"namespace": r.get("namespace", ""),
|
||||
"description": r.get("description", ""),
|
||||
"star_count": r.get("star_count", 0),
|
||||
"pull_count": r.get("pull_count", 0),
|
||||
"last_updated": r.get("last_updated", ""),
|
||||
"is_private": r.get("is_private", False),
|
||||
}
|
||||
)
|
||||
return {"namespace": namespace, "repos": repos}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -166,7 +172,11 @@ def register_tools(
|
||||
return {"error": "repository is required"}
|
||||
|
||||
max_results = max(1, min(max_results, 100))
|
||||
data = _get(f"repositories/{repository}/tags", token, {"page_size": max_results, "ordering": "-last_updated"})
|
||||
data = _get(
|
||||
f"repositories/{repository}/tags",
|
||||
token,
|
||||
{"page_size": max_results, "ordering": "-last_updated"},
|
||||
)
|
||||
if "error" in data:
|
||||
return data
|
||||
|
||||
@@ -174,12 +184,14 @@ def register_tools(
|
||||
for t in data.get("results", []):
|
||||
images = t.get("images", [])
|
||||
digest = images[0].get("digest", "") if images else ""
|
||||
tags.append({
|
||||
"name": t.get("name", ""),
|
||||
"full_size": t.get("full_size", 0),
|
||||
"last_updated": t.get("last_updated", ""),
|
||||
"digest": digest,
|
||||
})
|
||||
tags.append(
|
||||
{
|
||||
"name": t.get("name", ""),
|
||||
"full_size": t.get("full_size", 0),
|
||||
"last_updated": t.get("last_updated", ""),
|
||||
"digest": digest,
|
||||
}
|
||||
)
|
||||
return {"repository": repository, "tags": tags}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -60,11 +60,13 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
results = list(ddgs.text(**kwargs))
|
||||
items = []
|
||||
for r in results:
|
||||
items.append({
|
||||
"title": r.get("title", ""),
|
||||
"url": r.get("href", ""),
|
||||
"snippet": r.get("body", ""),
|
||||
})
|
||||
items.append(
|
||||
{
|
||||
"title": r.get("title", ""),
|
||||
"url": r.get("href", ""),
|
||||
"snippet": r.get("body", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": items, "count": len(items)}
|
||||
except Exception as e:
|
||||
return {"error": f"DuckDuckGo search failed: {e!s}"}
|
||||
@@ -106,13 +108,15 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
results = list(ddgs.news(**kwargs))
|
||||
items = []
|
||||
for r in results:
|
||||
items.append({
|
||||
"title": r.get("title", ""),
|
||||
"url": r.get("url", ""),
|
||||
"source": r.get("source", ""),
|
||||
"date": r.get("date", ""),
|
||||
"snippet": r.get("body", ""),
|
||||
})
|
||||
items.append(
|
||||
{
|
||||
"title": r.get("title", ""),
|
||||
"url": r.get("url", ""),
|
||||
"source": r.get("source", ""),
|
||||
"date": r.get("date", ""),
|
||||
"snippet": r.get("body", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": items, "count": len(items)}
|
||||
except Exception as e:
|
||||
return {"error": f"DuckDuckGo news search failed: {e!s}"}
|
||||
@@ -157,14 +161,16 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
results = list(ddgs.images(**kwargs))
|
||||
items = []
|
||||
for r in results:
|
||||
items.append({
|
||||
"title": r.get("title", ""),
|
||||
"image_url": r.get("image", ""),
|
||||
"thumbnail_url": r.get("thumbnail", ""),
|
||||
"source": r.get("source", ""),
|
||||
"width": r.get("width", 0),
|
||||
"height": r.get("height", 0),
|
||||
})
|
||||
items.append(
|
||||
{
|
||||
"title": r.get("title", ""),
|
||||
"image_url": r.get("image", ""),
|
||||
"thumbnail_url": r.get("thumbnail", ""),
|
||||
"source": r.get("source", ""),
|
||||
"width": r.get("width", 0),
|
||||
"height": r.get("height", 0),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": items, "count": len(items)}
|
||||
except Exception as e:
|
||||
return {"error": f"DuckDuckGo image search failed: {e!s}"}
|
||||
|
||||
@@ -34,7 +34,9 @@ def _get_credentials(credentials: CredentialStoreAdapter | None) -> tuple[str |
|
||||
return url, token
|
||||
|
||||
|
||||
def _get(base_url: str, path: str, token: str, params: dict[str, Any] | None = None) -> dict[str, Any] | list:
|
||||
def _get(
|
||||
base_url: str, path: str, token: str, params: dict[str, Any] | None = None
|
||||
) -> dict[str, Any] | list:
|
||||
"""Make an authenticated GET to the GitLab API."""
|
||||
try:
|
||||
resp = httpx.get(
|
||||
@@ -60,7 +62,9 @@ def _get(base_url: str, path: str, token: str, params: dict[str, Any] | None = N
|
||||
return {"error": f"GitLab request failed: {e!s}"}
|
||||
|
||||
|
||||
def _post(base_url: str, path: str, token: str, json: dict[str, Any] | None = None) -> dict[str, Any] | list:
|
||||
def _post(
|
||||
base_url: str, path: str, token: str, json: dict[str, Any] | None = None
|
||||
) -> dict[str, Any] | list:
|
||||
"""Make an authenticated POST to the GitLab API."""
|
||||
try:
|
||||
resp = httpx.post(
|
||||
@@ -135,18 +139,20 @@ def register_tools(
|
||||
return data
|
||||
|
||||
projects = []
|
||||
for p in (data if isinstance(data, list) else []):
|
||||
projects.append({
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"path_with_namespace": p.get("path_with_namespace", ""),
|
||||
"description": (p.get("description") or "")[:200],
|
||||
"visibility": p.get("visibility", ""),
|
||||
"default_branch": p.get("default_branch", ""),
|
||||
"web_url": p.get("web_url", ""),
|
||||
"star_count": p.get("star_count", 0),
|
||||
"last_activity_at": p.get("last_activity_at", ""),
|
||||
})
|
||||
for p in data if isinstance(data, list) else []:
|
||||
projects.append(
|
||||
{
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"path_with_namespace": p.get("path_with_namespace", ""),
|
||||
"description": (p.get("description") or "")[:200],
|
||||
"visibility": p.get("visibility", ""),
|
||||
"default_branch": p.get("default_branch", ""),
|
||||
"web_url": p.get("web_url", ""),
|
||||
"star_count": p.get("star_count", 0),
|
||||
"last_activity_at": p.get("last_activity_at", ""),
|
||||
}
|
||||
)
|
||||
return {"projects": projects, "count": len(projects)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -233,19 +239,21 @@ def register_tools(
|
||||
return data
|
||||
|
||||
issues = []
|
||||
for i in (data if isinstance(data, list) else []):
|
||||
for i in data if isinstance(data, list) else []:
|
||||
assignees = [a.get("username", "") for a in i.get("assignees", [])]
|
||||
issues.append({
|
||||
"iid": i.get("iid"),
|
||||
"title": i.get("title", ""),
|
||||
"state": i.get("state", ""),
|
||||
"labels": i.get("labels", []),
|
||||
"assignees": assignees,
|
||||
"author": (i.get("author") or {}).get("username", ""),
|
||||
"created_at": i.get("created_at", ""),
|
||||
"updated_at": i.get("updated_at", ""),
|
||||
"web_url": i.get("web_url", ""),
|
||||
})
|
||||
issues.append(
|
||||
{
|
||||
"iid": i.get("iid"),
|
||||
"title": i.get("title", ""),
|
||||
"state": i.get("state", ""),
|
||||
"labels": i.get("labels", []),
|
||||
"assignees": assignees,
|
||||
"author": (i.get("author") or {}).get("username", ""),
|
||||
"created_at": i.get("created_at", ""),
|
||||
"updated_at": i.get("updated_at", ""),
|
||||
"web_url": i.get("web_url", ""),
|
||||
}
|
||||
)
|
||||
return {"issues": issues, "count": len(issues)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -375,16 +383,18 @@ def register_tools(
|
||||
return data
|
||||
|
||||
mrs = []
|
||||
for mr in (data if isinstance(data, list) else []):
|
||||
mrs.append({
|
||||
"iid": mr.get("iid"),
|
||||
"title": mr.get("title", ""),
|
||||
"state": mr.get("state", ""),
|
||||
"source_branch": mr.get("source_branch", ""),
|
||||
"target_branch": mr.get("target_branch", ""),
|
||||
"author": (mr.get("author") or {}).get("username", ""),
|
||||
"web_url": mr.get("web_url", ""),
|
||||
"created_at": mr.get("created_at", ""),
|
||||
"updated_at": mr.get("updated_at", ""),
|
||||
})
|
||||
for mr in data if isinstance(data, list) else []:
|
||||
mrs.append(
|
||||
{
|
||||
"iid": mr.get("iid"),
|
||||
"title": mr.get("title", ""),
|
||||
"state": mr.get("state", ""),
|
||||
"source_branch": mr.get("source_branch", ""),
|
||||
"target_branch": mr.get("target_branch", ""),
|
||||
"author": (mr.get("author") or {}).get("username", ""),
|
||||
"web_url": mr.get("web_url", ""),
|
||||
"created_at": mr.get("created_at", ""),
|
||||
"updated_at": mr.get("updated_at", ""),
|
||||
}
|
||||
)
|
||||
return {"merge_requests": mrs, "count": len(mrs)}
|
||||
|
||||
+32
-21
@@ -51,9 +51,13 @@ def _get(endpoint: str, token: str, base: str = GSC_API) -> dict[str, Any]:
|
||||
return {"error": f"Request failed: {e!s}"}
|
||||
|
||||
|
||||
def _post(endpoint: str, token: str, body: dict | None = None, base: str = GSC_API) -> dict[str, Any]:
|
||||
def _post(
|
||||
endpoint: str, token: str, body: dict | None = None, base: str = GSC_API
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{base}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0)
|
||||
resp = httpx.post(
|
||||
f"{base}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your GOOGLE_SEARCH_CONSOLE_TOKEN."}
|
||||
if resp.status_code == 403:
|
||||
@@ -77,6 +81,7 @@ def _auth_error() -> dict[str, Any]:
|
||||
def _encode_site(site_url: str) -> str:
|
||||
"""URL-encode the site URL for API paths."""
|
||||
import urllib.parse
|
||||
|
||||
return urllib.parse.quote(site_url, safe="")
|
||||
|
||||
|
||||
@@ -130,13 +135,15 @@ def register_tools(
|
||||
|
||||
rows = []
|
||||
for r in data.get("rows", []):
|
||||
rows.append({
|
||||
"keys": r.get("keys", []),
|
||||
"clicks": r.get("clicks", 0),
|
||||
"impressions": r.get("impressions", 0),
|
||||
"ctr": round(r.get("ctr", 0), 4),
|
||||
"position": round(r.get("position", 0), 1),
|
||||
})
|
||||
rows.append(
|
||||
{
|
||||
"keys": r.get("keys", []),
|
||||
"clicks": r.get("clicks", 0),
|
||||
"impressions": r.get("impressions", 0),
|
||||
"ctr": round(r.get("ctr", 0), 4),
|
||||
"position": round(r.get("position", 0), 1),
|
||||
}
|
||||
)
|
||||
return {"site_url": site_url, "rows": rows, "count": len(rows)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -157,10 +164,12 @@ def register_tools(
|
||||
|
||||
sites = []
|
||||
for s in data.get("siteEntry", []):
|
||||
sites.append({
|
||||
"site_url": s.get("siteUrl", ""),
|
||||
"permission_level": s.get("permissionLevel", ""),
|
||||
})
|
||||
sites.append(
|
||||
{
|
||||
"site_url": s.get("siteUrl", ""),
|
||||
"permission_level": s.get("permissionLevel", ""),
|
||||
}
|
||||
)
|
||||
return {"sites": sites}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -187,14 +196,16 @@ def register_tools(
|
||||
|
||||
sitemaps = []
|
||||
for s in data.get("sitemap", []):
|
||||
sitemaps.append({
|
||||
"path": s.get("path", ""),
|
||||
"last_submitted": s.get("lastSubmitted", ""),
|
||||
"is_pending": s.get("isPending", False),
|
||||
"is_index": s.get("isSitemapsIndex", False),
|
||||
"warnings": s.get("warnings", 0),
|
||||
"errors": s.get("errors", 0),
|
||||
})
|
||||
sitemaps.append(
|
||||
{
|
||||
"path": s.get("path", ""),
|
||||
"last_submitted": s.get("lastSubmitted", ""),
|
||||
"is_pending": s.get("isPending", False),
|
||||
"is_index": s.get("isSitemapsIndex", False),
|
||||
"warnings": s.get("warnings", 0),
|
||||
"errors": s.get("errors", 0),
|
||||
}
|
||||
)
|
||||
return {"site_url": site_url, "sitemaps": sitemaps}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -42,7 +42,9 @@ def _get(path: str, api_key: str, params: dict[str, Any] | None = None) -> dict[
|
||||
if resp.status_code == 400:
|
||||
return {"error": f"Bad request: {resp.text[:500]}"}
|
||||
if resp.status_code == 403:
|
||||
return {"error": "Forbidden. The spreadsheet may not be public or the API key is invalid."}
|
||||
return {
|
||||
"error": "Forbidden. The spreadsheet may not be public or the API key is invalid."
|
||||
}
|
||||
if resp.status_code == 404:
|
||||
return {"error": "Spreadsheet not found."}
|
||||
if resp.status_code != 200:
|
||||
@@ -99,13 +101,15 @@ def register_tools(
|
||||
for s in data.get("sheets", []):
|
||||
sp = s.get("properties", {})
|
||||
grid = sp.get("gridProperties", {})
|
||||
sheets.append({
|
||||
"title": sp.get("title", ""),
|
||||
"sheet_id": sp.get("sheetId"),
|
||||
"index": sp.get("index", 0),
|
||||
"row_count": grid.get("rowCount", 0),
|
||||
"column_count": grid.get("columnCount", 0),
|
||||
})
|
||||
sheets.append(
|
||||
{
|
||||
"title": sp.get("title", ""),
|
||||
"sheet_id": sp.get("sheetId"),
|
||||
"index": sp.get("index", 0),
|
||||
"row_count": grid.get("rowCount", 0),
|
||||
"column_count": grid.get("columnCount", 0),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"spreadsheet_id": data.get("spreadsheetId", ""),
|
||||
@@ -190,9 +194,11 @@ def register_tools(
|
||||
results = []
|
||||
for vr in data.get("valueRanges", []):
|
||||
values = vr.get("values", [])
|
||||
results.append({
|
||||
"range": vr.get("range", ""),
|
||||
"values": values,
|
||||
"row_count": len(values),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"range": vr.get("range", ""),
|
||||
"values": values,
|
||||
"row_count": len(values),
|
||||
}
|
||||
)
|
||||
return {"ranges": results, "count": len(results)}
|
||||
|
||||
@@ -107,16 +107,18 @@ def register_tools(
|
||||
return data
|
||||
|
||||
jobs = []
|
||||
for j in (data if isinstance(data, list) else []):
|
||||
jobs.append({
|
||||
"id": j.get("id"),
|
||||
"name": j.get("name", ""),
|
||||
"status": j.get("status", ""),
|
||||
"departments": [d.get("name", "") for d in j.get("departments", [])],
|
||||
"offices": [o.get("name", "") for o in j.get("offices", [])],
|
||||
"created_at": j.get("created_at", ""),
|
||||
"updated_at": j.get("updated_at", ""),
|
||||
})
|
||||
for j in data if isinstance(data, list) else []:
|
||||
jobs.append(
|
||||
{
|
||||
"id": j.get("id"),
|
||||
"name": j.get("name", ""),
|
||||
"status": j.get("status", ""),
|
||||
"departments": [d.get("name", "") for d in j.get("departments", [])],
|
||||
"offices": [o.get("name", "") for o in j.get("offices", [])],
|
||||
"created_at": j.get("created_at", ""),
|
||||
"updated_at": j.get("updated_at", ""),
|
||||
}
|
||||
)
|
||||
return {"jobs": jobs, "count": len(jobs)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -150,8 +152,7 @@ def register_tools(
|
||||
"departments": [d.get("name", "") for d in data.get("departments", [])],
|
||||
"offices": [o.get("name", "") for o in data.get("offices", [])],
|
||||
"openings": [
|
||||
{"id": o.get("id"), "status": o.get("status", "")}
|
||||
for o in data.get("openings", [])
|
||||
{"id": o.get("id"), "status": o.get("status", "")} for o in data.get("openings", [])
|
||||
],
|
||||
"created_at": data.get("created_at", ""),
|
||||
"updated_at": data.get("updated_at", ""),
|
||||
@@ -195,17 +196,19 @@ def register_tools(
|
||||
return data
|
||||
|
||||
candidates = []
|
||||
for c in (data if isinstance(data, list) else []):
|
||||
candidates.append({
|
||||
"id": c.get("id"),
|
||||
"first_name": c.get("first_name", ""),
|
||||
"last_name": c.get("last_name", ""),
|
||||
"company": c.get("company", ""),
|
||||
"title": c.get("title", ""),
|
||||
"tags": c.get("tags", []),
|
||||
"application_ids": c.get("application_ids", []),
|
||||
"created_at": c.get("created_at", ""),
|
||||
})
|
||||
for c in data if isinstance(data, list) else []:
|
||||
candidates.append(
|
||||
{
|
||||
"id": c.get("id"),
|
||||
"first_name": c.get("first_name", ""),
|
||||
"last_name": c.get("last_name", ""),
|
||||
"company": c.get("company", ""),
|
||||
"title": c.get("title", ""),
|
||||
"tags": c.get("tags", []),
|
||||
"application_ids": c.get("application_ids", []),
|
||||
"created_at": c.get("created_at", ""),
|
||||
}
|
||||
)
|
||||
return {"candidates": candidates, "count": len(candidates)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -285,18 +288,20 @@ def register_tools(
|
||||
return data
|
||||
|
||||
apps = []
|
||||
for a in (data if isinstance(data, list) else []):
|
||||
for a in data if isinstance(data, list) else []:
|
||||
stage = a.get("current_stage") or {}
|
||||
jobs = [j.get("name", "") for j in a.get("jobs", [])]
|
||||
apps.append({
|
||||
"id": a.get("id"),
|
||||
"candidate_id": a.get("candidate_id"),
|
||||
"status": a.get("status", ""),
|
||||
"current_stage": stage.get("name", ""),
|
||||
"jobs": jobs,
|
||||
"applied_at": a.get("applied_at", ""),
|
||||
"last_activity_at": a.get("last_activity_at", ""),
|
||||
})
|
||||
apps.append(
|
||||
{
|
||||
"id": a.get("id"),
|
||||
"candidate_id": a.get("candidate_id"),
|
||||
"status": a.get("status", ""),
|
||||
"current_stage": stage.get("name", ""),
|
||||
"jobs": jobs,
|
||||
"applied_at": a.get("applied_at", ""),
|
||||
"last_activity_at": a.get("last_activity_at", ""),
|
||||
}
|
||||
)
|
||||
return {"applications": apps, "count": len(apps)}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -29,7 +29,9 @@ def _get_token(credentials: CredentialStoreAdapter | None) -> str | None:
|
||||
return os.getenv("HUGGINGFACE_TOKEN")
|
||||
|
||||
|
||||
def _get(path: str, token: str | None, params: dict[str, Any] | None = None) -> dict[str, Any] | list:
|
||||
def _get(
|
||||
path: str, token: str | None, params: dict[str, Any] | None = None
|
||||
) -> dict[str, Any] | list:
|
||||
"""Make a GET request to the HuggingFace Hub API."""
|
||||
headers: dict[str, str] = {}
|
||||
if token:
|
||||
@@ -106,15 +108,17 @@ def register_tools(
|
||||
|
||||
models = []
|
||||
for m in data if isinstance(data, list) else []:
|
||||
models.append({
|
||||
"id": m.get("id", ""),
|
||||
"author": m.get("author", ""),
|
||||
"downloads": m.get("downloads", 0),
|
||||
"likes": m.get("likes", 0),
|
||||
"pipeline_tag": m.get("pipeline_tag", ""),
|
||||
"tags": m.get("tags", [])[:10],
|
||||
"last_modified": m.get("lastModified", ""),
|
||||
})
|
||||
models.append(
|
||||
{
|
||||
"id": m.get("id", ""),
|
||||
"author": m.get("author", ""),
|
||||
"downloads": m.get("downloads", 0),
|
||||
"likes": m.get("likes", 0),
|
||||
"pipeline_tag": m.get("pipeline_tag", ""),
|
||||
"tags": m.get("tags", [])[:10],
|
||||
"last_modified": m.get("lastModified", ""),
|
||||
}
|
||||
)
|
||||
return {"models": models, "count": len(models)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -193,14 +197,16 @@ def register_tools(
|
||||
|
||||
datasets = []
|
||||
for d in data if isinstance(data, list) else []:
|
||||
datasets.append({
|
||||
"id": d.get("id", ""),
|
||||
"author": d.get("author", ""),
|
||||
"downloads": d.get("downloads", 0),
|
||||
"likes": d.get("likes", 0),
|
||||
"tags": d.get("tags", [])[:10],
|
||||
"last_modified": d.get("lastModified", ""),
|
||||
})
|
||||
datasets.append(
|
||||
{
|
||||
"id": d.get("id", ""),
|
||||
"author": d.get("author", ""),
|
||||
"downloads": d.get("downloads", 0),
|
||||
"likes": d.get("likes", 0),
|
||||
"tags": d.get("tags", [])[:10],
|
||||
"last_modified": d.get("lastModified", ""),
|
||||
}
|
||||
)
|
||||
return {"datasets": datasets, "count": len(datasets)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -276,14 +282,16 @@ def register_tools(
|
||||
|
||||
spaces = []
|
||||
for s in data if isinstance(data, list) else []:
|
||||
spaces.append({
|
||||
"id": s.get("id", ""),
|
||||
"author": s.get("author", ""),
|
||||
"likes": s.get("likes", 0),
|
||||
"sdk": s.get("sdk", ""),
|
||||
"tags": s.get("tags", [])[:10],
|
||||
"last_modified": s.get("lastModified", ""),
|
||||
})
|
||||
spaces.append(
|
||||
{
|
||||
"id": s.get("id", ""),
|
||||
"author": s.get("author", ""),
|
||||
"likes": s.get("likes", 0),
|
||||
"sdk": s.get("sdk", ""),
|
||||
"tags": s.get("tags", [])[:10],
|
||||
"last_modified": s.get("lastModified", ""),
|
||||
}
|
||||
)
|
||||
return {"spaces": spaces, "count": len(spaces)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -304,8 +312,7 @@ def register_tools(
|
||||
|
||||
u = data if isinstance(data, dict) else {}
|
||||
orgs = [
|
||||
{"name": o.get("name", ""), "role": o.get("roleInOrg", "")}
|
||||
for o in u.get("orgs", [])
|
||||
{"name": o.get("name", ""), "role": o.get("roleInOrg", "")} for o in u.get("orgs", [])
|
||||
]
|
||||
return {
|
||||
"name": u.get("name", ""),
|
||||
|
||||
@@ -21,7 +21,9 @@ if TYPE_CHECKING:
|
||||
from aden_tools.credentials import CredentialStoreAdapter
|
||||
|
||||
|
||||
def _get_credentials(credentials: CredentialStoreAdapter | None) -> tuple[str | None, str | None, str | None]:
|
||||
def _get_credentials(
|
||||
credentials: CredentialStoreAdapter | None,
|
||||
) -> tuple[str | None, str | None, str | None]:
|
||||
"""Return (domain, email, api_token)."""
|
||||
if credentials is not None:
|
||||
domain = credentials.get("jira_domain")
|
||||
@@ -44,9 +46,7 @@ def _auth_header(email: str, token: str) -> str:
|
||||
return f"Basic {encoded}"
|
||||
|
||||
|
||||
def _request(
|
||||
method: str, url: str, email: str, token: str, **kwargs: Any
|
||||
) -> dict[str, Any]:
|
||||
def _request(method: str, url: str, email: str, token: str, **kwargs: Any) -> dict[str, Any]:
|
||||
"""Make a request to the Jira API."""
|
||||
headers = kwargs.pop("headers", {})
|
||||
headers["Authorization"] = _auth_header(email, token)
|
||||
@@ -159,14 +159,16 @@ def register_tools(
|
||||
assignee = f.get("assignee") or {}
|
||||
priority = f.get("priority") or {}
|
||||
issuetype = f.get("issuetype") or {}
|
||||
issues.append({
|
||||
"key": issue.get("key", ""),
|
||||
"summary": f.get("summary", ""),
|
||||
"status": status.get("name", ""),
|
||||
"assignee": assignee.get("displayName", ""),
|
||||
"priority": priority.get("name", ""),
|
||||
"issuetype": issuetype.get("name", ""),
|
||||
})
|
||||
issues.append(
|
||||
{
|
||||
"key": issue.get("key", ""),
|
||||
"summary": f.get("summary", ""),
|
||||
"status": status.get("name", ""),
|
||||
"assignee": assignee.get("displayName", ""),
|
||||
"priority": priority.get("name", ""),
|
||||
"issuetype": issuetype.get("name", ""),
|
||||
}
|
||||
)
|
||||
return {"issues": issues, "count": len(issues)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -299,12 +301,14 @@ def register_tools(
|
||||
|
||||
projects = []
|
||||
for p in data.get("values", []):
|
||||
projects.append({
|
||||
"key": p.get("key", ""),
|
||||
"name": p.get("name", ""),
|
||||
"id": p.get("id", ""),
|
||||
"project_type": p.get("projectTypeKey", ""),
|
||||
})
|
||||
projects.append(
|
||||
{
|
||||
"key": p.get("key", ""),
|
||||
"name": p.get("name", ""),
|
||||
"id": p.get("id", ""),
|
||||
"project_type": p.get("projectTypeKey", ""),
|
||||
}
|
||||
)
|
||||
return {"projects": projects, "count": len(projects)}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -19,9 +19,15 @@ def _get_config() -> tuple[str, str, dict] | dict:
|
||||
rest_url = os.getenv("KAFKA_REST_URL", "").rstrip("/")
|
||||
cluster_id = os.getenv("KAFKA_CLUSTER_ID", "")
|
||||
if not rest_url:
|
||||
return {"error": "KAFKA_REST_URL is required", "help": "Set KAFKA_REST_URL environment variable"}
|
||||
return {
|
||||
"error": "KAFKA_REST_URL is required",
|
||||
"help": "Set KAFKA_REST_URL environment variable",
|
||||
}
|
||||
if not cluster_id:
|
||||
return {"error": "KAFKA_CLUSTER_ID is required", "help": "Set KAFKA_CLUSTER_ID environment variable"}
|
||||
return {
|
||||
"error": "KAFKA_CLUSTER_ID is required",
|
||||
"help": "Set KAFKA_CLUSTER_ID environment variable",
|
||||
}
|
||||
|
||||
headers: dict[str, str] = {"Content-Type": "application/json"}
|
||||
api_key = os.getenv("KAFKA_API_KEY", "")
|
||||
@@ -210,7 +216,9 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"id": g.get("consumer_group_id"),
|
||||
"is_simple": g.get("is_simple"),
|
||||
"state": g.get("state"),
|
||||
"coordinator_id": g.get("coordinator", {}).get("related") if isinstance(g.get("coordinator"), dict) else None,
|
||||
"coordinator_id": g.get("coordinator", {}).get("related")
|
||||
if isinstance(g.get("coordinator"), dict)
|
||||
else None,
|
||||
}
|
||||
for g in groups
|
||||
],
|
||||
|
||||
@@ -91,7 +91,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "LUSHA_API_KEY is required", "help": "Set LUSHA_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "LUSHA_API_KEY is required",
|
||||
"help": "Set LUSHA_API_KEY environment variable",
|
||||
}
|
||||
|
||||
params: dict[str, str] = {}
|
||||
if email:
|
||||
@@ -125,7 +128,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "LUSHA_API_KEY is required", "help": "Set LUSHA_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "LUSHA_API_KEY is required",
|
||||
"help": "Set LUSHA_API_KEY environment variable",
|
||||
}
|
||||
|
||||
params: dict[str, str] = {}
|
||||
if domain:
|
||||
@@ -164,7 +170,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "LUSHA_API_KEY is required", "help": "Set LUSHA_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "LUSHA_API_KEY is required",
|
||||
"help": "Set LUSHA_API_KEY environment variable",
|
||||
}
|
||||
|
||||
contacts_include: dict[str, Any] = {}
|
||||
companies_include: dict[str, Any] = {}
|
||||
@@ -240,7 +249,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "LUSHA_API_KEY is required", "help": "Set LUSHA_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "LUSHA_API_KEY is required",
|
||||
"help": "Set LUSHA_API_KEY environment variable",
|
||||
}
|
||||
|
||||
companies_include: dict[str, Any] = {}
|
||||
if company_names:
|
||||
@@ -281,7 +293,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""Get Lusha API credit usage statistics."""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "LUSHA_API_KEY is required", "help": "Set LUSHA_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "LUSHA_API_KEY is required",
|
||||
"help": "Set LUSHA_API_KEY environment variable",
|
||||
}
|
||||
|
||||
data = _get(f"{BASE_URL}/account/usage", headers)
|
||||
if "error" in data:
|
||||
|
||||
@@ -43,7 +43,9 @@ def _get(endpoint: str, token: str, params: dict[str, Any] | None = None) -> dic
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Access token may be expired or invalid."}
|
||||
if resp.status_code == 403:
|
||||
return {"error": f"Forbidden. Missing required permission scope. Details: {resp.text[:300]}"}
|
||||
return {
|
||||
"error": f"Forbidden. Missing required permission scope. Details: {resp.text[:300]}"
|
||||
}
|
||||
if resp.status_code != 200:
|
||||
return {"error": f"Microsoft Graph API error {resp.status_code}: {resp.text[:500]}"}
|
||||
return resp.json()
|
||||
@@ -61,7 +63,9 @@ def _post(endpoint: str, token: str, json_body: dict[str, Any]) -> dict[str, Any
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Access token may be expired or invalid."}
|
||||
if resp.status_code == 403:
|
||||
return {"error": f"Forbidden. Missing required permission scope. Details: {resp.text[:300]}"}
|
||||
return {
|
||||
"error": f"Forbidden. Missing required permission scope. Details: {resp.text[:300]}"
|
||||
}
|
||||
if resp.status_code not in (200, 201, 202):
|
||||
return {"error": f"Microsoft Graph API error {resp.status_code}: {resp.text[:500]}"}
|
||||
if resp.status_code == 202:
|
||||
@@ -132,16 +136,18 @@ def register_tools(
|
||||
messages = []
|
||||
for msg in data.get("value", []):
|
||||
from_addr = msg.get("from", {}).get("emailAddress", {})
|
||||
messages.append({
|
||||
"id": msg.get("id", ""),
|
||||
"subject": msg.get("subject", ""),
|
||||
"from_name": from_addr.get("name", ""),
|
||||
"from_email": from_addr.get("address", ""),
|
||||
"receivedDateTime": msg.get("receivedDateTime", ""),
|
||||
"isRead": msg.get("isRead", False),
|
||||
"hasAttachments": msg.get("hasAttachments", False),
|
||||
"bodyPreview": msg.get("bodyPreview", ""),
|
||||
})
|
||||
messages.append(
|
||||
{
|
||||
"id": msg.get("id", ""),
|
||||
"subject": msg.get("subject", ""),
|
||||
"from_name": from_addr.get("name", ""),
|
||||
"from_email": from_addr.get("address", ""),
|
||||
"receivedDateTime": msg.get("receivedDateTime", ""),
|
||||
"isRead": msg.get("isRead", False),
|
||||
"hasAttachments": msg.get("hasAttachments", False),
|
||||
"bodyPreview": msg.get("bodyPreview", ""),
|
||||
}
|
||||
)
|
||||
return {"folder": folder, "messages": messages}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -170,7 +176,10 @@ def register_tools(
|
||||
|
||||
from_addr = data.get("from", {}).get("emailAddress", {})
|
||||
to_list = [
|
||||
{"name": r.get("emailAddress", {}).get("name", ""), "email": r.get("emailAddress", {}).get("address", "")}
|
||||
{
|
||||
"name": r.get("emailAddress", {}).get("name", ""),
|
||||
"email": r.get("emailAddress", {}).get("address", ""),
|
||||
}
|
||||
for r in data.get("toRecipients", [])
|
||||
]
|
||||
return {
|
||||
@@ -227,7 +236,9 @@ def register_tools(
|
||||
}
|
||||
if cc:
|
||||
message["ccRecipients"] = [
|
||||
{"emailAddress": {"address": addr.strip()}} for addr in cc.split(",") if addr.strip()
|
||||
{"emailAddress": {"address": addr.strip()}}
|
||||
for addr in cc.split(",")
|
||||
if addr.strip()
|
||||
]
|
||||
|
||||
payload = {"message": message, "saveToSentItems": save_to_sent}
|
||||
@@ -256,11 +267,13 @@ def register_tools(
|
||||
|
||||
teams = []
|
||||
for team in data.get("value", []):
|
||||
teams.append({
|
||||
"id": team.get("id", ""),
|
||||
"displayName": team.get("displayName", ""),
|
||||
"description": team.get("description", ""),
|
||||
})
|
||||
teams.append(
|
||||
{
|
||||
"id": team.get("id", ""),
|
||||
"displayName": team.get("displayName", ""),
|
||||
"description": team.get("description", ""),
|
||||
}
|
||||
)
|
||||
return {"teams": teams}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -288,12 +301,14 @@ def register_tools(
|
||||
|
||||
channels = []
|
||||
for ch in data.get("value", []):
|
||||
channels.append({
|
||||
"id": ch.get("id", ""),
|
||||
"displayName": ch.get("displayName", ""),
|
||||
"description": ch.get("description", ""),
|
||||
"membershipType": ch.get("membershipType", ""),
|
||||
})
|
||||
channels.append(
|
||||
{
|
||||
"id": ch.get("id", ""),
|
||||
"displayName": ch.get("displayName", ""),
|
||||
"description": ch.get("description", ""),
|
||||
"membershipType": ch.get("membershipType", ""),
|
||||
}
|
||||
)
|
||||
return {"team_id": team_id, "channels": channels}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -363,13 +378,15 @@ def register_tools(
|
||||
messages = []
|
||||
for msg in data.get("value", []):
|
||||
from_info = msg.get("from", {}).get("user", {})
|
||||
messages.append({
|
||||
"id": msg.get("id", ""),
|
||||
"from_name": from_info.get("displayName", ""),
|
||||
"body": msg.get("body", {}).get("content", ""),
|
||||
"contentType": msg.get("body", {}).get("contentType", ""),
|
||||
"createdDateTime": msg.get("createdDateTime", ""),
|
||||
})
|
||||
messages.append(
|
||||
{
|
||||
"id": msg.get("id", ""),
|
||||
"from_name": from_info.get("displayName", ""),
|
||||
"body": msg.get("body", {}).get("content", ""),
|
||||
"contentType": msg.get("body", {}).get("contentType", ""),
|
||||
"createdDateTime": msg.get("createdDateTime", ""),
|
||||
}
|
||||
)
|
||||
return {"team_id": team_id, "channel_id": channel_id, "messages": messages}
|
||||
|
||||
# ── OneDrive ────────────────────────────────────────────────
|
||||
@@ -403,15 +420,17 @@ def register_tools(
|
||||
|
||||
files = []
|
||||
for item in data.get("value", []):
|
||||
files.append({
|
||||
"id": item.get("id", ""),
|
||||
"name": item.get("name", ""),
|
||||
"size": item.get("size", 0),
|
||||
"lastModifiedDateTime": item.get("lastModifiedDateTime", ""),
|
||||
"webUrl": item.get("webUrl", ""),
|
||||
"mimeType": item.get("file", {}).get("mimeType", ""),
|
||||
"path": item.get("parentReference", {}).get("path", ""),
|
||||
})
|
||||
files.append(
|
||||
{
|
||||
"id": item.get("id", ""),
|
||||
"name": item.get("name", ""),
|
||||
"size": item.get("size", 0),
|
||||
"lastModifiedDateTime": item.get("lastModifiedDateTime", ""),
|
||||
"webUrl": item.get("webUrl", ""),
|
||||
"mimeType": item.get("file", {}).get("mimeType", ""),
|
||||
"path": item.get("parentReference", {}).get("path", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "files": files}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -446,14 +465,16 @@ def register_tools(
|
||||
items = []
|
||||
for item in data.get("value", []):
|
||||
item_type = "folder" if "folder" in item else "file"
|
||||
items.append({
|
||||
"id": item.get("id", ""),
|
||||
"name": item.get("name", ""),
|
||||
"size": item.get("size", 0),
|
||||
"type": item_type,
|
||||
"lastModifiedDateTime": item.get("lastModifiedDateTime", ""),
|
||||
"webUrl": item.get("webUrl", ""),
|
||||
})
|
||||
items.append(
|
||||
{
|
||||
"id": item.get("id", ""),
|
||||
"name": item.get("name", ""),
|
||||
"size": item.get("size", 0),
|
||||
"type": item_type,
|
||||
"lastModifiedDateTime": item.get("lastModifiedDateTime", ""),
|
||||
"webUrl": item.get("webUrl", ""),
|
||||
}
|
||||
)
|
||||
return {"path": folder_path or "/", "items": items}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -23,7 +23,10 @@ def _get_config() -> tuple[str, str, str] | dict:
|
||||
api_key = os.getenv("MONGODB_API_KEY", "")
|
||||
data_source = os.getenv("MONGODB_DATA_SOURCE", "")
|
||||
if not url or not api_key:
|
||||
return {"error": "MONGODB_DATA_API_URL and MONGODB_API_KEY are required", "help": "Set MONGODB_DATA_API_URL and MONGODB_API_KEY environment variables"}
|
||||
return {
|
||||
"error": "MONGODB_DATA_API_URL and MONGODB_API_KEY are required",
|
||||
"help": "Set MONGODB_DATA_API_URL and MONGODB_API_KEY environment variables",
|
||||
}
|
||||
return url, api_key, data_source
|
||||
|
||||
|
||||
|
||||
@@ -73,19 +73,19 @@ def register_tools(
|
||||
if params["username"] and params["password"]:
|
||||
# SQL Server Authentication
|
||||
connection_string = (
|
||||
f'DRIVER={{ODBC Driver 17 for SQL Server}};'
|
||||
f'SERVER={params["server"]};'
|
||||
f'DATABASE={params["database"]};'
|
||||
f'UID={params["username"]};'
|
||||
f'PWD={params["password"]};'
|
||||
f"DRIVER={{ODBC Driver 17 for SQL Server}};"
|
||||
f"SERVER={params['server']};"
|
||||
f"DATABASE={params['database']};"
|
||||
f"UID={params['username']};"
|
||||
f"PWD={params['password']};"
|
||||
)
|
||||
else:
|
||||
# Windows Authentication
|
||||
connection_string = (
|
||||
f'DRIVER={{ODBC Driver 17 for SQL Server}};'
|
||||
f'SERVER={params["server"]};'
|
||||
f'DATABASE={params["database"]};'
|
||||
f'Trusted_Connection=yes;'
|
||||
f"DRIVER={{ODBC Driver 17 for SQL Server}};"
|
||||
f"SERVER={params['server']};"
|
||||
f"DATABASE={params['database']};"
|
||||
f"Trusted_Connection=yes;"
|
||||
)
|
||||
|
||||
connection = pyodbc.connect(connection_string, timeout=10)
|
||||
@@ -215,14 +215,14 @@ def register_tools(
|
||||
if not any(query_upper.startswith(kw) for kw in allowed_keywords):
|
||||
return {
|
||||
"error": f"Only {', '.join(allowed_keywords)} queries are allowed. "
|
||||
"Use mssql_execute_query for SELECT."
|
||||
"Use mssql_execute_query for SELECT."
|
||||
}
|
||||
|
||||
# Safety check for DELETE without WHERE
|
||||
if query_upper.startswith("DELETE") and "WHERE" not in query_upper:
|
||||
return {
|
||||
"error": "DELETE without WHERE clause is not allowed for safety. "
|
||||
"Add a WHERE clause or use DELETE FROM table WHERE 1=1 if intentional."
|
||||
"Add a WHERE clause or use DELETE FROM table WHERE 1=1 if intentional."
|
||||
}
|
||||
|
||||
connection, error = _create_connection()
|
||||
@@ -320,17 +320,21 @@ def register_tools(
|
||||
else:
|
||||
# Get detailed table schema
|
||||
# Check if table exists
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_NAME = ?
|
||||
""", table_name)
|
||||
""",
|
||||
table_name,
|
||||
)
|
||||
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return {"error": f"Table '{table_name}' not found"}
|
||||
|
||||
# Get columns
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
c.COLUMN_NAME,
|
||||
c.DATA_TYPE,
|
||||
@@ -348,7 +352,10 @@ def register_tools(
|
||||
) pk ON c.COLUMN_NAME = pk.COLUMN_NAME
|
||||
WHERE c.TABLE_NAME = ?
|
||||
ORDER BY c.ORDINAL_POSITION
|
||||
""", table_name, table_name)
|
||||
""",
|
||||
table_name,
|
||||
table_name,
|
||||
)
|
||||
|
||||
columns = []
|
||||
for row in cursor.fetchall():
|
||||
@@ -356,15 +363,18 @@ def register_tools(
|
||||
if row[2]: # Add length for varchar/nvarchar
|
||||
col_type += f"({row[2]})"
|
||||
|
||||
columns.append({
|
||||
"name": row[0],
|
||||
"type": col_type,
|
||||
"nullable": row[3] == "YES",
|
||||
"primary_key": bool(row[4]),
|
||||
})
|
||||
columns.append(
|
||||
{
|
||||
"name": row[0],
|
||||
"type": col_type,
|
||||
"nullable": row[3] == "YES",
|
||||
"primary_key": bool(row[4]),
|
||||
}
|
||||
)
|
||||
|
||||
# Get foreign keys
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
kcu.COLUMN_NAME,
|
||||
ccu.TABLE_NAME AS REFERENCED_TABLE,
|
||||
@@ -375,14 +385,18 @@ def register_tools(
|
||||
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
|
||||
ON rc.UNIQUE_CONSTRAINT_NAME = ccu.CONSTRAINT_NAME
|
||||
WHERE kcu.TABLE_NAME = ?
|
||||
""", table_name)
|
||||
""",
|
||||
table_name,
|
||||
)
|
||||
|
||||
foreign_keys = []
|
||||
for row in cursor.fetchall():
|
||||
foreign_keys.append({
|
||||
"column": row[0],
|
||||
"references": f"{row[1]}({row[2]})",
|
||||
})
|
||||
foreign_keys.append(
|
||||
{
|
||||
"column": row[0],
|
||||
"references": f"{row[1]}({row[2]})",
|
||||
}
|
||||
)
|
||||
|
||||
result = {
|
||||
"table": table_name,
|
||||
@@ -393,7 +407,8 @@ def register_tools(
|
||||
|
||||
# Optionally include indexes
|
||||
if include_indexes:
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
i.name AS INDEX_NAME,
|
||||
i.type_desc AS INDEX_TYPE,
|
||||
@@ -402,7 +417,9 @@ def register_tools(
|
||||
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
||||
WHERE i.object_id = OBJECT_ID(?)
|
||||
ORDER BY i.name, ic.key_ordinal
|
||||
""", table_name)
|
||||
""",
|
||||
table_name,
|
||||
)
|
||||
|
||||
indexes = {}
|
||||
for row in cursor.fetchall():
|
||||
@@ -489,10 +506,12 @@ def register_tools(
|
||||
row_dict[column] = value
|
||||
rows.append(row_dict)
|
||||
|
||||
result_sets.append({
|
||||
"columns": columns,
|
||||
"rows": rows,
|
||||
})
|
||||
result_sets.append(
|
||||
{
|
||||
"columns": columns,
|
||||
"rows": rows,
|
||||
}
|
||||
)
|
||||
|
||||
if not cursor.nextset():
|
||||
break
|
||||
|
||||
@@ -38,9 +38,7 @@ def _headers(token: str) -> dict[str, str]:
|
||||
}
|
||||
|
||||
|
||||
def _request(
|
||||
method: str, path: str, token: str, **kwargs: Any
|
||||
) -> dict[str, Any]:
|
||||
def _request(method: str, path: str, token: str, **kwargs: Any) -> dict[str, Any]:
|
||||
"""Make a request to the Notion API."""
|
||||
try:
|
||||
resp = getattr(httpx, method)(
|
||||
@@ -130,14 +128,16 @@ def register_tools(
|
||||
elif obj_type == "database":
|
||||
title_parts = item.get("title", [])
|
||||
title = "".join(p.get("text", {}).get("content", "") for p in title_parts)
|
||||
results.append({
|
||||
"id": item.get("id", ""),
|
||||
"object": obj_type,
|
||||
"title": title,
|
||||
"url": item.get("url", ""),
|
||||
"created_time": item.get("created_time", ""),
|
||||
"last_edited_time": item.get("last_edited_time", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"id": item.get("id", ""),
|
||||
"object": obj_type,
|
||||
"title": title,
|
||||
"url": item.get("url", ""),
|
||||
"created_time": item.get("created_time", ""),
|
||||
"last_edited_time": item.get("last_edited_time", ""),
|
||||
}
|
||||
)
|
||||
return {"results": results, "count": len(results), "has_more": data.get("has_more", False)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -245,9 +245,7 @@ def register_tools(
|
||||
{
|
||||
"object": "block",
|
||||
"type": "paragraph",
|
||||
"paragraph": {
|
||||
"rich_text": [{"type": "text", "text": {"content": content}}]
|
||||
},
|
||||
"paragraph": {"rich_text": [{"type": "text", "text": {"content": content}}]},
|
||||
}
|
||||
]
|
||||
|
||||
@@ -303,13 +301,15 @@ def register_tools(
|
||||
pages = []
|
||||
for item in data.get("results", []):
|
||||
title = _extract_title(item.get("properties", {}))
|
||||
pages.append({
|
||||
"id": item.get("id", ""),
|
||||
"title": title,
|
||||
"url": item.get("url", ""),
|
||||
"created_time": item.get("created_time", ""),
|
||||
"last_edited_time": item.get("last_edited_time", ""),
|
||||
})
|
||||
pages.append(
|
||||
{
|
||||
"id": item.get("id", ""),
|
||||
"title": title,
|
||||
"url": item.get("url", ""),
|
||||
"created_time": item.get("created_time", ""),
|
||||
"last_edited_time": item.get("last_edited_time", ""),
|
||||
}
|
||||
)
|
||||
return {"pages": pages, "count": len(pages), "has_more": data.get("has_more", False)}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -68,10 +68,7 @@ def _extract_incident(inc: dict) -> dict:
|
||||
"html_url": inc.get("html_url"),
|
||||
"service": inc.get("service", {}).get("summary"),
|
||||
"service_id": inc.get("service", {}).get("id"),
|
||||
"assignments": [
|
||||
a.get("assignee", {}).get("summary")
|
||||
for a in inc.get("assignments", [])
|
||||
],
|
||||
"assignments": [a.get("assignee", {}).get("summary") for a in inc.get("assignments", [])],
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +96,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "PAGERDUTY_API_KEY is required", "help": "Set PAGERDUTY_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "PAGERDUTY_API_KEY is required",
|
||||
"help": "Set PAGERDUTY_API_KEY environment variable",
|
||||
}
|
||||
|
||||
params: dict[str, Any] = {"limit": min(limit, 100)}
|
||||
if status:
|
||||
@@ -135,7 +135,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "PAGERDUTY_API_KEY is required", "help": "Set PAGERDUTY_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "PAGERDUTY_API_KEY is required",
|
||||
"help": "Set PAGERDUTY_API_KEY environment variable",
|
||||
}
|
||||
if not incident_id:
|
||||
return {"error": "incident_id is required"}
|
||||
|
||||
@@ -167,7 +170,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers(write=True)
|
||||
if headers is None:
|
||||
return {"error": "PAGERDUTY_API_KEY is required", "help": "Set PAGERDUTY_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "PAGERDUTY_API_KEY is required",
|
||||
"help": "Set PAGERDUTY_API_KEY environment variable",
|
||||
}
|
||||
if not title or not service_id:
|
||||
return {"error": "title and service_id are required"}
|
||||
|
||||
@@ -204,7 +210,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers(write=True)
|
||||
if headers is None:
|
||||
return {"error": "PAGERDUTY_API_KEY is required", "help": "Set PAGERDUTY_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "PAGERDUTY_API_KEY is required",
|
||||
"help": "Set PAGERDUTY_API_KEY environment variable",
|
||||
}
|
||||
if not incident_id:
|
||||
return {"error": "incident_id is required"}
|
||||
if not status:
|
||||
@@ -237,7 +246,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "PAGERDUTY_API_KEY is required", "help": "Set PAGERDUTY_API_KEY environment variable"}
|
||||
return {
|
||||
"error": "PAGERDUTY_API_KEY is required",
|
||||
"help": "Set PAGERDUTY_API_KEY environment variable",
|
||||
}
|
||||
|
||||
params: dict[str, Any] = {"limit": min(limit, 100)}
|
||||
if query:
|
||||
|
||||
@@ -119,15 +119,17 @@ def register_tools(
|
||||
|
||||
indexes = []
|
||||
for idx in data.get("indexes", []):
|
||||
indexes.append({
|
||||
"name": idx.get("name", ""),
|
||||
"dimension": idx.get("dimension", 0),
|
||||
"metric": idx.get("metric", ""),
|
||||
"host": idx.get("host", ""),
|
||||
"vector_type": idx.get("vector_type", "dense"),
|
||||
"state": (idx.get("status") or {}).get("state", ""),
|
||||
"ready": (idx.get("status") or {}).get("ready", False),
|
||||
})
|
||||
indexes.append(
|
||||
{
|
||||
"name": idx.get("name", ""),
|
||||
"dimension": idx.get("dimension", 0),
|
||||
"metric": idx.get("metric", ""),
|
||||
"host": idx.get("host", ""),
|
||||
"vector_type": idx.get("vector_type", "dense"),
|
||||
"state": (idx.get("status") or {}).get("state", ""),
|
||||
"ready": (idx.get("status") or {}).get("ready", False),
|
||||
}
|
||||
)
|
||||
return {"indexes": indexes, "count": len(indexes)}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -157,17 +157,19 @@ def register_tools(
|
||||
|
||||
deals = []
|
||||
for d in data.get("data") or []:
|
||||
deals.append({
|
||||
"id": d.get("id"),
|
||||
"title": d.get("title", ""),
|
||||
"value": d.get("value", 0),
|
||||
"currency": d.get("currency", ""),
|
||||
"status": d.get("status", ""),
|
||||
"person_name": (d.get("person_id") or {}).get("name", ""),
|
||||
"org_name": (d.get("org_id") or {}).get("name", ""),
|
||||
"stage_id": d.get("stage_id"),
|
||||
"add_time": d.get("add_time", ""),
|
||||
})
|
||||
deals.append(
|
||||
{
|
||||
"id": d.get("id"),
|
||||
"title": d.get("title", ""),
|
||||
"value": d.get("value", 0),
|
||||
"currency": d.get("currency", ""),
|
||||
"status": d.get("status", ""),
|
||||
"person_name": (d.get("person_id") or {}).get("name", ""),
|
||||
"org_name": (d.get("org_id") or {}).get("name", ""),
|
||||
"stage_id": d.get("stage_id"),
|
||||
"add_time": d.get("add_time", ""),
|
||||
}
|
||||
)
|
||||
return {"deals": deals, "count": len(deals)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -293,14 +295,16 @@ def register_tools(
|
||||
for p in data.get("data") or []:
|
||||
emails = p.get("email", [])
|
||||
phones = p.get("phone", [])
|
||||
persons.append({
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"email": emails[0].get("value", "") if emails else "",
|
||||
"phone": phones[0].get("value", "") if phones else "",
|
||||
"org_name": (p.get("org_id") or {}).get("name", ""),
|
||||
"open_deals_count": p.get("open_deals_count", 0),
|
||||
})
|
||||
persons.append(
|
||||
{
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"email": emails[0].get("value", "") if emails else "",
|
||||
"phone": phones[0].get("value", "") if phones else "",
|
||||
"org_name": (p.get("org_id") or {}).get("name", ""),
|
||||
"open_deals_count": p.get("open_deals_count", 0),
|
||||
}
|
||||
)
|
||||
return {"persons": persons, "count": len(persons)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -336,13 +340,15 @@ def register_tools(
|
||||
p = item.get("item", {})
|
||||
emails = p.get("emails", [])
|
||||
phones = p.get("phones", [])
|
||||
results.append({
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"email": emails[0] if emails else "",
|
||||
"phone": phones[0] if phones else "",
|
||||
"org_name": (p.get("organization") or {}).get("name", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"email": emails[0] if emails else "",
|
||||
"phone": phones[0] if phones else "",
|
||||
"org_name": (p.get("organization") or {}).get("name", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": results}
|
||||
|
||||
# ── Organizations ────────────────────────────────────────────
|
||||
@@ -375,13 +381,15 @@ def register_tools(
|
||||
|
||||
orgs = []
|
||||
for o in data.get("data") or []:
|
||||
orgs.append({
|
||||
"id": o.get("id"),
|
||||
"name": o.get("name", ""),
|
||||
"address": o.get("address", ""),
|
||||
"open_deals_count": o.get("open_deals_count", 0),
|
||||
"people_count": o.get("people_count", 0),
|
||||
})
|
||||
orgs.append(
|
||||
{
|
||||
"id": o.get("id"),
|
||||
"name": o.get("name", ""),
|
||||
"address": o.get("address", ""),
|
||||
"open_deals_count": o.get("open_deals_count", 0),
|
||||
"people_count": o.get("people_count", 0),
|
||||
}
|
||||
)
|
||||
return {"organizations": orgs, "count": len(orgs)}
|
||||
|
||||
# ── Activities ───────────────────────────────────────────────
|
||||
@@ -426,18 +434,20 @@ def register_tools(
|
||||
|
||||
activities = []
|
||||
for a in data.get("data") or []:
|
||||
activities.append({
|
||||
"id": a.get("id"),
|
||||
"subject": a.get("subject", ""),
|
||||
"type": a.get("type", ""),
|
||||
"done": a.get("done", False),
|
||||
"due_date": a.get("due_date", ""),
|
||||
"due_time": a.get("due_time", ""),
|
||||
"deal_title": a.get("deal_title", ""),
|
||||
"person_name": a.get("person_name", ""),
|
||||
"org_name": a.get("org_name", ""),
|
||||
"note": a.get("note", "")[:200] if a.get("note") else "",
|
||||
})
|
||||
activities.append(
|
||||
{
|
||||
"id": a.get("id"),
|
||||
"subject": a.get("subject", ""),
|
||||
"type": a.get("type", ""),
|
||||
"done": a.get("done", False),
|
||||
"due_date": a.get("due_date", ""),
|
||||
"due_time": a.get("due_time", ""),
|
||||
"deal_title": a.get("deal_title", ""),
|
||||
"person_name": a.get("person_name", ""),
|
||||
"org_name": a.get("org_name", ""),
|
||||
"note": a.get("note", "")[:200] if a.get("note") else "",
|
||||
}
|
||||
)
|
||||
return {"activities": activities, "count": len(activities)}
|
||||
|
||||
# ── Pipelines ────────────────────────────────────────────────
|
||||
@@ -462,13 +472,15 @@ def register_tools(
|
||||
|
||||
pipelines = []
|
||||
for p in data.get("data") or []:
|
||||
pipelines.append({
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"active": p.get("active", False),
|
||||
"deal_probability": p.get("deal_probability", False),
|
||||
"order_nr": p.get("order_nr", 0),
|
||||
})
|
||||
pipelines.append(
|
||||
{
|
||||
"id": p.get("id"),
|
||||
"name": p.get("name", ""),
|
||||
"active": p.get("active", False),
|
||||
"deal_probability": p.get("deal_probability", False),
|
||||
"order_nr": p.get("order_nr", 0),
|
||||
}
|
||||
)
|
||||
return {"pipelines": pipelines}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -498,13 +510,15 @@ def register_tools(
|
||||
|
||||
stages = []
|
||||
for s in data.get("data") or []:
|
||||
stages.append({
|
||||
"id": s.get("id"),
|
||||
"name": s.get("name", ""),
|
||||
"pipeline_id": s.get("pipeline_id"),
|
||||
"order_nr": s.get("order_nr", 0),
|
||||
"active_flag": s.get("active_flag", True),
|
||||
})
|
||||
stages.append(
|
||||
{
|
||||
"id": s.get("id"),
|
||||
"name": s.get("name", ""),
|
||||
"pipeline_id": s.get("pipeline_id"),
|
||||
"order_nr": s.get("order_nr", 0),
|
||||
"active_flag": s.get("active_flag", True),
|
||||
}
|
||||
)
|
||||
return {"stages": stages}
|
||||
|
||||
# ── Notes ────────────────────────────────────────────────────
|
||||
|
||||
@@ -41,7 +41,9 @@ def _get_env() -> str:
|
||||
return os.getenv("PLAID_ENV", DEFAULT_ENV)
|
||||
|
||||
|
||||
def _post(path: str, client_id: str, secret: str, body: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
def _post(
|
||||
path: str, client_id: str, secret: str, body: dict[str, Any] | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""Make a POST request to the Plaid API."""
|
||||
env = _get_env()
|
||||
base = BASE_URLS.get(env, BASE_URLS["sandbox"])
|
||||
@@ -101,17 +103,19 @@ def register_tools(
|
||||
accounts = []
|
||||
for a in data.get("accounts", []):
|
||||
bal = a.get("balances") or {}
|
||||
accounts.append({
|
||||
"account_id": a.get("account_id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"official_name": a.get("official_name", ""),
|
||||
"type": a.get("type", ""),
|
||||
"subtype": a.get("subtype", ""),
|
||||
"mask": a.get("mask", ""),
|
||||
"available_balance": bal.get("available"),
|
||||
"current_balance": bal.get("current"),
|
||||
"currency": bal.get("iso_currency_code", ""),
|
||||
})
|
||||
accounts.append(
|
||||
{
|
||||
"account_id": a.get("account_id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"official_name": a.get("official_name", ""),
|
||||
"type": a.get("type", ""),
|
||||
"subtype": a.get("subtype", ""),
|
||||
"mask": a.get("mask", ""),
|
||||
"available_balance": bal.get("available"),
|
||||
"current_balance": bal.get("current"),
|
||||
"currency": bal.get("iso_currency_code", ""),
|
||||
}
|
||||
)
|
||||
return {"accounts": accounts, "count": len(accounts)}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -138,15 +142,17 @@ def register_tools(
|
||||
accounts = []
|
||||
for a in data.get("accounts", []):
|
||||
bal = a.get("balances") or {}
|
||||
accounts.append({
|
||||
"account_id": a.get("account_id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"type": a.get("type", ""),
|
||||
"available": bal.get("available"),
|
||||
"current": bal.get("current"),
|
||||
"limit": bal.get("limit"),
|
||||
"currency": bal.get("iso_currency_code", ""),
|
||||
})
|
||||
accounts.append(
|
||||
{
|
||||
"account_id": a.get("account_id", ""),
|
||||
"name": a.get("name", ""),
|
||||
"type": a.get("type", ""),
|
||||
"available": bal.get("available"),
|
||||
"current": bal.get("current"),
|
||||
"limit": bal.get("limit"),
|
||||
"currency": bal.get("iso_currency_code", ""),
|
||||
}
|
||||
)
|
||||
return {"accounts": accounts}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -250,17 +256,19 @@ def register_tools(
|
||||
|
||||
txns = []
|
||||
for t in data.get("transactions", []):
|
||||
txns.append({
|
||||
"transaction_id": t.get("transaction_id", ""),
|
||||
"account_id": t.get("account_id", ""),
|
||||
"amount": t.get("amount", 0),
|
||||
"date": t.get("date", ""),
|
||||
"name": t.get("name", ""),
|
||||
"merchant_name": t.get("merchant_name", ""),
|
||||
"category": t.get("category", []),
|
||||
"pending": t.get("pending", False),
|
||||
"currency": t.get("iso_currency_code", ""),
|
||||
})
|
||||
txns.append(
|
||||
{
|
||||
"transaction_id": t.get("transaction_id", ""),
|
||||
"account_id": t.get("account_id", ""),
|
||||
"amount": t.get("amount", 0),
|
||||
"date": t.get("date", ""),
|
||||
"name": t.get("name", ""),
|
||||
"merchant_name": t.get("merchant_name", ""),
|
||||
"category": t.get("category", []),
|
||||
"pending": t.get("pending", False),
|
||||
"currency": t.get("iso_currency_code", ""),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"transactions": txns,
|
||||
@@ -347,12 +355,14 @@ def register_tools(
|
||||
|
||||
institutions = []
|
||||
for inst in data.get("institutions", []):
|
||||
institutions.append({
|
||||
"institution_id": inst.get("institution_id", ""),
|
||||
"name": inst.get("name", ""),
|
||||
"products": inst.get("products", []),
|
||||
"country_codes": inst.get("country_codes", []),
|
||||
"url": inst.get("url", ""),
|
||||
"oauth": inst.get("oauth", False),
|
||||
})
|
||||
institutions.append(
|
||||
{
|
||||
"institution_id": inst.get("institution_id", ""),
|
||||
"name": inst.get("name", ""),
|
||||
"products": inst.get("products", []),
|
||||
"country_codes": inst.get("country_codes", []),
|
||||
"url": inst.get("url", ""),
|
||||
"oauth": inst.get("oauth", False),
|
||||
}
|
||||
)
|
||||
return {"institutions": institutions, "count": len(institutions)}
|
||||
|
||||
@@ -61,7 +61,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "POWERBI_ACCESS_TOKEN is required", "help": "Set POWERBI_ACCESS_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "POWERBI_ACCESS_TOKEN is required",
|
||||
"help": "Set POWERBI_ACCESS_TOKEN environment variable",
|
||||
}
|
||||
|
||||
params: dict[str, Any] = {"$top": top, "$skip": skip}
|
||||
if search:
|
||||
@@ -94,7 +97,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "POWERBI_ACCESS_TOKEN is required", "help": "Set POWERBI_ACCESS_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "POWERBI_ACCESS_TOKEN is required",
|
||||
"help": "Set POWERBI_ACCESS_TOKEN environment variable",
|
||||
}
|
||||
if not workspace_id:
|
||||
return {"error": "workspace_id is required"}
|
||||
|
||||
@@ -128,7 +134,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "POWERBI_ACCESS_TOKEN is required", "help": "Set POWERBI_ACCESS_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "POWERBI_ACCESS_TOKEN is required",
|
||||
"help": "Set POWERBI_ACCESS_TOKEN environment variable",
|
||||
}
|
||||
if not workspace_id:
|
||||
return {"error": "workspace_id is required"}
|
||||
|
||||
@@ -167,7 +176,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "POWERBI_ACCESS_TOKEN is required", "help": "Set POWERBI_ACCESS_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "POWERBI_ACCESS_TOKEN is required",
|
||||
"help": "Set POWERBI_ACCESS_TOKEN environment variable",
|
||||
}
|
||||
if not workspace_id or not dataset_id:
|
||||
return {"error": "workspace_id and dataset_id are required"}
|
||||
|
||||
@@ -194,7 +206,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if not headers:
|
||||
return {"error": "POWERBI_ACCESS_TOKEN is required", "help": "Set POWERBI_ACCESS_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "POWERBI_ACCESS_TOKEN is required",
|
||||
"help": "Set POWERBI_ACCESS_TOKEN environment variable",
|
||||
}
|
||||
if not workspace_id or not dataset_id:
|
||||
return {"error": "workspace_id and dataset_id are required"}
|
||||
|
||||
|
||||
@@ -113,7 +113,9 @@ def register_tools(
|
||||
result = resp.json()
|
||||
if result.get("status") != 1:
|
||||
errors = result.get("errors", [])
|
||||
return {"error": f"Pushover error: {', '.join(errors) if errors else resp.text[:300]}"}
|
||||
return {
|
||||
"error": f"Pushover error: {', '.join(errors) if errors else resp.text[:300]}"
|
||||
}
|
||||
out: dict[str, Any] = {"status": "sent", "request": result.get("request", "")}
|
||||
if "receipt" in result:
|
||||
out["receipt"] = result["receipt"]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Tests for Pushover tool."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from aden_tools.tools.pushover_tool.pushover_tool import (
|
||||
@@ -84,9 +85,7 @@ class TestPushoverClient:
|
||||
|
||||
@patch("aden_tools.tools.pushover_tool.pushover_tool.httpx.post")
|
||||
def test_validate_user_with_device(self, mock_post):
|
||||
mock_post.return_value = self._mock_response(
|
||||
json_data={"status": 1, "devices": ["iphone"]}
|
||||
)
|
||||
mock_post.return_value = self._mock_response(json_data={"status": 1, "devices": ["iphone"]})
|
||||
result = self.client.validate_user(device="iphone")
|
||||
call_kwargs = mock_post.call_args[1]["data"]
|
||||
assert call_kwargs["device"] == "iphone"
|
||||
@@ -103,6 +102,7 @@ class TestRegisterTools:
|
||||
def decorator(func):
|
||||
self.tools[func.__name__] = func
|
||||
return func
|
||||
|
||||
return decorator
|
||||
|
||||
self.mcp.tool = tool_decorator
|
||||
@@ -127,9 +127,7 @@ class TestRegisterTools:
|
||||
{"PUSHOVER_API_TOKEN": "test_token", "PUSHOVER_USER_KEY": "test_user"},
|
||||
)
|
||||
def test_pushover_send_notification_invalid_priority(self):
|
||||
result = self.tools["pushover_send_notification"](
|
||||
message="Hello!", priority=99
|
||||
)
|
||||
result = self.tools["pushover_send_notification"](message="Hello!", priority=99)
|
||||
assert "error" in result
|
||||
assert "priority" in result["error"]
|
||||
|
||||
|
||||
@@ -22,7 +22,10 @@ def _get_config() -> tuple[str, str] | dict:
|
||||
token = os.getenv("QUICKBOOKS_ACCESS_TOKEN", "")
|
||||
realm_id = os.getenv("QUICKBOOKS_REALM_ID", "")
|
||||
if not token or not realm_id:
|
||||
return {"error": "QUICKBOOKS_ACCESS_TOKEN and QUICKBOOKS_REALM_ID are required", "help": "Set QUICKBOOKS_ACCESS_TOKEN and QUICKBOOKS_REALM_ID environment variables"}
|
||||
return {
|
||||
"error": "QUICKBOOKS_ACCESS_TOKEN and QUICKBOOKS_REALM_ID are required",
|
||||
"help": "Set QUICKBOOKS_ACCESS_TOKEN and QUICKBOOKS_REALM_ID environment variables",
|
||||
}
|
||||
|
||||
use_sandbox = os.getenv("QUICKBOOKS_SANDBOX", "").lower() in ("1", "true")
|
||||
base = SANDBOX_URL if use_sandbox else PROD_URL
|
||||
@@ -245,6 +248,8 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"company_name": info.get("CompanyName"),
|
||||
"legal_name": info.get("LegalName"),
|
||||
"country": info.get("Country"),
|
||||
"email": info.get("Email", {}).get("Address") if isinstance(info.get("Email"), dict) else None,
|
||||
"email": info.get("Email", {}).get("Address")
|
||||
if isinstance(info.get("Email"), dict)
|
||||
else None,
|
||||
"fiscal_year_start": info.get("FiscalYearStartMonth"),
|
||||
}
|
||||
|
||||
@@ -87,19 +87,21 @@ def _extract_posts(listing: dict) -> list[dict[str, Any]]:
|
||||
if child.get("kind") != "t3":
|
||||
continue
|
||||
d = child.get("data", {})
|
||||
posts.append({
|
||||
"id": d.get("id", ""),
|
||||
"title": d.get("title", ""),
|
||||
"author": d.get("author", ""),
|
||||
"subreddit": d.get("subreddit", ""),
|
||||
"score": d.get("score", 0),
|
||||
"num_comments": d.get("num_comments", 0),
|
||||
"url": d.get("url", ""),
|
||||
"permalink": d.get("permalink", ""),
|
||||
"selftext": (d.get("selftext", "") or "")[:500],
|
||||
"created_utc": d.get("created_utc", 0),
|
||||
"is_self": d.get("is_self", False),
|
||||
})
|
||||
posts.append(
|
||||
{
|
||||
"id": d.get("id", ""),
|
||||
"title": d.get("title", ""),
|
||||
"author": d.get("author", ""),
|
||||
"subreddit": d.get("subreddit", ""),
|
||||
"score": d.get("score", 0),
|
||||
"num_comments": d.get("num_comments", 0),
|
||||
"url": d.get("url", ""),
|
||||
"permalink": d.get("permalink", ""),
|
||||
"selftext": (d.get("selftext", "") or "")[:500],
|
||||
"created_utc": d.get("created_utc", 0),
|
||||
"is_self": d.get("is_self", False),
|
||||
}
|
||||
)
|
||||
return posts
|
||||
|
||||
|
||||
@@ -260,13 +262,15 @@ def register_tools(
|
||||
if child.get("kind") != "t1":
|
||||
continue
|
||||
cd = child.get("data", {})
|
||||
comments.append({
|
||||
"id": cd.get("id", ""),
|
||||
"author": cd.get("author", ""),
|
||||
"body": (cd.get("body", "") or "")[:500],
|
||||
"score": cd.get("score", 0),
|
||||
"created_utc": cd.get("created_utc", 0),
|
||||
})
|
||||
comments.append(
|
||||
{
|
||||
"id": cd.get("id", ""),
|
||||
"author": cd.get("author", ""),
|
||||
"body": (cd.get("body", "") or "")[:500],
|
||||
"score": cd.get("score", 0),
|
||||
"created_utc": cd.get("created_utc", 0),
|
||||
}
|
||||
)
|
||||
|
||||
return {"post": post, "comments": comments, "comment_count": len(comments)}
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ def _get_config() -> tuple[str, str, str] | dict:
|
||||
secret_key = os.getenv("AWS_SECRET_ACCESS_KEY", "")
|
||||
region = os.getenv("AWS_REGION", "us-east-1")
|
||||
if not access_key or not secret_key:
|
||||
return {"error": "AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are required", "help": "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables"}
|
||||
return {
|
||||
"error": "AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are required",
|
||||
"help": "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables",
|
||||
}
|
||||
return access_key, secret_key, region
|
||||
|
||||
|
||||
@@ -62,22 +65,16 @@ def _api_call(
|
||||
"x-amz-target": f"RedshiftData.{action}",
|
||||
}
|
||||
signed_headers_str = ";".join(sorted(headers_to_sign.keys()))
|
||||
canonical_headers = "".join(
|
||||
f"{k}:{v}\n" for k, v in sorted(headers_to_sign.items())
|
||||
)
|
||||
canonical_headers = "".join(f"{k}:{v}\n" for k, v in sorted(headers_to_sign.items()))
|
||||
|
||||
canonical_request = (
|
||||
f"POST\n/\n\n{canonical_headers}\n{signed_headers_str}\n{payload_hash}"
|
||||
)
|
||||
canonical_request = f"POST\n/\n\n{canonical_headers}\n{signed_headers_str}\n{payload_hash}"
|
||||
credential_scope = f"{datestamp}/{region}/{SERVICE}/aws4_request"
|
||||
string_to_sign = (
|
||||
f"AWS4-HMAC-SHA256\n{amz_date}\n{credential_scope}\n"
|
||||
+ hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
|
||||
)
|
||||
signing_key = _get_signing_key(secret_key, datestamp, region)
|
||||
signature = hmac.new(
|
||||
signing_key, string_to_sign.encode("utf-8"), hashlib.sha256
|
||||
).hexdigest()
|
||||
signature = hmac.new(signing_key, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
|
||||
|
||||
auth_header = (
|
||||
f"AWS4-HMAC-SHA256 Credential={access_key}/{credential_scope}, "
|
||||
@@ -172,9 +169,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
if not statement_id:
|
||||
return {"error": "statement_id is required"}
|
||||
|
||||
data = _api_call(
|
||||
"DescribeStatement", {"Id": statement_id}, access_key, secret_key, region
|
||||
)
|
||||
data = _api_call("DescribeStatement", {"Id": statement_id}, access_key, secret_key, region)
|
||||
if "error" in data:
|
||||
return data
|
||||
|
||||
@@ -202,9 +197,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
if not statement_id:
|
||||
return {"error": "statement_id is required"}
|
||||
|
||||
data = _api_call(
|
||||
"GetStatementResult", {"Id": statement_id}, access_key, secret_key, region
|
||||
)
|
||||
data = _api_call("GetStatementResult", {"Id": statement_id}, access_key, secret_key, region)
|
||||
if "error" in data:
|
||||
return data
|
||||
|
||||
|
||||
@@ -162,16 +162,11 @@ def register_tools(
|
||||
return {"error": "object_type and record_id are required"}
|
||||
|
||||
try:
|
||||
url = (
|
||||
f"{instance_url}/services/data/{API_VERSION}"
|
||||
f"/sobjects/{object_type}/{record_id}"
|
||||
)
|
||||
url = f"{instance_url}/services/data/{API_VERSION}/sobjects/{object_type}/{record_id}"
|
||||
params = {}
|
||||
if fields:
|
||||
params["fields"] = fields
|
||||
resp = httpx.get(
|
||||
url, headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
resp = httpx.get(url, headers=_headers(token), params=params, timeout=30.0)
|
||||
return _handle_response(resp)
|
||||
except httpx.TimeoutException:
|
||||
return {"error": "Request timed out"}
|
||||
@@ -204,13 +199,8 @@ def register_tools(
|
||||
return {"error": "fields dict is required"}
|
||||
|
||||
try:
|
||||
url = (
|
||||
f"{instance_url}/services/data/{API_VERSION}"
|
||||
f"/sobjects/{object_type}"
|
||||
)
|
||||
resp = httpx.post(
|
||||
url, headers=_headers(token), json=fields, timeout=30.0
|
||||
)
|
||||
url = f"{instance_url}/services/data/{API_VERSION}/sobjects/{object_type}"
|
||||
resp = httpx.post(url, headers=_headers(token), json=fields, timeout=30.0)
|
||||
return _handle_response(resp)
|
||||
except httpx.TimeoutException:
|
||||
return {"error": "Request timed out"}
|
||||
@@ -245,13 +235,8 @@ def register_tools(
|
||||
return {"error": "fields dict is required"}
|
||||
|
||||
try:
|
||||
url = (
|
||||
f"{instance_url}/services/data/{API_VERSION}"
|
||||
f"/sobjects/{object_type}/{record_id}"
|
||||
)
|
||||
resp = httpx.patch(
|
||||
url, headers=_headers(token), json=fields, timeout=30.0
|
||||
)
|
||||
url = f"{instance_url}/services/data/{API_VERSION}/sobjects/{object_type}/{record_id}"
|
||||
resp = httpx.patch(url, headers=_headers(token), json=fields, timeout=30.0)
|
||||
return _handle_response(resp)
|
||||
except httpx.TimeoutException:
|
||||
return {"error": "Request timed out"}
|
||||
@@ -280,10 +265,7 @@ def register_tools(
|
||||
return {"error": "object_type is required"}
|
||||
|
||||
try:
|
||||
url = (
|
||||
f"{instance_url}/services/data/{API_VERSION}"
|
||||
f"/sobjects/{object_type}/describe"
|
||||
)
|
||||
url = f"{instance_url}/services/data/{API_VERSION}/sobjects/{object_type}/describe"
|
||||
resp = httpx.get(url, headers=_headers(token), timeout=30.0)
|
||||
result = _handle_response(resp)
|
||||
if "error" in result:
|
||||
@@ -296,14 +278,11 @@ def register_tools(
|
||||
"name": f.get("name"),
|
||||
"label": f.get("label"),
|
||||
"type": f.get("type"),
|
||||
"required": not f.get("nillable", True)
|
||||
and f.get("createable", False),
|
||||
"required": not f.get("nillable", True) and f.get("createable", False),
|
||||
}
|
||||
if f.get("picklistValues"):
|
||||
entry["picklist_values"] = [
|
||||
pv["value"]
|
||||
for pv in f["picklistValues"]
|
||||
if pv.get("active")
|
||||
pv["value"] for pv in f["picklistValues"] if pv.get("active")
|
||||
]
|
||||
fields_summary.append(entry)
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@ def _get_config() -> tuple[str, dict] | dict:
|
||||
username = os.getenv("SAP_USERNAME", "")
|
||||
password = os.getenv("SAP_PASSWORD", "")
|
||||
if not base_url or not username or not password:
|
||||
return {"error": "SAP_BASE_URL, SAP_USERNAME, and SAP_PASSWORD are required", "help": "Set SAP_BASE_URL, SAP_USERNAME, and SAP_PASSWORD environment variables"}
|
||||
return {
|
||||
"error": "SAP_BASE_URL, SAP_USERNAME, and SAP_PASSWORD are required",
|
||||
"help": "Set SAP_BASE_URL, SAP_USERNAME, and SAP_PASSWORD environment variables",
|
||||
}
|
||||
creds = base64.b64encode(f"{username}:{password}".encode()).decode()
|
||||
headers = {"Authorization": f"Basic {creds}", "Accept": "application/json"}
|
||||
return base_url, headers
|
||||
|
||||
@@ -19,16 +19,17 @@ def _get_config() -> tuple[str, dict] | dict:
|
||||
account = os.getenv("SNOWFLAKE_ACCOUNT", "").strip()
|
||||
token = os.getenv("SNOWFLAKE_TOKEN", "").strip()
|
||||
if not account or not token:
|
||||
return {"error": "SNOWFLAKE_ACCOUNT and SNOWFLAKE_TOKEN are required", "help": "Set SNOWFLAKE_ACCOUNT and SNOWFLAKE_TOKEN environment variables"}
|
||||
return {
|
||||
"error": "SNOWFLAKE_ACCOUNT and SNOWFLAKE_TOKEN are required",
|
||||
"help": "Set SNOWFLAKE_ACCOUNT and SNOWFLAKE_TOKEN environment variables",
|
||||
}
|
||||
base_url = f"https://{account}.snowflakecomputing.com/api/v2/statements"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
"User-Agent": "aden-tools/1.0",
|
||||
"X-Snowflake-Authorization-Token-Type": os.getenv(
|
||||
"SNOWFLAKE_TOKEN_TYPE", "OAUTH"
|
||||
),
|
||||
"X-Snowflake-Authorization-Token-Type": os.getenv("SNOWFLAKE_TOKEN_TYPE", "OAUTH"),
|
||||
}
|
||||
return base_url, headers
|
||||
|
||||
@@ -148,9 +149,7 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
if not statement_handle:
|
||||
return {"error": "statement_handle is required"}
|
||||
|
||||
resp = httpx.post(
|
||||
f"{base_url}/{statement_handle}/cancel", headers=headers, timeout=30
|
||||
)
|
||||
resp = httpx.post(f"{base_url}/{statement_handle}/cancel", headers=headers, timeout=30)
|
||||
if resp.status_code == 200:
|
||||
return {"result": "cancelled", "statement_handle": statement_handle}
|
||||
return {"error": f"HTTP {resp.status_code}: {resp.text[:500]}"}
|
||||
|
||||
@@ -393,7 +393,10 @@ def register_tools(
|
||||
response_data = resp.text
|
||||
|
||||
if resp.status_code >= 400:
|
||||
return {"error": f"Edge function error {resp.status_code}", "response": response_data}
|
||||
return {
|
||||
"error": f"Edge function error {resp.status_code}",
|
||||
"response": response_data,
|
||||
}
|
||||
return {"status_code": resp.status_code, "response": response_data}
|
||||
except httpx.TimeoutException:
|
||||
return {"error": "Edge function invocation timed out"}
|
||||
|
||||
@@ -18,7 +18,10 @@ def _get_config() -> tuple[str, dict] | dict:
|
||||
domain = os.getenv("TINES_DOMAIN", "").rstrip("/")
|
||||
api_key = os.getenv("TINES_API_KEY", "")
|
||||
if not domain or not api_key:
|
||||
return {"error": "TINES_DOMAIN and TINES_API_KEY are required", "help": "Set TINES_DOMAIN and TINES_API_KEY environment variables"}
|
||||
return {
|
||||
"error": "TINES_DOMAIN and TINES_API_KEY are required",
|
||||
"help": "Set TINES_DOMAIN and TINES_API_KEY environment variables",
|
||||
}
|
||||
base_url = f"https://{domain}/api/v1"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
|
||||
@@ -120,7 +120,10 @@ def register_tools(
|
||||
|
||||
url = f"{_base_url(sid)}/Messages.json"
|
||||
data = _request(
|
||||
"post", url, sid, token,
|
||||
"post",
|
||||
url,
|
||||
sid,
|
||||
token,
|
||||
data={"To": to, "From": from_number, "Body": body},
|
||||
)
|
||||
if "error" in data:
|
||||
@@ -156,7 +159,10 @@ def register_tools(
|
||||
|
||||
url = f"{_base_url(sid)}/Messages.json"
|
||||
data = _request(
|
||||
"post", url, sid, token,
|
||||
"post",
|
||||
url,
|
||||
sid,
|
||||
token,
|
||||
data={"To": wa_to, "From": wa_from, "Body": body},
|
||||
)
|
||||
if "error" in data:
|
||||
|
||||
@@ -68,7 +68,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "X_BEARER_TOKEN is required", "help": "Set X_BEARER_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "X_BEARER_TOKEN is required",
|
||||
"help": "Set X_BEARER_TOKEN environment variable",
|
||||
}
|
||||
if not query:
|
||||
return {"error": "query is required"}
|
||||
|
||||
@@ -114,7 +117,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "X_BEARER_TOKEN is required", "help": "Set X_BEARER_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "X_BEARER_TOKEN is required",
|
||||
"help": "Set X_BEARER_TOKEN environment variable",
|
||||
}
|
||||
if not username:
|
||||
return {"error": "username is required"}
|
||||
|
||||
@@ -155,7 +161,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "X_BEARER_TOKEN is required", "help": "Set X_BEARER_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "X_BEARER_TOKEN is required",
|
||||
"help": "Set X_BEARER_TOKEN environment variable",
|
||||
}
|
||||
if not user_id:
|
||||
return {"error": "user_id is required"}
|
||||
|
||||
@@ -187,7 +196,10 @@ def register_tools(mcp: FastMCP, credentials: Any = None) -> None:
|
||||
"""
|
||||
headers = _get_headers()
|
||||
if headers is None:
|
||||
return {"error": "X_BEARER_TOKEN is required", "help": "Set X_BEARER_TOKEN environment variable"}
|
||||
return {
|
||||
"error": "X_BEARER_TOKEN is required",
|
||||
"help": "Set X_BEARER_TOKEN environment variable",
|
||||
}
|
||||
if not tweet_id:
|
||||
return {"error": "tweet_id is required"}
|
||||
|
||||
|
||||
@@ -37,7 +37,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{VERCEL_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{VERCEL_API}/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your VERCEL_TOKEN."}
|
||||
if resp.status_code == 403:
|
||||
@@ -53,7 +55,9 @@ def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any
|
||||
|
||||
def _post(endpoint: str, token: str, body: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{VERCEL_API}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0)
|
||||
resp = httpx.post(
|
||||
f"{VERCEL_API}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your VERCEL_TOKEN."}
|
||||
if resp.status_code not in (200, 201):
|
||||
@@ -76,7 +80,10 @@ def _delete(endpoint: str, token: str) -> dict[str, Any]:
|
||||
|
||||
|
||||
def _auth_error() -> dict[str, Any]:
|
||||
return {"error": "VERCEL_TOKEN not set", "help": "Get a token at https://vercel.com/account/tokens"}
|
||||
return {
|
||||
"error": "VERCEL_TOKEN not set",
|
||||
"help": "Get a token at https://vercel.com/account/tokens",
|
||||
}
|
||||
|
||||
|
||||
def register_tools(
|
||||
@@ -118,14 +125,16 @@ def register_tools(
|
||||
|
||||
deployments = []
|
||||
for d in data.get("deployments", []):
|
||||
deployments.append({
|
||||
"uid": d.get("uid", ""),
|
||||
"name": d.get("name", ""),
|
||||
"url": d.get("url", ""),
|
||||
"state": d.get("state", ""),
|
||||
"created": d.get("created", 0),
|
||||
"target": d.get("target", ""),
|
||||
})
|
||||
deployments.append(
|
||||
{
|
||||
"uid": d.get("uid", ""),
|
||||
"name": d.get("name", ""),
|
||||
"url": d.get("url", ""),
|
||||
"state": d.get("state", ""),
|
||||
"created": d.get("created", 0),
|
||||
"target": d.get("target", ""),
|
||||
}
|
||||
)
|
||||
return {"deployments": deployments}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -186,13 +195,15 @@ def register_tools(
|
||||
for p in data.get("projects", []):
|
||||
latest = p.get("latestDeployments", [{}])
|
||||
latest_url = latest[0].get("url", "") if latest else ""
|
||||
projects.append({
|
||||
"id": p.get("id", ""),
|
||||
"name": p.get("name", ""),
|
||||
"framework": p.get("framework", ""),
|
||||
"updatedAt": p.get("updatedAt", 0),
|
||||
"latestDeploymentUrl": latest_url,
|
||||
})
|
||||
projects.append(
|
||||
{
|
||||
"id": p.get("id", ""),
|
||||
"name": p.get("name", ""),
|
||||
"framework": p.get("framework", ""),
|
||||
"updatedAt": p.get("updatedAt", 0),
|
||||
"latestDeploymentUrl": latest_url,
|
||||
}
|
||||
)
|
||||
return {"projects": projects}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -249,12 +260,14 @@ def register_tools(
|
||||
|
||||
domains = []
|
||||
for d in data.get("domains", []):
|
||||
domains.append({
|
||||
"name": d.get("name", ""),
|
||||
"redirect": d.get("redirect", ""),
|
||||
"gitBranch": d.get("gitBranch", ""),
|
||||
"verified": d.get("verified", False),
|
||||
})
|
||||
domains.append(
|
||||
{
|
||||
"name": d.get("name", ""),
|
||||
"redirect": d.get("redirect", ""),
|
||||
"gitBranch": d.get("gitBranch", ""),
|
||||
"verified": d.get("verified", False),
|
||||
}
|
||||
)
|
||||
return {"project_id": project_id, "domains": domains}
|
||||
|
||||
# ── Environment Variables ───────────────────────────────────
|
||||
@@ -282,12 +295,14 @@ def register_tools(
|
||||
|
||||
env_vars = []
|
||||
for e in data.get("envs", []):
|
||||
env_vars.append({
|
||||
"id": e.get("id", ""),
|
||||
"key": e.get("key", ""),
|
||||
"target": e.get("target", []),
|
||||
"type": e.get("type", ""),
|
||||
})
|
||||
env_vars.append(
|
||||
{
|
||||
"id": e.get("id", ""),
|
||||
"key": e.get("key", ""),
|
||||
"target": e.get("target", []),
|
||||
"type": e.get("type", ""),
|
||||
}
|
||||
)
|
||||
return {"project_id": project_id, "env_vars": env_vars}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -21,6 +21,7 @@ from fastmcp import FastMCP
|
||||
def _get_ticker(symbol: str) -> Any:
|
||||
"""Lazily import yfinance and create a Ticker object."""
|
||||
import yfinance as yf
|
||||
|
||||
return yf.Ticker(symbol)
|
||||
|
||||
|
||||
@@ -96,14 +97,16 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
|
||||
data = []
|
||||
for idx, row in hist.iterrows():
|
||||
data.append({
|
||||
"date": str(idx.date()) if hasattr(idx, "date") else str(idx),
|
||||
"open": round(row.get("Open", 0), 2),
|
||||
"high": round(row.get("High", 0), 2),
|
||||
"low": round(row.get("Low", 0), 2),
|
||||
"close": round(row.get("Close", 0), 2),
|
||||
"volume": int(row.get("Volume", 0)),
|
||||
})
|
||||
data.append(
|
||||
{
|
||||
"date": str(idx.date()) if hasattr(idx, "date") else str(idx),
|
||||
"open": round(row.get("Open", 0), 2),
|
||||
"high": round(row.get("High", 0), 2),
|
||||
"low": round(row.get("Low", 0), 2),
|
||||
"close": round(row.get("Close", 0), 2),
|
||||
"volume": int(row.get("Volume", 0)),
|
||||
}
|
||||
)
|
||||
return {"symbol": symbol.upper(), "period": period, "interval": interval, "data": data}
|
||||
except Exception as e:
|
||||
return {"error": f"Failed to fetch history for {symbol}: {e!s}"}
|
||||
@@ -136,7 +139,9 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
elif statement == "cashflow":
|
||||
df = ticker.cashflow
|
||||
else:
|
||||
return {"error": f"Invalid statement type: {statement}. Use: income, balance, cashflow"}
|
||||
return {
|
||||
"error": f"Invalid statement type: {statement}. Use: income, balance, cashflow"
|
||||
}
|
||||
|
||||
if df is None or df.empty:
|
||||
return {"error": f"No {statement} statement data for '{symbol}'"}
|
||||
@@ -147,7 +152,9 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
period_data = {}
|
||||
for idx, val in df[col].items():
|
||||
if val is not None and str(val) != "nan":
|
||||
period_data[str(idx)] = float(val) if isinstance(val, (int, float)) else str(val)
|
||||
period_data[str(idx)] = (
|
||||
float(val) if isinstance(val, (int, float)) else str(val)
|
||||
)
|
||||
result[str(col.date()) if hasattr(col, "date") else str(col)] = period_data
|
||||
|
||||
return {"symbol": symbol.upper(), "statement": statement, "data": result}
|
||||
@@ -210,17 +217,20 @@ def register_tools(mcp: FastMCP) -> None:
|
||||
|
||||
try:
|
||||
import yfinance as yf
|
||||
|
||||
search = yf.Search(query)
|
||||
quotes = search.quotes if hasattr(search, "quotes") else []
|
||||
|
||||
results = []
|
||||
for q in quotes[:20]:
|
||||
results.append({
|
||||
"symbol": q.get("symbol", ""),
|
||||
"name": q.get("shortname", q.get("longname", "")),
|
||||
"exchange": q.get("exchange", ""),
|
||||
"type": q.get("quoteType", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"symbol": q.get("symbol", ""),
|
||||
"name": q.get("shortname", q.get("longname", "")),
|
||||
"exchange": q.get("exchange", ""),
|
||||
"type": q.get("quoteType", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": results}
|
||||
except Exception as e:
|
||||
return {"error": f"Search failed: {e!s}"}
|
||||
|
||||
@@ -45,7 +45,9 @@ def _request(
|
||||
if errors:
|
||||
reason = errors[0].get("reason", "")
|
||||
if reason == "quotaExceeded":
|
||||
return {"error": "YouTube API quota exceeded. Try again tomorrow or request a quota increase."}
|
||||
return {
|
||||
"error": "YouTube API quota exceeded. Try again tomorrow or request a quota increase."
|
||||
}
|
||||
return {"error": f"Forbidden: {reason or resp.text}"}
|
||||
if resp.status_code != 200:
|
||||
return {"error": f"YouTube API error {resp.status_code}: {resp.text[:500]}"}
|
||||
@@ -145,15 +147,17 @@ def register_tools(
|
||||
results = []
|
||||
for item in data.get("items", []):
|
||||
snippet = item.get("snippet", {})
|
||||
results.append({
|
||||
"videoId": item.get("id", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"channelTitle": snippet.get("channelTitle", ""),
|
||||
"channelId": snippet.get("channelId", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"videoId": item.get("id", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"channelTitle": snippet.get("channelTitle", ""),
|
||||
"channelId": snippet.get("channelId", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
}
|
||||
)
|
||||
return {
|
||||
"query": query,
|
||||
"results": results,
|
||||
@@ -199,22 +203,24 @@ def register_tools(
|
||||
snippet = item.get("snippet", {})
|
||||
stats = item.get("statistics", {})
|
||||
content = item.get("contentDetails", {})
|
||||
videos.append({
|
||||
"videoId": item.get("id", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"channelTitle": snippet.get("channelTitle", ""),
|
||||
"channelId": snippet.get("channelId", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"tags": snippet.get("tags", []),
|
||||
"categoryId": snippet.get("categoryId", ""),
|
||||
"duration": _parse_duration(content.get("duration", "")),
|
||||
"duration_raw": content.get("duration", ""),
|
||||
"viewCount": int(stats.get("viewCount", 0)),
|
||||
"likeCount": int(stats.get("likeCount", 0)),
|
||||
"commentCount": int(stats.get("commentCount", 0)),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("high", {}).get("url", ""),
|
||||
})
|
||||
videos.append(
|
||||
{
|
||||
"videoId": item.get("id", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"channelTitle": snippet.get("channelTitle", ""),
|
||||
"channelId": snippet.get("channelId", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"tags": snippet.get("tags", []),
|
||||
"categoryId": snippet.get("categoryId", ""),
|
||||
"duration": _parse_duration(content.get("duration", "")),
|
||||
"duration_raw": content.get("duration", ""),
|
||||
"viewCount": int(stats.get("viewCount", 0)),
|
||||
"likeCount": int(stats.get("likeCount", 0)),
|
||||
"commentCount": int(stats.get("commentCount", 0)),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("high", {}).get("url", ""),
|
||||
}
|
||||
)
|
||||
return {"videos": videos}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -273,7 +279,9 @@ def register_tools(
|
||||
"videoCount": int(stats.get("videoCount", 0)),
|
||||
"viewCount": int(stats.get("viewCount", 0)),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("high", {}).get("url", ""),
|
||||
"uploadsPlaylistId": item.get("contentDetails", {}).get("relatedPlaylists", {}).get("uploads", ""),
|
||||
"uploadsPlaylistId": item.get("contentDetails", {})
|
||||
.get("relatedPlaylists", {})
|
||||
.get("uploads", ""),
|
||||
}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -320,13 +328,15 @@ def register_tools(
|
||||
videos = []
|
||||
for item in data.get("items", []):
|
||||
snippet = item.get("snippet", {})
|
||||
videos.append({
|
||||
"videoId": item.get("id", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
})
|
||||
videos.append(
|
||||
{
|
||||
"videoId": item.get("id", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"publishedAt": snippet.get("publishedAt", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
}
|
||||
)
|
||||
return {"channel_id": channel_id, "videos": videos}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -387,13 +397,15 @@ def register_tools(
|
||||
items = []
|
||||
for item in items_data.get("items", []):
|
||||
snippet = item.get("snippet", {})
|
||||
items.append({
|
||||
"videoId": snippet.get("resourceId", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"position": snippet.get("position", 0),
|
||||
"channelTitle": snippet.get("videoOwnerChannelTitle", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
})
|
||||
items.append(
|
||||
{
|
||||
"videoId": snippet.get("resourceId", {}).get("videoId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"position": snippet.get("position", 0),
|
||||
"channelTitle": snippet.get("videoOwnerChannelTitle", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"playlistId": playlist_id,
|
||||
@@ -448,12 +460,14 @@ def register_tools(
|
||||
results = []
|
||||
for item in data.get("items", []):
|
||||
snippet = item.get("snippet", {})
|
||||
results.append({
|
||||
"channelId": item.get("id", {}).get("channelId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"channelId": item.get("id", {}).get("channelId", ""),
|
||||
"title": snippet.get("title", ""),
|
||||
"description": snippet.get("description", ""),
|
||||
"thumbnail": snippet.get("thumbnails", {}).get("medium", {}).get("url", ""),
|
||||
}
|
||||
)
|
||||
return {"query": query, "results": results}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -500,13 +514,15 @@ def register_tools(
|
||||
comments = []
|
||||
for item in data.get("items", []):
|
||||
top = item.get("snippet", {}).get("topLevelComment", {}).get("snippet", {})
|
||||
comments.append({
|
||||
"author": top.get("authorDisplayName", ""),
|
||||
"text": top.get("textDisplay", ""),
|
||||
"likeCount": top.get("likeCount", 0),
|
||||
"publishedAt": top.get("publishedAt", ""),
|
||||
"replyCount": item.get("snippet", {}).get("totalReplyCount", 0),
|
||||
})
|
||||
comments.append(
|
||||
{
|
||||
"author": top.get("authorDisplayName", ""),
|
||||
"text": top.get("textDisplay", ""),
|
||||
"likeCount": top.get("likeCount", 0),
|
||||
"publishedAt": top.get("publishedAt", ""),
|
||||
"replyCount": item.get("snippet", {}).get("totalReplyCount", 0),
|
||||
}
|
||||
)
|
||||
return {"video_id": video_id, "comments": comments}
|
||||
|
||||
@mcp.tool()
|
||||
@@ -539,8 +555,10 @@ def register_tools(
|
||||
|
||||
categories = []
|
||||
for item in data.get("items", []):
|
||||
categories.append({
|
||||
"id": item.get("id", ""),
|
||||
"title": item.get("snippet", {}).get("title", ""),
|
||||
})
|
||||
categories.append(
|
||||
{
|
||||
"id": item.get("id", ""),
|
||||
"title": item.get("snippet", {}).get("title", ""),
|
||||
}
|
||||
)
|
||||
return {"region_code": region_code, "categories": categories}
|
||||
|
||||
@@ -44,7 +44,9 @@ def register_tools(
|
||||
try:
|
||||
from youtube_transcript_api import YouTubeTranscriptApi
|
||||
except ImportError:
|
||||
return {"error": "youtube-transcript-api package not installed. Run: pip install youtube-transcript-api"}
|
||||
return {
|
||||
"error": "youtube-transcript-api package not installed. Run: pip install youtube-transcript-api"
|
||||
}
|
||||
|
||||
try:
|
||||
ytt_api = YouTubeTranscriptApi()
|
||||
@@ -85,19 +87,23 @@ def register_tools(
|
||||
try:
|
||||
from youtube_transcript_api import YouTubeTranscriptApi
|
||||
except ImportError:
|
||||
return {"error": "youtube-transcript-api package not installed. Run: pip install youtube-transcript-api"}
|
||||
return {
|
||||
"error": "youtube-transcript-api package not installed. Run: pip install youtube-transcript-api"
|
||||
}
|
||||
|
||||
try:
|
||||
ytt_api = YouTubeTranscriptApi()
|
||||
transcript_list = ytt_api.list(video_id)
|
||||
transcripts = []
|
||||
for t in transcript_list:
|
||||
transcripts.append({
|
||||
"language": t.language,
|
||||
"language_code": t.language_code,
|
||||
"is_generated": t.is_generated,
|
||||
"is_translatable": t.is_translatable,
|
||||
})
|
||||
transcripts.append(
|
||||
{
|
||||
"language": t.language,
|
||||
"language_code": t.language_code,
|
||||
"is_generated": t.is_generated,
|
||||
"is_translatable": t.is_translatable,
|
||||
}
|
||||
)
|
||||
return {
|
||||
"video_id": video_id,
|
||||
"transcripts": transcripts,
|
||||
|
||||
@@ -21,7 +21,9 @@ if TYPE_CHECKING:
|
||||
from aden_tools.credentials import CredentialStoreAdapter
|
||||
|
||||
|
||||
def _get_credentials(credentials: CredentialStoreAdapter | None) -> tuple[str | None, str | None, str | None]:
|
||||
def _get_credentials(
|
||||
credentials: CredentialStoreAdapter | None,
|
||||
) -> tuple[str | None, str | None, str | None]:
|
||||
"""Return (subdomain, email, api_token)."""
|
||||
if credentials is not None:
|
||||
subdomain = credentials.get("zendesk_subdomain")
|
||||
@@ -44,9 +46,7 @@ def _auth_header(email: str, token: str) -> str:
|
||||
return f"Basic {encoded}"
|
||||
|
||||
|
||||
def _request(
|
||||
method: str, url: str, email: str, token: str, **kwargs: Any
|
||||
) -> dict[str, Any]:
|
||||
def _request(method: str, url: str, email: str, token: str, **kwargs: Any) -> dict[str, Any]:
|
||||
"""Make a request to the Zendesk API."""
|
||||
headers = kwargs.pop("headers", {})
|
||||
headers["Authorization"] = _auth_header(email, token)
|
||||
@@ -286,10 +286,12 @@ def register_tools(
|
||||
|
||||
results = []
|
||||
for r in data.get("results", []):
|
||||
results.append({
|
||||
"id": r.get("id"),
|
||||
"subject": r.get("subject", ""),
|
||||
"status": r.get("status", ""),
|
||||
"priority": r.get("priority", ""),
|
||||
})
|
||||
results.append(
|
||||
{
|
||||
"id": r.get("id"),
|
||||
"subject": r.get("subject", ""),
|
||||
"status": r.get("status", ""),
|
||||
"priority": r.get("priority", ""),
|
||||
}
|
||||
)
|
||||
return {"results": results, "count": data.get("count", len(results))}
|
||||
|
||||
@@ -38,7 +38,9 @@ def _headers(token: str) -> dict[str, str]:
|
||||
|
||||
def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.get(f"{_base_url()}/{endpoint}", headers=_headers(token), params=params, timeout=30.0)
|
||||
resp = httpx.get(
|
||||
f"{_base_url()}/{endpoint}", headers=_headers(token), params=params, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your ZOHO_CRM_ACCESS_TOKEN (may need refresh)."}
|
||||
if resp.status_code == 204:
|
||||
@@ -54,7 +56,9 @@ def _get(endpoint: str, token: str, params: dict | None = None) -> dict[str, Any
|
||||
|
||||
def _post(endpoint: str, token: str, body: dict | None = None) -> dict[str, Any]:
|
||||
try:
|
||||
resp = httpx.post(f"{_base_url()}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0)
|
||||
resp = httpx.post(
|
||||
f"{_base_url()}/{endpoint}", headers=_headers(token), json=body or {}, timeout=30.0
|
||||
)
|
||||
if resp.status_code == 401:
|
||||
return {"error": "Unauthorized. Check your ZOHO_CRM_ACCESS_TOKEN."}
|
||||
if resp.status_code not in (200, 201):
|
||||
@@ -236,7 +240,9 @@ def register_tools(
|
||||
if not module:
|
||||
return {"error": "module is required"}
|
||||
if not (criteria or email or phone or word):
|
||||
return {"error": "At least one search parameter is required (criteria, email, phone, or word)"}
|
||||
return {
|
||||
"error": "At least one search parameter is required (criteria, email, phone, or word)"
|
||||
}
|
||||
|
||||
params: dict[str, Any] = {
|
||||
"page": page,
|
||||
@@ -280,12 +286,14 @@ def register_tools(
|
||||
|
||||
modules = []
|
||||
for m in data.get("modules", []):
|
||||
modules.append({
|
||||
"api_name": m.get("api_name", ""),
|
||||
"module_name": m.get("module_name", ""),
|
||||
"plural_label": m.get("plural_label", ""),
|
||||
"editable": m.get("editable", False),
|
||||
})
|
||||
modules.append(
|
||||
{
|
||||
"api_name": m.get("api_name", ""),
|
||||
"module_name": m.get("module_name", ""),
|
||||
"plural_label": m.get("plural_label", ""),
|
||||
"editable": m.get("editable", False),
|
||||
}
|
||||
)
|
||||
return {"modules": modules}
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@@ -34,8 +34,7 @@ def _get_token(
|
||||
return {
|
||||
"error": "Zoom credentials not configured",
|
||||
"help": (
|
||||
"Set ZOOM_ACCESS_TOKEN environment variable "
|
||||
"or configure via credential store"
|
||||
"Set ZOOM_ACCESS_TOKEN environment variable or configure via credential store"
|
||||
),
|
||||
}
|
||||
return token
|
||||
|
||||
@@ -59,7 +59,8 @@ def list_all_tables(cursor):
|
||||
def get_table_schema(cursor, table_name):
|
||||
"""Get detailed schema for a specific table."""
|
||||
# Get columns with primary key information
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
c.COLUMN_NAME,
|
||||
c.DATA_TYPE,
|
||||
@@ -79,7 +80,10 @@ def get_table_schema(cursor, table_name):
|
||||
) pk ON c.COLUMN_NAME = pk.COLUMN_NAME
|
||||
WHERE c.TABLE_NAME = ?
|
||||
ORDER BY c.ORDINAL_POSITION
|
||||
""", table_name, table_name)
|
||||
""",
|
||||
table_name,
|
||||
table_name,
|
||||
)
|
||||
|
||||
columns = []
|
||||
for row in cursor.fetchall():
|
||||
@@ -94,15 +98,18 @@ def get_table_schema(cursor, table_name):
|
||||
else:
|
||||
col_type += f"({row[3]})"
|
||||
|
||||
columns.append({
|
||||
"name": row[0],
|
||||
"type": col_type,
|
||||
"nullable": row[5] == "YES",
|
||||
"primary_key": bool(row[6]),
|
||||
})
|
||||
columns.append(
|
||||
{
|
||||
"name": row[0],
|
||||
"type": col_type,
|
||||
"nullable": row[5] == "YES",
|
||||
"primary_key": bool(row[6]),
|
||||
}
|
||||
)
|
||||
|
||||
# Get foreign keys
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
kcu.COLUMN_NAME,
|
||||
ccu.TABLE_NAME AS REFERENCED_TABLE,
|
||||
@@ -113,21 +120,21 @@ def get_table_schema(cursor, table_name):
|
||||
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
|
||||
ON rc.UNIQUE_CONSTRAINT_NAME = ccu.CONSTRAINT_NAME
|
||||
WHERE kcu.TABLE_NAME = ?
|
||||
""", table_name)
|
||||
""",
|
||||
table_name,
|
||||
)
|
||||
|
||||
foreign_keys = []
|
||||
for row in cursor.fetchall():
|
||||
foreign_keys.append({
|
||||
"column": row[0],
|
||||
"references_table": row[1],
|
||||
"references_column": row[2],
|
||||
})
|
||||
foreign_keys.append(
|
||||
{
|
||||
"column": row[0],
|
||||
"references_table": row[1],
|
||||
"references_column": row[2],
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"table": table_name,
|
||||
"columns": columns,
|
||||
"foreign_keys": foreign_keys
|
||||
}
|
||||
return {"table": table_name, "columns": columns, "foreign_keys": foreign_keys}
|
||||
|
||||
|
||||
def print_table_schema(schema, is_last=False):
|
||||
@@ -198,7 +205,7 @@ def main():
|
||||
|
||||
for i, table in enumerate(tables):
|
||||
schema = get_table_schema(cursor, table)
|
||||
is_last = (i == len(tables) - 1)
|
||||
is_last = i == len(tables) - 1
|
||||
print_table_schema(schema, is_last)
|
||||
|
||||
# Summary
|
||||
|
||||
@@ -47,7 +47,10 @@ class TestAirtableListRecords:
|
||||
data = {"records": [RECORD_DATA]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_list_records"](base_id="appXXX", table_name="Tasks")
|
||||
|
||||
@@ -58,7 +61,10 @@ class TestAirtableListRecords:
|
||||
data = {"records": [RECORD_DATA], "offset": "itrXXX/recXXX"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_list_records"](base_id="appXXX", table_name="Tasks")
|
||||
|
||||
@@ -75,9 +81,14 @@ class TestAirtableGetRecord:
|
||||
def test_successful_get(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.get", return_value=_mock_resp(RECORD_DATA)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.get",
|
||||
return_value=_mock_resp(RECORD_DATA),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_get_record"](base_id="appXXX", table_name="Tasks", record_id="recABC123")
|
||||
result = tool_fns["airtable_get_record"](
|
||||
base_id="appXXX", table_name="Tasks", record_id="recABC123"
|
||||
)
|
||||
|
||||
assert result["id"] == "recABC123"
|
||||
assert result["fields"]["Status"] == "Active"
|
||||
@@ -86,12 +97,16 @@ class TestAirtableGetRecord:
|
||||
class TestAirtableCreateRecords:
|
||||
def test_missing_records(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["airtable_create_records"](base_id="appXXX", table_name="Tasks", records="")
|
||||
result = tool_fns["airtable_create_records"](
|
||||
base_id="appXXX", table_name="Tasks", records=""
|
||||
)
|
||||
assert "error" in result
|
||||
|
||||
def test_invalid_json(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["airtable_create_records"](base_id="appXXX", table_name="Tasks", records="not json")
|
||||
result = tool_fns["airtable_create_records"](
|
||||
base_id="appXXX", table_name="Tasks", records="not json"
|
||||
)
|
||||
assert "error" in result
|
||||
|
||||
def test_too_many_records(self, tool_fns):
|
||||
@@ -99,7 +114,9 @@ class TestAirtableCreateRecords:
|
||||
|
||||
records = json.dumps([{"fields": {"Name": f"Item {i}"}} for i in range(11)])
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["airtable_create_records"](base_id="appXXX", table_name="Tasks", records=records)
|
||||
result = tool_fns["airtable_create_records"](
|
||||
base_id="appXXX", table_name="Tasks", records=records
|
||||
)
|
||||
assert "error" in result
|
||||
assert "10" in result["error"]
|
||||
|
||||
@@ -107,7 +124,10 @@ class TestAirtableCreateRecords:
|
||||
data = {"records": [RECORD_DATA]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_create_records"](
|
||||
base_id="appXXX",
|
||||
@@ -126,7 +146,10 @@ class TestAirtableUpdateRecords:
|
||||
data = {"records": [updated]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.patch", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.patch",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_update_records"](
|
||||
base_id="appXXX",
|
||||
@@ -152,7 +175,10 @@ class TestAirtableListBases:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_list_bases"]()
|
||||
|
||||
@@ -181,7 +207,10 @@ class TestAirtableGetBaseSchema:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.airtable_tool.airtable_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.airtable_tool.airtable_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["airtable_get_base_schema"](base_id="appXXX")
|
||||
|
||||
|
||||
@@ -156,7 +156,12 @@ class TestAsanaSearchTasks:
|
||||
def test_successful_search(self, tool_fns):
|
||||
mock_resp = {
|
||||
"data": [
|
||||
{"gid": "task-1", "name": "Design homepage", "completed": False, "due_on": "2024-06-15"}
|
||||
{
|
||||
"gid": "task-1",
|
||||
"name": "Design homepage",
|
||||
"completed": False,
|
||||
"due_on": "2024-06-15",
|
||||
}
|
||||
]
|
||||
}
|
||||
with (
|
||||
|
||||
@@ -121,9 +121,7 @@ class TestAttioClient:
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
params = {"matching_attribute": "email_addresses"}
|
||||
result = self.client._request(
|
||||
"PUT", "/objects/people/records", json_body={}, params=params
|
||||
)
|
||||
result = self.client._request("PUT", "/objects/people/records", json_body={}, params=params)
|
||||
|
||||
call_kwargs = mock_request.call_args.kwargs
|
||||
assert call_kwargs["params"] == params
|
||||
@@ -210,7 +208,10 @@ class TestAttioClient:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": {"record_id": "rec-123"}, "values": {"name": [{"first_name": "Updated"}]}}
|
||||
"data": {
|
||||
"id": {"record_id": "rec-123"},
|
||||
"values": {"name": [{"first_name": "Updated"}]},
|
||||
}
|
||||
}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
@@ -223,9 +224,7 @@ class TestAttioClient:
|
||||
def test_assert_record(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": {"record_id": "rec-upserted"}}
|
||||
}
|
||||
mock_response.json.return_value = {"data": {"id": {"record_id": "rec-upserted"}}}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
values = {"email_addresses": [{"email_address": "test@example.com"}]}
|
||||
@@ -241,9 +240,7 @@ class TestAttioClient:
|
||||
def test_list_lists(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "list-1", "name": "Sales Pipeline"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "list-1", "name": "Sales Pipeline"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.list_lists()
|
||||
@@ -255,9 +252,7 @@ class TestAttioClient:
|
||||
def test_get_entries(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "entry-1"}, {"id": "entry-2"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "entry-1"}, {"id": "entry-2"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.get_entries("list-1")
|
||||
@@ -332,9 +327,7 @@ class TestAttioClient:
|
||||
def test_list_tasks(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "task-1"}, {"id": "task-2"}]
|
||||
}
|
||||
mock_response.json.return_value = {"data": [{"id": "task-1"}, {"id": "task-2"}]}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.list_tasks()
|
||||
@@ -346,9 +339,7 @@ class TestAttioClient:
|
||||
def test_get_task(self, mock_request):
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": {"id": "task-1", "content": "Call back"}
|
||||
}
|
||||
mock_response.json.return_value = {"data": {"id": "task-1", "content": "Call back"}}
|
||||
mock_request.return_value = mock_response
|
||||
|
||||
result = self.client.get_task("task-1")
|
||||
|
||||
@@ -61,7 +61,10 @@ class TestS3ListBuckets:
|
||||
def test_successful_list(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.aws_s3_tool.aws_s3_tool.httpx.get", return_value=_mock_resp(LIST_BUCKETS_XML)),
|
||||
patch(
|
||||
"aden_tools.tools.aws_s3_tool.aws_s3_tool.httpx.get",
|
||||
return_value=_mock_resp(LIST_BUCKETS_XML),
|
||||
),
|
||||
):
|
||||
result = tool_fns["s3_list_buckets"]()
|
||||
|
||||
@@ -78,7 +81,10 @@ class TestS3ListObjects:
|
||||
def test_successful_list(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.aws_s3_tool.aws_s3_tool.httpx.get", return_value=_mock_resp(LIST_OBJECTS_XML)),
|
||||
patch(
|
||||
"aden_tools.tools.aws_s3_tool.aws_s3_tool.httpx.get",
|
||||
return_value=_mock_resp(LIST_OBJECTS_XML),
|
||||
),
|
||||
):
|
||||
result = tool_fns["s3_list_objects"](bucket="my-bucket")
|
||||
|
||||
@@ -97,7 +103,12 @@ class TestS3GetObject:
|
||||
def test_successful_get_text(self, tool_fns):
|
||||
resp = _mock_resp(
|
||||
"Hello, world!",
|
||||
headers={"content-type": "text/plain", "content-length": "13", "etag": '"abc"', "last-modified": "Wed, 15 Jan 2024"},
|
||||
headers={
|
||||
"content-type": "text/plain",
|
||||
"content-length": "13",
|
||||
"etag": '"abc"',
|
||||
"last-modified": "Wed, 15 Jan 2024",
|
||||
},
|
||||
)
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
@@ -121,7 +132,9 @@ class TestS3PutObject:
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.aws_s3_tool.aws_s3_tool.httpx.put", return_value=resp),
|
||||
):
|
||||
result = tool_fns["s3_put_object"](bucket="my-bucket", key="new-file.txt", content="Hello!")
|
||||
result = tool_fns["s3_put_object"](
|
||||
bucket="my-bucket", key="new-file.txt", content="Hello!"
|
||||
)
|
||||
|
||||
assert result["result"] == "uploaded"
|
||||
assert result["key"] == "new-file.txt"
|
||||
|
||||
@@ -52,7 +52,10 @@ class TestAzureSQLListServers:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["azure_sql_list_servers"]()
|
||||
|
||||
@@ -81,7 +84,10 @@ class TestAzureSQLGetServer:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["azure_sql_get_server"](resource_group="rg", server_name="myserver")
|
||||
|
||||
@@ -116,9 +122,14 @@ class TestAzureSQLListDatabases:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["azure_sql_list_databases"](resource_group="rg", server_name="myserver")
|
||||
result = tool_fns["azure_sql_list_databases"](
|
||||
resource_group="rg", server_name="myserver"
|
||||
)
|
||||
|
||||
assert result["count"] == 1
|
||||
assert result["databases"][0]["name"] == "mydb"
|
||||
@@ -129,7 +140,9 @@ class TestAzureSQLListDatabases:
|
||||
class TestAzureSQLGetDatabase:
|
||||
def test_missing_params(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["azure_sql_get_database"](resource_group="", server_name="", database_name="")
|
||||
result = tool_fns["azure_sql_get_database"](
|
||||
resource_group="", server_name="", database_name=""
|
||||
)
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_get(self, tool_fns):
|
||||
@@ -148,7 +161,10 @@ class TestAzureSQLGetDatabase:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["azure_sql_get_database"](
|
||||
resource_group="rg", server_name="myserver", database_name="mydb"
|
||||
@@ -179,9 +195,14 @@ class TestAzureSQLListFirewallRules:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.azure_sql_tool.azure_sql_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["azure_sql_list_firewall_rules"](resource_group="rg", server_name="myserver")
|
||||
result = tool_fns["azure_sql_list_firewall_rules"](
|
||||
resource_group="rg", server_name="myserver"
|
||||
)
|
||||
|
||||
assert result["count"] == 1
|
||||
assert result["firewall_rules"][0]["name"] == "AllowAll"
|
||||
|
||||
@@ -79,9 +79,7 @@ class TestBrevoSendEmail:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 201
|
||||
mock_response.content = b'{"messageId": "<abc123@smtp-relay.brevo.com>"}'
|
||||
mock_response.json.return_value = {
|
||||
"messageId": "<abc123@smtp-relay.brevo.com>"
|
||||
}
|
||||
mock_response.json.return_value = {"messageId": "<abc123@smtp-relay.brevo.com>"}
|
||||
mock_post.return_value = mock_response
|
||||
|
||||
result = fn(
|
||||
@@ -105,9 +103,7 @@ class TestBrevoSendEmail:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 201
|
||||
mock_response.content = b'{"messageId": "<abc123@smtp-relay.brevo.com>"}'
|
||||
mock_response.json.return_value = {
|
||||
"messageId": "<abc123@smtp-relay.brevo.com>"
|
||||
}
|
||||
mock_response.json.return_value = {"messageId": "<abc123@smtp-relay.brevo.com>"}
|
||||
mock_post.return_value = mock_response
|
||||
|
||||
fn(
|
||||
@@ -201,6 +197,7 @@ class TestBrevoSendEmail:
|
||||
def test_send_email_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_send_email")
|
||||
|
||||
@@ -284,6 +281,7 @@ class TestBrevoSendSMS:
|
||||
def test_send_sms_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_send_sms")
|
||||
|
||||
@@ -364,6 +362,7 @@ class TestBrevoCreateContact:
|
||||
def test_create_contact_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_create_contact")
|
||||
|
||||
@@ -447,6 +446,7 @@ class TestBrevoGetContact:
|
||||
def test_get_contact_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_get_contact")
|
||||
|
||||
@@ -524,6 +524,7 @@ class TestBrevoUpdateContact:
|
||||
def test_update_contact_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_update_contact")
|
||||
|
||||
@@ -556,9 +557,7 @@ class TestBrevoGetEmailStats:
|
||||
"email": "user@example.com",
|
||||
"subject": "Hello",
|
||||
"date": "2024-01-15T10:30:00Z",
|
||||
"events": [
|
||||
{"name": "delivered", "time": "2024-01-15T10:30:05Z"}
|
||||
],
|
||||
"events": [{"name": "delivered", "time": "2024-01-15T10:30:05Z"}],
|
||||
}
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
@@ -599,6 +598,7 @@ class TestBrevoGetEmailStats:
|
||||
def test_get_email_stats_timeout(self, get_tool_fn, monkeypatch):
|
||||
"""Timeout returns error."""
|
||||
import httpx
|
||||
|
||||
monkeypatch.setenv("BREVO_API_KEY", "test-api-key")
|
||||
fn = get_tool_fn("brevo_get_email_stats")
|
||||
|
||||
|
||||
@@ -48,7 +48,10 @@ class TestCalendlyGetCurrentUser:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.calendly_tool.calendly_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.calendly_tool.calendly_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["calendly_get_current_user"]()
|
||||
|
||||
@@ -81,7 +84,10 @@ class TestCalendlyListEventTypes:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.calendly_tool.calendly_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.calendly_tool.calendly_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["calendly_list_event_types"](user_uri=USER_URI)
|
||||
|
||||
@@ -114,7 +120,10 @@ class TestCalendlyListScheduledEvents:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.calendly_tool.calendly_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.calendly_tool.calendly_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["calendly_list_scheduled_events"](user_uri=USER_URI)
|
||||
|
||||
@@ -146,7 +155,10 @@ class TestCalendlyGetScheduledEvent:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.calendly_tool.calendly_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.calendly_tool.calendly_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["calendly_get_scheduled_event"](event_uri=EVENT_URI)
|
||||
|
||||
@@ -169,9 +181,7 @@ class TestCalendlyListInvitees:
|
||||
"email": "jane@example.com",
|
||||
"status": "active",
|
||||
"timezone": "America/Chicago",
|
||||
"questions_and_answers": [
|
||||
{"question": "Topic?", "answer": "Product demo"}
|
||||
],
|
||||
"questions_and_answers": [{"question": "Topic?", "answer": "Product demo"}],
|
||||
"created_at": "2024-03-10T12:00:00.000000Z",
|
||||
}
|
||||
],
|
||||
@@ -179,7 +189,10 @@ class TestCalendlyListInvitees:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.calendly_tool.calendly_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.calendly_tool.calendly_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["calendly_list_invitees"](event_uri=EVENT_URI)
|
||||
|
||||
|
||||
@@ -47,7 +47,10 @@ class TestCloudinaryUpload:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["cloudinary_upload"](file_url="https://example.com/img.jpg")
|
||||
|
||||
@@ -80,7 +83,9 @@ class TestCloudinaryListResources:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["cloudinary_list_resources"]()
|
||||
|
||||
@@ -111,7 +116,9 @@ class TestCloudinaryGetResource:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["cloudinary_get_resource"](public_id="sample1")
|
||||
|
||||
@@ -131,7 +138,10 @@ class TestCloudinaryDeleteResource:
|
||||
mock_resp.json.return_value = {"result": "ok"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["cloudinary_delete_resource"](public_id="sample1")
|
||||
|
||||
@@ -163,7 +173,10 @@ class TestCloudinarySearch:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.cloudinary_tool.cloudinary_tool.httpx.post",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["cloudinary_search"](expression="resource_type:image AND tags=nature")
|
||||
|
||||
|
||||
@@ -33,12 +33,20 @@ class TestConfluenceListSpaces:
|
||||
mock_resp.content = b"{}"
|
||||
mock_resp.json.return_value = {
|
||||
"results": [
|
||||
{"id": "123", "key": "DEV", "name": "Development", "type": "global", "status": "current"}
|
||||
{
|
||||
"id": "123",
|
||||
"key": "DEV",
|
||||
"name": "Development",
|
||||
"type": "global",
|
||||
"status": "current",
|
||||
}
|
||||
]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["confluence_list_spaces"]()
|
||||
|
||||
@@ -54,14 +62,20 @@ class TestConfluenceListPages:
|
||||
mock_resp.json.return_value = {
|
||||
"results": [
|
||||
{
|
||||
"id": "page-1", "title": "Getting Started", "spaceId": "123",
|
||||
"status": "current", "version": {"number": 3}, "createdAt": "2024-01-01T00:00:00Z",
|
||||
"id": "page-1",
|
||||
"title": "Getting Started",
|
||||
"spaceId": "123",
|
||||
"status": "current",
|
||||
"version": {"number": 3},
|
||||
"createdAt": "2024-01-01T00:00:00Z",
|
||||
}
|
||||
]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["confluence_list_pages"](space_id="123")
|
||||
|
||||
@@ -80,14 +94,19 @@ class TestConfluenceGetPage:
|
||||
mock_resp.status_code = 200
|
||||
mock_resp.content = b"{}"
|
||||
mock_resp.json.return_value = {
|
||||
"id": "page-1", "title": "Getting Started", "spaceId": "123",
|
||||
"status": "current", "version": {"number": 3},
|
||||
"id": "page-1",
|
||||
"title": "Getting Started",
|
||||
"spaceId": "123",
|
||||
"status": "current",
|
||||
"version": {"number": 3},
|
||||
"body": {"storage": {"value": "<p>Hello</p>"}},
|
||||
"createdAt": "2024-01-01T00:00:00Z",
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["confluence_get_page"](page_id="page-1")
|
||||
|
||||
@@ -108,7 +127,10 @@ class TestConfluenceCreatePage:
|
||||
mock_resp.json.return_value = {"id": "page-new", "title": "New Page"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.confluence_tool.confluence_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.confluence_tool.confluence_tool.httpx.post",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["confluence_create_page"](
|
||||
space_id="123", title="New Page", body="<p>Content</p>"
|
||||
@@ -139,7 +161,9 @@ class TestConfluenceSearch:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.confluence_tool.confluence_tool.httpx.get", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["confluence_search"](query="deployment")
|
||||
|
||||
|
||||
@@ -42,7 +42,9 @@ class TestDatabricksSqlQuery:
|
||||
mock_post.return_value.status_code = 200
|
||||
mock_post.return_value.json.return_value = mock_resp
|
||||
mock_post.return_value.text = "{}"
|
||||
result = tool_fns["databricks_sql_query"](statement="SELECT * FROM users", warehouse_id="w1")
|
||||
result = tool_fns["databricks_sql_query"](
|
||||
statement="SELECT * FROM users", warehouse_id="w1"
|
||||
)
|
||||
|
||||
assert result["status"] == "SUCCEEDED"
|
||||
assert result["columns"] == ["id", "name"]
|
||||
|
||||
@@ -47,7 +47,10 @@ class TestGitlabListProjects:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(projects)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get",
|
||||
return_value=_mock_resp(projects),
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_list_projects"]()
|
||||
|
||||
@@ -79,7 +82,10 @@ class TestGitlabGetProject:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(project)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get",
|
||||
return_value=_mock_resp(project),
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_get_project"](project_id="1")
|
||||
|
||||
@@ -109,7 +115,10 @@ class TestGitlabListIssues:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(issues)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get",
|
||||
return_value=_mock_resp(issues),
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_list_issues"](project_id="1")
|
||||
|
||||
@@ -141,7 +150,9 @@ class TestGitlabGetIssue:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(issue)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(issue)
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_get_issue"](project_id="1", issue_iid=1)
|
||||
|
||||
@@ -156,10 +167,17 @@ class TestGitlabCreateIssue:
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_create(self, tool_fns):
|
||||
issue = {"iid": 2, "title": "New issue", "web_url": "https://gitlab.com/user/project/-/issues/2"}
|
||||
issue = {
|
||||
"iid": 2,
|
||||
"title": "New issue",
|
||||
"web_url": "https://gitlab.com/user/project/-/issues/2",
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.post", return_value=_mock_resp(issue, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.post",
|
||||
return_value=_mock_resp(issue, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_create_issue"](project_id="1", title="New issue")
|
||||
|
||||
@@ -189,7 +207,9 @@ class TestGitlabListMergeRequests:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(mrs)),
|
||||
patch(
|
||||
"aden_tools.tools.gitlab_tool.gitlab_tool.httpx.get", return_value=_mock_resp(mrs)
|
||||
),
|
||||
):
|
||||
result = tool_fns["gitlab_list_merge_requests"](project_id="1")
|
||||
|
||||
|
||||
@@ -27,9 +27,7 @@ class TestGscSearchAnalytics:
|
||||
|
||||
def test_missing_params(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["gsc_search_analytics"](
|
||||
site_url="", start_date="", end_date=""
|
||||
)
|
||||
result = tool_fns["gsc_search_analytics"](site_url="", start_date="", end_date="")
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_query(self, tool_fns):
|
||||
@@ -46,7 +44,9 @@ class TestGscSearchAnalytics:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.post") as mock_post,
|
||||
patch(
|
||||
"aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.post"
|
||||
) as mock_post,
|
||||
):
|
||||
mock_post.return_value.status_code = 200
|
||||
mock_post.return_value.json.return_value = mock_resp
|
||||
@@ -61,13 +61,13 @@ class TestGscSearchAnalytics:
|
||||
class TestGscListSites:
|
||||
def test_successful_list(self, tool_fns):
|
||||
mock_resp = {
|
||||
"siteEntry": [
|
||||
{"siteUrl": "https://example.com", "permissionLevel": "siteOwner"}
|
||||
]
|
||||
"siteEntry": [{"siteUrl": "https://example.com", "permissionLevel": "siteOwner"}]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_resp
|
||||
@@ -98,7 +98,9 @@ class TestGscListSitemaps:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_resp
|
||||
@@ -131,7 +133,9 @@ class TestGscInspectUrl:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.post") as mock_post,
|
||||
patch(
|
||||
"aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.post"
|
||||
) as mock_post,
|
||||
):
|
||||
mock_post.return_value.status_code = 200
|
||||
mock_post.return_value.json.return_value = mock_resp
|
||||
@@ -153,7 +157,9 @@ class TestGscSubmitSitemap:
|
||||
def test_successful_submit(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.put") as mock_put,
|
||||
patch(
|
||||
"aden_tools.tools.google_search_console_tool.google_search_console_tool.httpx.put"
|
||||
) as mock_put,
|
||||
):
|
||||
mock_put.return_value.status_code = 204
|
||||
result = tool_fns["gsc_submit_sitemap"](
|
||||
|
||||
@@ -53,7 +53,10 @@ class TestSheetsGetSpreadsheet:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["sheets_get_spreadsheet"](spreadsheet_id="abc123")
|
||||
|
||||
@@ -85,7 +88,10 @@ class TestSheetsReadRange:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["sheets_read_range"](spreadsheet_id="abc123", range="Sheet1!A1:B3")
|
||||
|
||||
@@ -109,9 +115,14 @@ class TestSheetsBatchRead:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.google_sheets_tool.google_sheets_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["sheets_batch_read"](spreadsheet_id="abc123", ranges="Sheet1!A1:B2,Sheet2!A1:A2")
|
||||
result = tool_fns["sheets_batch_read"](
|
||||
spreadsheet_id="abc123", ranges="Sheet1!A1:B2,Sheet2!A1:A2"
|
||||
)
|
||||
|
||||
assert result["count"] == 2
|
||||
assert result["ranges"][0]["row_count"] == 2
|
||||
|
||||
@@ -45,7 +45,10 @@ class TestGreenhouseListJobs:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(jobs)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(jobs),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_list_jobs"]()
|
||||
|
||||
@@ -75,7 +78,10 @@ class TestGreenhouseGetJob:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(job)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(job),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_get_job"](job_id=1)
|
||||
|
||||
@@ -104,7 +110,10 @@ class TestGreenhouseListCandidates:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(candidates)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(candidates),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_list_candidates"]()
|
||||
|
||||
@@ -134,7 +143,10 @@ class TestGreenhouseGetCandidate:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(candidate)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(candidate),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_get_candidate"](candidate_id=100)
|
||||
|
||||
@@ -162,7 +174,10 @@ class TestGreenhouseListApplications:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(apps)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(apps),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_list_applications"]()
|
||||
|
||||
@@ -191,7 +206,10 @@ class TestGreenhouseGetApplication:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get", return_value=_mock_resp(app)),
|
||||
patch(
|
||||
"aden_tools.tools.greenhouse_tool.greenhouse_tool.httpx.get",
|
||||
return_value=_mock_resp(app),
|
||||
),
|
||||
):
|
||||
result = tool_fns["greenhouse_get_application"](application_id=200)
|
||||
|
||||
|
||||
@@ -39,7 +39,10 @@ class TestHuggingFaceSearchModels:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_search_models"](query="llama")
|
||||
|
||||
@@ -70,7 +73,10 @@ class TestHuggingFaceGetModel:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_get_model"](model_id="meta-llama/Llama-3-8B")
|
||||
|
||||
@@ -94,7 +100,10 @@ class TestHuggingFaceSearchDatasets:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_search_datasets"](query="squad")
|
||||
|
||||
@@ -123,7 +132,10 @@ class TestHuggingFaceGetDataset:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_get_dataset"](dataset_id="openai/gsm8k")
|
||||
|
||||
@@ -146,7 +158,10 @@ class TestHuggingFaceSearchSpaces:
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_search_spaces"](query="chatbot")
|
||||
|
||||
@@ -173,7 +188,10 @@ class TestHuggingFaceWhoami:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.huggingface_tool.huggingface_tool.httpx.get",
|
||||
return_value=mock_resp,
|
||||
),
|
||||
):
|
||||
result = tool_fns["huggingface_whoami"]()
|
||||
|
||||
|
||||
@@ -112,10 +112,17 @@ class TestJiraCreateIssue:
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_create(self, tool_fns):
|
||||
data = {"key": "TEST-2", "id": "10002", "self": "https://test.atlassian.net/rest/api/3/issue/10002"}
|
||||
data = {
|
||||
"key": "TEST-2",
|
||||
"id": "10002",
|
||||
"self": "https://test.atlassian.net/rest/api/3/issue/10002",
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.jira_tool.jira_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.jira_tool.jira_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["jira_create_issue"](project_key="TEST", summary="New task")
|
||||
|
||||
@@ -188,7 +195,10 @@ class TestJiraAddComment:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.jira_tool.jira_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.jira_tool.jira_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["jira_add_comment"](issue_key="TEST-1", body="Great work!")
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ class TestKafkaListTopics:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_list_topics"]()
|
||||
|
||||
@@ -78,7 +80,9 @@ class TestKafkaGetTopic:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_get_topic"](topic_name="orders")
|
||||
|
||||
@@ -100,7 +104,9 @@ class TestKafkaCreateTopic:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_create_topic"](topic_name="new-topic", partitions_count=3)
|
||||
|
||||
@@ -123,7 +129,9 @@ class TestKafkaProduceMessage:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_produce_message"](
|
||||
topic_name="orders", value='{"order_id": 123}', key="order-123"
|
||||
@@ -147,7 +155,9 @@ class TestKafkaListConsumerGroups:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_list_consumer_groups"]()
|
||||
|
||||
@@ -173,7 +183,9 @@ class TestKafkaGetConsumerGroupLag:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.kafka_tool.kafka_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["kafka_get_consumer_group_lag"](consumer_group_id="my-group")
|
||||
|
||||
|
||||
@@ -54,7 +54,10 @@ class TestLangfuseListTraces:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_list_traces"]()
|
||||
|
||||
@@ -106,7 +109,10 @@ class TestLangfuseGetTrace:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_get_trace"](trace_id="trace-abc123")
|
||||
|
||||
@@ -136,7 +142,10 @@ class TestLangfuseListScores:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_list_scores"]()
|
||||
|
||||
@@ -155,7 +164,10 @@ class TestLangfuseCreateScore:
|
||||
data = {"id": "score-new-123"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_create_score"](
|
||||
trace_id="trace-abc123",
|
||||
@@ -184,7 +196,10 @@ class TestLangfuseListPrompts:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_list_prompts"]()
|
||||
|
||||
@@ -214,7 +229,10 @@ class TestLangfuseGetPrompt:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.langfuse_tool.langfuse_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["langfuse_get_prompt"](prompt_name="movie-critic")
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ class TestLushaEnrichPerson:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_enrich_person"](
|
||||
first_name="Jane", last_name="Doe", company_domain="acme.com"
|
||||
@@ -72,7 +74,9 @@ class TestLushaEnrichPerson:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_enrich_person"](email="jane@acme.com")
|
||||
|
||||
@@ -99,7 +103,9 @@ class TestLushaEnrichCompany:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_enrich_company"](domain="acme.com")
|
||||
|
||||
@@ -133,7 +139,9 @@ class TestLushaSearchContacts:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_search_contacts"](
|
||||
seniorities="4,5", company_domains="acme.com"
|
||||
@@ -166,7 +174,9 @@ class TestLushaSearchCompanies:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_search_companies"](country="United States")
|
||||
|
||||
@@ -184,7 +194,9 @@ class TestLushaGetUsage:
|
||||
data = {"credits_used": 150, "credits_remaining": 850, "plan": "Professional"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.lusha_tool.lusha_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["lusha_get_usage"]()
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@ class TestOutlookListMessages:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_response
|
||||
@@ -72,7 +74,9 @@ class TestOutlookGetMessage:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_response
|
||||
@@ -92,7 +96,9 @@ class TestOutlookSendMail:
|
||||
def test_successful_send(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.post") as mock_post,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.post"
|
||||
) as mock_post,
|
||||
):
|
||||
mock_post.return_value.status_code = 202
|
||||
mock_post.return_value.json.return_value = {}
|
||||
@@ -108,13 +114,13 @@ class TestOutlookSendMail:
|
||||
class TestTeamsListTeams:
|
||||
def test_successful_list(self, tool_fns):
|
||||
mock_response = {
|
||||
"value": [
|
||||
{"id": "team-1", "displayName": "Engineering", "description": "Dev team"}
|
||||
]
|
||||
"value": [{"id": "team-1", "displayName": "Engineering", "description": "Dev team"}]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_response
|
||||
@@ -143,7 +149,9 @@ class TestTeamsListChannels:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_response
|
||||
@@ -156,15 +164,15 @@ class TestTeamsListChannels:
|
||||
class TestTeamsSendChannelMessage:
|
||||
def test_missing_fields(self, tool_fns):
|
||||
with patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}):
|
||||
result = tool_fns["teams_send_channel_message"](
|
||||
team_id="", channel_id="", message=""
|
||||
)
|
||||
result = tool_fns["teams_send_channel_message"](team_id="", channel_id="", message="")
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_send(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.post") as mock_post,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.post"
|
||||
) as mock_post,
|
||||
):
|
||||
mock_post.return_value.status_code = 201
|
||||
mock_post.return_value.json.return_value = {"id": "msg-123"}
|
||||
@@ -199,7 +207,9 @@ class TestOneDriveSearchFiles:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get") as mock_get,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.get"
|
||||
) as mock_get,
|
||||
):
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = mock_response
|
||||
@@ -219,7 +229,9 @@ class TestOneDriveUploadFile:
|
||||
def test_successful_upload(self, tool_fns):
|
||||
with (
|
||||
patch.dict("os.environ", {"MICROSOFT_GRAPH_ACCESS_TOKEN": "test-token"}),
|
||||
patch("aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.put") as mock_put,
|
||||
patch(
|
||||
"aden_tools.tools.microsoft_graph_tool.microsoft_graph_tool.httpx.put"
|
||||
) as mock_put,
|
||||
):
|
||||
mock_put.return_value.status_code = 201
|
||||
mock_put.return_value.json.return_value = {
|
||||
|
||||
@@ -49,7 +49,10 @@ class TestMongodbFind:
|
||||
data = {"documents": [{"_id": "1", "name": "Alice"}, {"_id": "2", "name": "Bob"}]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_find"](database="mydb", collection="users")
|
||||
|
||||
@@ -62,9 +65,14 @@ class TestMongodbFindOne:
|
||||
data = {"document": {"_id": "1", "name": "Alice", "age": 30}}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_find_one"](database="mydb", collection="users", filter='{"name": "Alice"}')
|
||||
result = tool_fns["mongodb_find_one"](
|
||||
database="mydb", collection="users", filter='{"name": "Alice"}'
|
||||
)
|
||||
|
||||
assert result["name"] == "Alice"
|
||||
assert result["age"] == 30
|
||||
@@ -73,9 +81,14 @@ class TestMongodbFindOne:
|
||||
data = {"document": None}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_find_one"](database="mydb", collection="users", filter='{"name": "Nobody"}')
|
||||
result = tool_fns["mongodb_find_one"](
|
||||
database="mydb", collection="users", filter='{"name": "Nobody"}'
|
||||
)
|
||||
|
||||
assert "error" in result
|
||||
|
||||
@@ -90,7 +103,10 @@ class TestMongodbInsertOne:
|
||||
data = {"insertedId": "abc123"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_insert_one"](
|
||||
database="mydb", collection="users", document='{"name": "Alice", "age": 30}'
|
||||
@@ -103,14 +119,19 @@ class TestMongodbInsertOne:
|
||||
class TestMongodbUpdateOne:
|
||||
def test_missing_params(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["mongodb_update_one"](database="db", collection="col", filter="", update="")
|
||||
result = tool_fns["mongodb_update_one"](
|
||||
database="db", collection="col", filter="", update=""
|
||||
)
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_update(self, tool_fns):
|
||||
data = {"matchedCount": 1, "modifiedCount": 1}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_update_one"](
|
||||
database="mydb",
|
||||
@@ -133,7 +154,10 @@ class TestMongodbDeleteOne:
|
||||
data = {"deletedCount": 1}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_delete_one"](
|
||||
database="mydb", collection="users", filter='{"name": "Alice"}'
|
||||
@@ -150,14 +174,19 @@ class TestMongodbAggregate:
|
||||
|
||||
def test_invalid_pipeline(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["mongodb_aggregate"](database="db", collection="col", pipeline='{"not": "array"}')
|
||||
result = tool_fns["mongodb_aggregate"](
|
||||
database="db", collection="col", pipeline='{"not": "array"}'
|
||||
)
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_aggregate(self, tool_fns):
|
||||
data = {"documents": [{"_id": "active", "count": 5}, {"_id": "inactive", "count": 2}]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.mongodb_tool.mongodb_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["mongodb_aggregate"](
|
||||
database="mydb",
|
||||
|
||||
@@ -63,7 +63,17 @@ class TestN8nListWorkflows:
|
||||
|
||||
def test_pagination(self, tool_fns):
|
||||
data = {
|
||||
"data": [{"id": "wf1", "name": "WF1", "active": True, "createdAt": "", "updatedAt": "", "tags": [], "nodes": []}],
|
||||
"data": [
|
||||
{
|
||||
"id": "wf1",
|
||||
"name": "WF1",
|
||||
"active": True,
|
||||
"createdAt": "",
|
||||
"updatedAt": "",
|
||||
"tags": [],
|
||||
"nodes": [],
|
||||
}
|
||||
],
|
||||
"nextCursor": "cursor123",
|
||||
}
|
||||
with (
|
||||
|
||||
@@ -52,7 +52,9 @@ class TestNotionSearch:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.notion_tool.notion_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.notion_tool.notion_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["notion_search"](query="My Page")
|
||||
|
||||
@@ -86,7 +88,9 @@ class TestNotionGetPage:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.notion_tool.notion_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.notion_tool.notion_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["notion_get_page"](page_id="page-1")
|
||||
|
||||
@@ -104,7 +108,10 @@ class TestNotionCreatePage:
|
||||
data = {"id": "new-page", "url": "https://notion.so/new-page"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.notion_tool.notion_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.notion_tool.notion_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["notion_create_page"](parent_database_id="db-1", title="New Page")
|
||||
|
||||
@@ -138,7 +145,9 @@ class TestNotionQueryDatabase:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.notion_tool.notion_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.notion_tool.notion_tool.httpx.post", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["notion_query_database"](database_id="db-1")
|
||||
|
||||
@@ -166,7 +175,9 @@ class TestNotionGetDatabase:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.notion_tool.notion_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.notion_tool.notion_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["notion_get_database"](database_id="db-1")
|
||||
|
||||
|
||||
@@ -50,7 +50,10 @@ class TestObsidianReadNote:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["obsidian_read_note"](path="Notes/meeting.md")
|
||||
|
||||
@@ -111,14 +114,23 @@ class TestObsidianSearch:
|
||||
"filename": "Daily/2025-03-01.md",
|
||||
"score": 0.85,
|
||||
"matches": [
|
||||
{"match": {"start": 45, "end": 52}, "context": "...attended the team meeting to discuss..."},
|
||||
{"match": {"start": 120, "end": 127}, "context": "...follow-up meeting scheduled for..."},
|
||||
{
|
||||
"match": {"start": 45, "end": 52},
|
||||
"context": "...attended the team meeting to discuss...",
|
||||
},
|
||||
{
|
||||
"match": {"start": 120, "end": 127},
|
||||
"context": "...follow-up meeting scheduled for...",
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.obsidian_tool.obsidian_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.obsidian_tool.obsidian_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["obsidian_search"](query="meeting")
|
||||
|
||||
@@ -132,7 +144,10 @@ class TestObsidianListFiles:
|
||||
data = ["Daily/", "Projects/", "README.md", "Templates/"]
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["obsidian_list_files"]()
|
||||
|
||||
@@ -151,7 +166,10 @@ class TestObsidianGetActive:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.obsidian_tool.obsidian_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["obsidian_get_active"]()
|
||||
|
||||
|
||||
@@ -51,7 +51,10 @@ class TestPagerdutyListIncidents:
|
||||
data = {"incidents": [INCIDENT_DATA], "more": False}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["pagerduty_list_incidents"]()
|
||||
|
||||
@@ -72,7 +75,10 @@ class TestPagerdutyGetIncident:
|
||||
data = {"incident": inc}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["pagerduty_get_incident"](incident_id="PT4KHLK")
|
||||
|
||||
@@ -90,9 +96,14 @@ class TestPagerdutyCreateIncident:
|
||||
data = {"incident": INCIDENT_DATA}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["pagerduty_create_incident"](title="Server is on fire", service_id="PWIXJZS")
|
||||
result = tool_fns["pagerduty_create_incident"](
|
||||
title="Server is on fire", service_id="PWIXJZS"
|
||||
)
|
||||
|
||||
assert result["result"] == "created"
|
||||
assert result["id"] == "PT4KHLK"
|
||||
@@ -110,9 +121,14 @@ class TestPagerdutyUpdateIncident:
|
||||
data = {"incident": ack}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.put", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.put",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["pagerduty_update_incident"](incident_id="PT4KHLK", status="acknowledged")
|
||||
result = tool_fns["pagerduty_update_incident"](
|
||||
incident_id="PT4KHLK", status="acknowledged"
|
||||
)
|
||||
|
||||
assert result["status"] == "acknowledged"
|
||||
|
||||
@@ -139,7 +155,10 @@ class TestPagerdutyListServices:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.pagerduty_tool.pagerduty_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["pagerduty_list_services"]()
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ class TestPineconeCreateIndex:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_create_index"](name="new-idx", dimension=768)
|
||||
|
||||
@@ -118,7 +120,9 @@ class TestPineconeDeleteIndex:
|
||||
mock_resp.content = b""
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.delete", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.delete", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_delete_index"](index_name="old-index")
|
||||
|
||||
@@ -138,7 +142,9 @@ class TestPineconeUpsertVectors:
|
||||
mock_resp.json.return_value = {"upsertedCount": 2}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_upsert_vectors"](
|
||||
index_host="my-index-abc.svc.pinecone.io",
|
||||
@@ -170,7 +176,9 @@ class TestPineconeQueryVectors:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_query_vectors"](
|
||||
index_host="my-index-abc.svc.pinecone.io",
|
||||
@@ -223,7 +231,9 @@ class TestPineconeDeleteVectors:
|
||||
mock_resp.json.return_value = {}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_delete_vectors"](
|
||||
index_host="my-index-abc.svc.pinecone.io",
|
||||
@@ -255,7 +265,9 @@ class TestPineconeIndexStats:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp),
|
||||
patch(
|
||||
"aden_tools.tools.pinecone_tool.pinecone_tool.httpx.post", return_value=mock_resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["pinecone_index_stats"](
|
||||
index_host="my-index-abc.svc.pinecone.io",
|
||||
|
||||
@@ -75,7 +75,12 @@ class TestPlaidGetBalance:
|
||||
"account_id": "acc-1",
|
||||
"name": "Savings",
|
||||
"type": "depository",
|
||||
"balances": {"available": 5000, "current": 5000, "limit": None, "iso_currency_code": "USD"},
|
||||
"balances": {
|
||||
"available": 5000,
|
||||
"current": 5000,
|
||||
"limit": None,
|
||||
"iso_currency_code": "USD",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -130,9 +135,7 @@ class TestPlaidSyncTransactions:
|
||||
class TestPlaidGetTransactions:
|
||||
def test_missing_params(self, tool_fns):
|
||||
with patch.dict("os.environ", ENV):
|
||||
result = tool_fns["plaid_get_transactions"](
|
||||
access_token="", start_date="", end_date=""
|
||||
)
|
||||
result = tool_fns["plaid_get_transactions"](access_token="", start_date="", end_date="")
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_get(self, tool_fns):
|
||||
|
||||
@@ -46,7 +46,10 @@ class TestPowerBIListWorkspaces:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["powerbi_list_workspaces"]()
|
||||
|
||||
@@ -77,7 +80,10 @@ class TestPowerBIListDatasets:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["powerbi_list_datasets"](workspace_id="ws-123")
|
||||
|
||||
@@ -107,7 +113,10 @@ class TestPowerBIListReports:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["powerbi_list_reports"](workspace_id="ws-123")
|
||||
|
||||
@@ -128,9 +137,7 @@ class TestPowerBIRefreshDataset:
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.powerbi_tool.powerbi_tool.httpx.post", return_value=resp),
|
||||
):
|
||||
result = tool_fns["powerbi_refresh_dataset"](
|
||||
workspace_id="ws-123", dataset_id="ds-456"
|
||||
)
|
||||
result = tool_fns["powerbi_refresh_dataset"](workspace_id="ws-123", dataset_id="ds-456")
|
||||
|
||||
assert result["result"] == "accepted"
|
||||
|
||||
@@ -155,7 +162,10 @@ class TestPowerBIGetRefreshHistory:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.powerbi_tool.powerbi_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["powerbi_get_refresh_history"](
|
||||
workspace_id="ws-123", dataset_id="ds-456"
|
||||
|
||||
@@ -61,9 +61,7 @@ class TestPushoverSend:
|
||||
"request": "req-2",
|
||||
"receipt": "rcpt-1",
|
||||
}
|
||||
result = tool_fns["pushover_send"](
|
||||
user_key="ukey", message="URGENT", priority=2
|
||||
)
|
||||
result = tool_fns["pushover_send"](user_key="ukey", message="URGENT", priority=2)
|
||||
|
||||
assert result["receipt"] == "rcpt-1"
|
||||
|
||||
|
||||
@@ -51,7 +51,10 @@ class TestQuickbooksQuery:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["quickbooks_query"](entity="Customer")
|
||||
|
||||
@@ -76,7 +79,10 @@ class TestQuickbooksGetEntity:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["quickbooks_get_entity"](entity="Customer", entity_id="1")
|
||||
|
||||
@@ -100,9 +106,14 @@ class TestQuickbooksCreateCustomer:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["quickbooks_create_customer"](display_name="New Customer", email="new@example.com")
|
||||
result = tool_fns["quickbooks_create_customer"](
|
||||
display_name="New Customer", email="new@example.com"
|
||||
)
|
||||
|
||||
assert result["result"] == "created"
|
||||
assert result["id"] == "59"
|
||||
@@ -131,7 +142,10 @@ class TestQuickbooksCreateInvoice:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["quickbooks_create_invoice"](
|
||||
customer_id="1",
|
||||
@@ -161,7 +175,10 @@ class TestQuickbooksGetCompanyInfo:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.quickbooks_tool.quickbooks_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["quickbooks_get_company_info"]()
|
||||
|
||||
|
||||
@@ -57,7 +57,10 @@ class TestRedshiftExecuteSQL:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.redshift_tool.redshift_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.redshift_tool.redshift_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["redshift_execute_sql"](
|
||||
sql="SELECT * FROM users", database="dev", cluster_identifier="my-cluster"
|
||||
@@ -85,7 +88,10 @@ class TestRedshiftDescribeStatement:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.redshift_tool.redshift_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.redshift_tool.redshift_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["redshift_describe_statement"](statement_id="stmt-abc123")
|
||||
|
||||
@@ -114,7 +120,10 @@ class TestRedshiftGetResults:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.redshift_tool.redshift_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.redshift_tool.redshift_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["redshift_get_results"](statement_id="stmt-abc123")
|
||||
|
||||
@@ -133,7 +142,10 @@ class TestRedshiftListDatabases:
|
||||
data = {"Databases": ["dev", "staging", "analytics"], "NextToken": ""}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.redshift_tool.redshift_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.redshift_tool.redshift_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["redshift_list_databases"](cluster_identifier="my-cluster")
|
||||
|
||||
@@ -157,7 +169,10 @@ class TestRedshiftListTables:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.redshift_tool.redshift_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.redshift_tool.redshift_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["redshift_list_tables"](
|
||||
database="dev", cluster_identifier="my-cluster"
|
||||
|
||||
@@ -50,7 +50,10 @@ class TestSalesforceSOQLQuery:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_soql_query"](query="SELECT Id, Name FROM Lead")
|
||||
|
||||
@@ -67,7 +70,10 @@ class TestSalesforceSOQLQuery:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_soql_query"](query="SELECT Id FROM Lead")
|
||||
|
||||
@@ -91,9 +97,14 @@ class TestSalesforceGetRecord:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_get_record"](object_type="Contact", record_id="003xx000001")
|
||||
result = tool_fns["salesforce_get_record"](
|
||||
object_type="Contact", record_id="003xx000001"
|
||||
)
|
||||
|
||||
assert result["Id"] == "003xx000001"
|
||||
assert result["Email"] == "jane@example.com"
|
||||
@@ -109,7 +120,10 @@ class TestSalesforceCreateRecord:
|
||||
data = {"id": "00Qxx000001", "success": True, "errors": []}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_create_record"](
|
||||
object_type="Lead",
|
||||
@@ -126,7 +140,9 @@ class TestSalesforceUpdateRecord:
|
||||
resp.status_code = 204
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.patch", return_value=resp),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.patch", return_value=resp
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_update_record"](
|
||||
object_type="Lead",
|
||||
@@ -169,7 +185,10 @@ class TestSalesforceDescribeObject:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_describe_object"](object_type="Lead")
|
||||
|
||||
@@ -182,13 +201,30 @@ class TestSalesforceListObjects:
|
||||
def test_successful_list(self, tool_fns):
|
||||
data = {
|
||||
"sobjects": [
|
||||
{"name": "Lead", "label": "Lead", "keyPrefix": "00Q", "queryable": True, "createable": True, "custom": False},
|
||||
{"name": "Account", "label": "Account", "keyPrefix": "001", "queryable": True, "createable": True, "custom": False},
|
||||
{
|
||||
"name": "Lead",
|
||||
"label": "Lead",
|
||||
"keyPrefix": "00Q",
|
||||
"queryable": True,
|
||||
"createable": True,
|
||||
"custom": False,
|
||||
},
|
||||
{
|
||||
"name": "Account",
|
||||
"label": "Account",
|
||||
"keyPrefix": "001",
|
||||
"queryable": True,
|
||||
"createable": True,
|
||||
"custom": False,
|
||||
},
|
||||
]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.salesforce_tool.salesforce_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["salesforce_list_objects"]()
|
||||
|
||||
|
||||
@@ -52,7 +52,10 @@ class TestShopifyListOrders:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_list_orders"]()
|
||||
|
||||
@@ -106,7 +109,10 @@ class TestShopifyGetOrder:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_get_order"](order_id="450789469")
|
||||
|
||||
@@ -134,7 +140,10 @@ class TestShopifyListProducts:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_list_products"]()
|
||||
|
||||
@@ -175,12 +184,17 @@ class TestShopifyGetProduct:
|
||||
}
|
||||
],
|
||||
"options": [{"name": "Size"}, {"name": "Color"}],
|
||||
"images": [{"id": 850703190, "src": "https://cdn.shopify.com/test.jpg", "position": 1}],
|
||||
"images": [
|
||||
{"id": 850703190, "src": "https://cdn.shopify.com/test.jpg", "position": 1}
|
||||
],
|
||||
}
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_get_product"](product_id="632910392")
|
||||
|
||||
@@ -210,7 +224,10 @@ class TestShopifyListCustomers:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_list_customers"]()
|
||||
|
||||
@@ -243,7 +260,10 @@ class TestShopifySearchCustomers:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.shopify_tool.shopify_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.shopify_tool.shopify_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["shopify_search_customers"](query="email:bob@example.com")
|
||||
|
||||
|
||||
@@ -50,7 +50,10 @@ class TestSnowflakeExecuteSQL:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_execute_sql"](statement="SELECT * FROM users")
|
||||
|
||||
@@ -66,7 +69,10 @@ class TestSnowflakeExecuteSQL:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post", return_value=_mock_resp(data, 202)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 202),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_execute_sql"](statement="SELECT * FROM big_table")
|
||||
|
||||
@@ -91,7 +97,10 @@ class TestSnowflakeGetStatementStatus:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_get_statement_status"](statement_handle="handle-123")
|
||||
|
||||
@@ -105,7 +114,10 @@ class TestSnowflakeGetStatementStatus:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get", return_value=_mock_resp(data, 202)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get",
|
||||
return_value=_mock_resp(data, 202),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_get_statement_status"](statement_handle="handle-456")
|
||||
|
||||
@@ -118,7 +130,10 @@ class TestSnowflakeGetStatementStatus:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get", return_value=_mock_resp(data, 422)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.get",
|
||||
return_value=_mock_resp(data, 422),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_get_statement_status"](statement_handle="handle-789")
|
||||
|
||||
@@ -136,7 +151,10 @@ class TestSnowflakeCancelStatement:
|
||||
data = {"statementHandle": "handle-123"}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.snowflake_tool.snowflake_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["snowflake_cancel_statement"](statement_handle="handle-123")
|
||||
|
||||
|
||||
@@ -75,9 +75,7 @@ class TestSupabaseInsert:
|
||||
):
|
||||
mock_post.return_value.status_code = 201
|
||||
mock_post.return_value.json.return_value = [{"id": 1, "name": "Alice"}]
|
||||
result = tool_fns["supabase_insert"](
|
||||
table="users", rows='{"name": "Alice"}'
|
||||
)
|
||||
result = tool_fns["supabase_insert"](table="users", rows='{"name": "Alice"}')
|
||||
|
||||
assert result["table"] == "users"
|
||||
assert len(result["inserted"]) == 1
|
||||
|
||||
@@ -63,7 +63,10 @@ class TestTerraformListWorkspaces:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.terraform_tool.terraform_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.terraform_tool.terraform_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["terraform_list_workspaces"](organization="my-org")
|
||||
|
||||
@@ -101,7 +104,10 @@ class TestTerraformGetWorkspace:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.terraform_tool.terraform_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.terraform_tool.terraform_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["terraform_get_workspace"](workspace_id="ws-abc123")
|
||||
|
||||
@@ -144,7 +150,10 @@ class TestTerraformListRuns:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.terraform_tool.terraform_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.terraform_tool.terraform_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["terraform_list_runs"](workspace_id="ws-abc123")
|
||||
|
||||
@@ -181,7 +190,10 @@ class TestTerraformGetRun:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.terraform_tool.terraform_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.terraform_tool.terraform_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["terraform_get_run"](run_id="run-xyz789")
|
||||
|
||||
@@ -215,7 +227,10 @@ class TestTerraformCreateRun:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.terraform_tool.terraform_tool.httpx.post", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.terraform_tool.terraform_tool.httpx.post",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["terraform_create_run"](
|
||||
workspace_id="ws-abc123",
|
||||
|
||||
@@ -53,7 +53,9 @@ class TestTinesListStories:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["tines_list_stories"]()
|
||||
|
||||
@@ -85,7 +87,9 @@ class TestTinesGetStory:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["tines_get_story"](story_id=123)
|
||||
|
||||
@@ -111,7 +115,9 @@ class TestTinesListActions:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["tines_list_actions"](story_id=123)
|
||||
|
||||
@@ -142,7 +148,9 @@ class TestTinesGetAction:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["tines_get_action"](action_id=456)
|
||||
|
||||
@@ -170,7 +178,9 @@ class TestTinesGetActionLogs:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.tines_tool.tines_tool.httpx.get", return_value=_mock_resp(data)
|
||||
),
|
||||
):
|
||||
result = tool_fns["tines_get_action_logs"](action_id=456)
|
||||
|
||||
|
||||
@@ -54,9 +54,13 @@ class TestTwilioSendSms:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twilio_tool.twilio_tool.httpx.post", return_value=_mock_resp(msg)),
|
||||
patch(
|
||||
"aden_tools.tools.twilio_tool.twilio_tool.httpx.post", return_value=_mock_resp(msg)
|
||||
),
|
||||
):
|
||||
result = tool_fns["twilio_send_sms"](to="+14155552671", from_number="+15017122661", body="Hello!")
|
||||
result = tool_fns["twilio_send_sms"](
|
||||
to="+14155552671", from_number="+15017122661", body="Hello!"
|
||||
)
|
||||
|
||||
assert result["sid"] == "SM123"
|
||||
assert result["status"] == "queued"
|
||||
@@ -78,9 +82,13 @@ class TestTwilioSendWhatsapp:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twilio_tool.twilio_tool.httpx.post", return_value=_mock_resp(msg)),
|
||||
patch(
|
||||
"aden_tools.tools.twilio_tool.twilio_tool.httpx.post", return_value=_mock_resp(msg)
|
||||
),
|
||||
):
|
||||
result = tool_fns["twilio_send_whatsapp"](to="+14155552671", from_number="+14155238886", body="WhatsApp msg")
|
||||
result = tool_fns["twilio_send_whatsapp"](
|
||||
to="+14155552671", from_number="+14155238886", body="WhatsApp msg"
|
||||
)
|
||||
|
||||
assert result["sid"] == "SM456"
|
||||
|
||||
@@ -110,7 +118,10 @@ class TestTwilioListMessages:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twilio_tool.twilio_tool.httpx.get", return_value=_mock_resp(data, 200)),
|
||||
patch(
|
||||
"aden_tools.tools.twilio_tool.twilio_tool.httpx.get",
|
||||
return_value=_mock_resp(data, 200),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twilio_list_messages"]()
|
||||
|
||||
@@ -139,7 +150,10 @@ class TestTwilioGetMessage:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twilio_tool.twilio_tool.httpx.get", return_value=_mock_resp(msg, 200)),
|
||||
patch(
|
||||
"aden_tools.tools.twilio_tool.twilio_tool.httpx.get",
|
||||
return_value=_mock_resp(msg, 200),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twilio_get_message"](message_sid="SM123")
|
||||
|
||||
|
||||
@@ -53,14 +53,15 @@ class TestTwitterSearchTweets:
|
||||
},
|
||||
}
|
||||
],
|
||||
"includes": {
|
||||
"users": [{"id": "456", "name": "Test User", "username": "testuser"}]
|
||||
},
|
||||
"includes": {"users": [{"id": "456", "name": "Test User", "username": "testuser"}]},
|
||||
"meta": {"result_count": 1},
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twitter_tool.twitter_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.twitter_tool.twitter_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twitter_search_tweets"](query="hello")
|
||||
|
||||
@@ -95,7 +96,10 @@ class TestTwitterGetUser:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twitter_tool.twitter_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.twitter_tool.twitter_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twitter_get_user"](username="testuser")
|
||||
|
||||
@@ -129,7 +133,10 @@ class TestTwitterGetUserTweets:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twitter_tool.twitter_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.twitter_tool.twitter_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twitter_get_user_tweets"](user_id="456")
|
||||
|
||||
@@ -158,13 +165,14 @@ class TestTwitterGetTweet:
|
||||
"impression_count": 20,
|
||||
},
|
||||
},
|
||||
"includes": {
|
||||
"users": [{"name": "Author", "username": "author"}]
|
||||
},
|
||||
"includes": {"users": [{"name": "Author", "username": "author"}]},
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.twitter_tool.twitter_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.twitter_tool.twitter_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["twitter_get_tweet"](tweet_id="123")
|
||||
|
||||
|
||||
@@ -111,9 +111,7 @@ class TestVercelListProjectDomains:
|
||||
|
||||
def test_successful_list(self, tool_fns):
|
||||
mock_resp = {
|
||||
"domains": [
|
||||
{"name": "example.com", "redirect": "", "gitBranch": "", "verified": True}
|
||||
]
|
||||
"domains": [{"name": "example.com", "redirect": "", "gitBranch": "", "verified": True}]
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
|
||||
@@ -70,6 +70,7 @@ class TestYahooFinanceHistory:
|
||||
|
||||
# Create a mock DataFrame
|
||||
import pandas as pd
|
||||
|
||||
mock_df = pd.DataFrame(
|
||||
{
|
||||
"Open": [174.0, 175.0],
|
||||
|
||||
@@ -54,7 +54,10 @@ class TestZendeskListTickets:
|
||||
data = {"tickets": [TICKET_DATA]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zendesk_list_tickets"]()
|
||||
|
||||
@@ -72,7 +75,10 @@ class TestZendeskGetTicket:
|
||||
data = {"ticket": TICKET_DATA}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zendesk_get_ticket"](ticket_id=123)
|
||||
|
||||
@@ -90,7 +96,10 @@ class TestZendeskCreateTicket:
|
||||
data = {"ticket": {"id": 456, "subject": "New ticket", "status": "new"}}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zendesk_tool.zendesk_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.zendesk_tool.zendesk_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zendesk_create_ticket"](subject="New ticket", body="Help needed")
|
||||
|
||||
@@ -110,7 +119,10 @@ class TestZendeskUpdateTicket:
|
||||
data = {"ticket": updated}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zendesk_tool.zendesk_tool.httpx.put", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.zendesk_tool.zendesk_tool.httpx.put",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zendesk_update_ticket"](ticket_id=123, status="pending")
|
||||
|
||||
@@ -125,12 +137,17 @@ class TestZendeskSearchTickets:
|
||||
|
||||
def test_successful_search(self, tool_fns):
|
||||
data = {
|
||||
"results": [{"id": 123, "subject": "Printer issue", "status": "open", "priority": "high"}],
|
||||
"results": [
|
||||
{"id": 123, "subject": "Printer issue", "status": "open", "priority": "high"}
|
||||
],
|
||||
"count": 1,
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
patch(
|
||||
"aden_tools.tools.zendesk_tool.zendesk_tool.httpx.get",
|
||||
return_value=_mock_resp(data),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zendesk_search_tickets"](query="status:open priority:high")
|
||||
|
||||
|
||||
@@ -152,9 +152,7 @@ class TestZohoCrmAddNote:
|
||||
assert "error" in result
|
||||
|
||||
def test_successful_add(self, tool_fns):
|
||||
mock_resp = {
|
||||
"data": [{"status": "success", "details": {"id": "note-1"}}]
|
||||
}
|
||||
mock_resp = {"data": [{"status": "success", "details": {"id": "note-1"}}]}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zoho_crm_tool.zoho_crm_tool.httpx.post") as mock_post,
|
||||
|
||||
@@ -87,7 +87,19 @@ class TestZoomListMeetings:
|
||||
data = {
|
||||
"total_records": 50,
|
||||
"next_page_token": "token123",
|
||||
"meetings": [{"id": 1, "uuid": "a", "topic": "M1", "type": 2, "start_time": "", "duration": 30, "timezone": "", "join_url": "", "created_at": ""}],
|
||||
"meetings": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "a",
|
||||
"topic": "M1",
|
||||
"type": 2,
|
||||
"start_time": "",
|
||||
"duration": 30,
|
||||
"timezone": "",
|
||||
"join_url": "",
|
||||
"created_at": "",
|
||||
}
|
||||
],
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
@@ -158,7 +170,10 @@ class TestZoomCreateMeeting:
|
||||
}
|
||||
with (
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zoom_tool.zoom_tool.httpx.post", return_value=_mock_resp(data, 201)),
|
||||
patch(
|
||||
"aden_tools.tools.zoom_tool.zoom_tool.httpx.post",
|
||||
return_value=_mock_resp(data, 201),
|
||||
),
|
||||
):
|
||||
result = tool_fns["zoom_create_meeting"](
|
||||
topic="New Meeting",
|
||||
@@ -222,9 +237,7 @@ class TestZoomListRecordings:
|
||||
patch.dict("os.environ", ENV),
|
||||
patch("aden_tools.tools.zoom_tool.zoom_tool.httpx.get", return_value=_mock_resp(data)),
|
||||
):
|
||||
result = tool_fns["zoom_list_recordings"](
|
||||
from_date="2025-01-01", to_date="2025-01-31"
|
||||
)
|
||||
result = tool_fns["zoom_list_recordings"](from_date="2025-01-01", to_date="2025-01-31")
|
||||
|
||||
assert result["total_records"] == 1
|
||||
assert result["recordings"][0]["recording_count"] == 2
|
||||
|
||||
@@ -21,6 +21,7 @@ DATABASE = os.getenv("MSSQL_DATABASE", "AdenTestDB")
|
||||
USERNAME = os.getenv("MSSQL_USERNAME")
|
||||
PASSWORD = os.getenv("MSSQL_PASSWORD")
|
||||
|
||||
|
||||
def main():
|
||||
connection = None
|
||||
|
||||
@@ -82,5 +83,6 @@ def main():
|
||||
if connection:
|
||||
connection.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user