90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
import json
|
|
from typing import Any, Dict
|
|
|
|
import httpx
|
|
from langchain_core.tools import BaseTool
|
|
|
|
|
|
class RestApiTool(BaseTool):
|
|
"""RESTful API 调用工具"""
|
|
|
|
name: str = "rest_api"
|
|
description: str = (
|
|
"调用 RESTful API。输入为 JSON 字符串,示例:"
|
|
'{"method":"GET","url":"https://example.com/api","params":{},"headers":{},"body":null,"timeout":30}'
|
|
)
|
|
|
|
def _run(self, payload: str) -> str:
|
|
"""执行 RESTful API 请求"""
|
|
try:
|
|
data = json.loads(payload)
|
|
except Exception as e:
|
|
return f"请求参数解析失败: {e}"
|
|
|
|
method = str(data.get("method", "GET")).upper()
|
|
url = data.get("url")
|
|
params: Dict[str, Any] = data.get("params") or {}
|
|
headers: Dict[str, Any] = data.get("headers") or {}
|
|
body = data.get("body")
|
|
timeout = float(data.get("timeout", 30))
|
|
|
|
if not url:
|
|
return "缺少 url"
|
|
|
|
try:
|
|
with httpx.Client(timeout=timeout) as client:
|
|
response = client.request(
|
|
method=method,
|
|
url=url,
|
|
params=params,
|
|
headers=headers,
|
|
json=body,
|
|
)
|
|
return json.dumps(
|
|
{
|
|
"status_code": response.status_code,
|
|
"headers": dict(response.headers),
|
|
"text": response.text,
|
|
},
|
|
ensure_ascii=False,
|
|
)
|
|
except Exception as e:
|
|
return f"请求失败: {e}"
|
|
|
|
async def _arun(self, payload: str) -> str:
|
|
"""工具的异步版本"""
|
|
try:
|
|
data = json.loads(payload)
|
|
except Exception as e:
|
|
return f"请求参数解析失败: {e}"
|
|
|
|
method = str(data.get("method", "GET")).upper()
|
|
url = data.get("url")
|
|
params: Dict[str, Any] = data.get("params") or {}
|
|
headers: Dict[str, Any] = data.get("headers") or {}
|
|
body = data.get("body")
|
|
timeout = float(data.get("timeout", 30))
|
|
|
|
if not url:
|
|
return "缺少 url"
|
|
|
|
try:
|
|
async with httpx.AsyncClient(timeout=timeout) as client:
|
|
response = await client.request(
|
|
method=method,
|
|
url=url,
|
|
params=params,
|
|
headers=headers,
|
|
json=body,
|
|
)
|
|
return json.dumps(
|
|
{
|
|
"status_code": response.status_code,
|
|
"headers": dict(response.headers),
|
|
"text": response.text,
|
|
},
|
|
ensure_ascii=False,
|
|
)
|
|
except Exception as e:
|
|
return f"请求失败: {e}"
|