Skip to content

Commit 3cd1d9d

Browse files
feat(auth): support auto auth for web search (#272)
* feat(auth): support auto auth for web search * change version
1 parent e1c7db2 commit 3cd1d9d

File tree

3 files changed

+40
-156
lines changed

3 files changed

+40
-156
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "veadk-python"
3-
version = "0.2.16"
3+
version = "0.2.17"
44
description = "Volcengine agent development kit, integrations with Volcengine cloud services."
55
readme = "README.md"
66
requires-python = ">=3.10"

veadk/tools/builtin_tools/web_search.py

Lines changed: 38 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -16,142 +16,17 @@
1616
The document of this tool see: https://www.volcengine.com/docs/85508/1650263
1717
"""
1818

19-
import datetime
20-
import hashlib
21-
import hmac
22-
import json
23-
from urllib.parse import quote
19+
import os
2420

25-
import requests
2621
from google.adk.tools import ToolContext
2722

28-
from veadk.config import getenv
23+
from veadk.auth.veauth.utils import get_credential_from_vefaas_iam
2924
from veadk.utils.logger import get_logger
25+
from veadk.utils.volcengine_sign import ve_request
3026

3127
logger = get_logger(__name__)
3228

3329

34-
Service = "volc_torchlight_api"
35-
Version = "2025-01-01"
36-
Region = "cn-beijing"
37-
Host = "mercury.volcengineapi.com"
38-
ContentType = "application/json"
39-
40-
41-
def norm_query(params):
42-
query = ""
43-
for key in sorted(params.keys()):
44-
if isinstance(params[key], list):
45-
for k in params[key]:
46-
query = (
47-
query + quote(key, safe="-_.~") + "=" + quote(k, safe="-_.~") + "&"
48-
)
49-
else:
50-
query = (
51-
query
52-
+ quote(key, safe="-_.~")
53-
+ "="
54-
+ quote(params[key], safe="-_.~")
55-
+ "&"
56-
)
57-
query = query[:-1]
58-
return query.replace("+", "%20")
59-
60-
61-
def hmac_sha256(key: bytes, content: str):
62-
return hmac.new(key, content.encode("utf-8"), hashlib.sha256).digest()
63-
64-
65-
def hash_sha256(content: str):
66-
return hashlib.sha256(content.encode("utf-8")).hexdigest()
67-
68-
69-
def request(method, date, query, header, ak, sk, action, body):
70-
credential = {
71-
"access_key_id": ak,
72-
"secret_access_key": sk,
73-
"service": Service,
74-
"region": Region,
75-
}
76-
request_param = {
77-
"body": body,
78-
"host": Host,
79-
"path": "/",
80-
"method": method,
81-
"content_type": ContentType,
82-
"date": date,
83-
"query": {"Action": action, "Version": Version, **query},
84-
}
85-
if body is None:
86-
request_param["body"] = ""
87-
# 第四步:接下来开始计算签名。在计算签名前,先准备好用于接收签算结果的 signResult 变量,并设置一些参数。
88-
# 初始化签名结果的结构体
89-
x_date = request_param["date"].strftime("%Y%m%dT%H%M%SZ")
90-
short_x_date = x_date[:8]
91-
x_content_sha256 = hash_sha256(request_param["body"])
92-
sign_result = {
93-
"Host": request_param["host"],
94-
"X-Content-Sha256": x_content_sha256,
95-
"X-Date": x_date,
96-
"Content-Type": request_param["content_type"],
97-
}
98-
signed_headers_str = ";".join(
99-
["content-type", "host", "x-content-sha256", "x-date"]
100-
)
101-
# signed_headers_str = signed_headers_str + ";x-security-token"
102-
canonical_request_str = "\n".join(
103-
[
104-
request_param["method"].upper(),
105-
request_param["path"],
106-
norm_query(request_param["query"]),
107-
"\n".join(
108-
[
109-
"content-type:" + request_param["content_type"],
110-
"host:" + request_param["host"],
111-
"x-content-sha256:" + x_content_sha256,
112-
"x-date:" + x_date,
113-
]
114-
),
115-
"",
116-
signed_headers_str,
117-
x_content_sha256,
118-
]
119-
)
120-
121-
hashed_canonical_request = hash_sha256(canonical_request_str)
122-
123-
credential_scope = "/".join(
124-
[short_x_date, credential["region"], credential["service"], "request"]
125-
)
126-
string_to_sign = "\n".join(
127-
["HMAC-SHA256", x_date, credential_scope, hashed_canonical_request]
128-
)
129-
130-
k_date = hmac_sha256(credential["secret_access_key"].encode("utf-8"), short_x_date)
131-
k_region = hmac_sha256(k_date, credential["region"])
132-
k_service = hmac_sha256(k_region, credential["service"])
133-
k_signing = hmac_sha256(k_service, "request")
134-
signature = hmac_sha256(k_signing, string_to_sign).hex()
135-
136-
sign_result["Authorization"] = (
137-
"HMAC-SHA256 Credential={}, SignedHeaders={}, Signature={}".format(
138-
credential["access_key_id"] + "/" + credential_scope,
139-
signed_headers_str,
140-
signature,
141-
)
142-
)
143-
header = {**header, **sign_result}
144-
# header = {**header, **{"X-Security-Token": SessionToken}}
145-
r = requests.request(
146-
method=method,
147-
url="https://{}{}".format(request_param["host"], request_param["path"]),
148-
headers=header,
149-
params=request_param["query"],
150-
data=request_param["body"],
151-
)
152-
return r.json()
153-
154-
15530
def web_search(query: str, tool_context: ToolContext) -> list[str]:
15631
"""Search a query in websites.
15732
@@ -161,39 +36,48 @@ def web_search(query: str, tool_context: ToolContext) -> list[str]:
16136
Returns:
16237
A list of result documents.
16338
"""
164-
req = {
165-
"Query": query,
166-
"SearchType": "web",
167-
"Count": 5,
168-
"NeedSummary": True,
169-
}
170-
17139
ak = tool_context.state.get("VOLCENGINE_ACCESS_KEY")
172-
if not ak:
173-
ak = getenv("VOLCENGINE_ACCESS_KEY")
174-
17540
sk = tool_context.state.get("VOLCENGINE_SECRET_KEY")
176-
if not sk:
177-
sk = getenv("VOLCENGINE_SECRET_KEY")
178-
179-
now = datetime.datetime.utcnow()
180-
response_body = request(
181-
"POST",
182-
now,
183-
{},
184-
{},
185-
ak,
186-
sk,
187-
"WebSearch",
188-
json.dumps(req),
41+
session_token = ""
42+
43+
if not (ak and sk):
44+
logger.debug("Get AK/SK from tool context failed.")
45+
ak = os.getenv("VOLCENGINE_ACCESS_KEY")
46+
sk = os.getenv("VOLCENGINE_SECRET_KEY")
47+
if not (ak and sk):
48+
logger.debug("Get AK/SK from environment variables failed.")
49+
credential = get_credential_from_vefaas_iam()
50+
ak = credential.access_key_id
51+
sk = credential.secret_access_key
52+
session_token = credential.session_token
53+
else:
54+
logger.debug("Successfully get AK/SK from environment variables.")
55+
else:
56+
logger.debug("Successfully get AK/SK from tool context.")
57+
58+
response = ve_request(
59+
request_body={
60+
"Query": query,
61+
"SearchType": "web",
62+
"Count": 5,
63+
"NeedSummary": True,
64+
},
65+
action="WebSearch",
66+
ak=ak,
67+
sk=sk,
68+
service="volc_torchlight_api",
69+
version="2025-01-01",
70+
region="cn-beijing",
71+
host="mercury.volcengineapi.com",
72+
header={"X-Security-Token": session_token},
18973
)
19074

19175
try:
192-
results: list = response_body["Result"]["WebResults"]
76+
results: list = response["Result"]["WebResults"]
19377
final_results = []
19478
for result in results:
19579
final_results.append(result["Summary"].strip())
19680
return final_results
19781
except Exception as e:
198-
logger.error(f"Web search failed {e}, response body: {response_body}")
199-
return [response_body]
82+
logger.error(f"Web search failed {e}, response body: {response}")
83+
return [response]

veadk/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
VERSION = "0.2.16"
15+
VERSION = "0.2.17"

0 commit comments

Comments
 (0)