Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions agentrun/utils/__data_api_async_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ async def get_async(
"""
return await self._make_request_async(
"GET",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -470,7 +470,7 @@ async def post_async(

return await self._make_request_async(
"POST",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -501,7 +501,7 @@ async def put_async(
"""
return await self._make_request_async(
"PUT",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -532,7 +532,7 @@ async def patch_async(
"""
return await self._make_request_async(
"PATCH",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -561,7 +561,7 @@ async def delete_async(
"""
return await self._make_request_async(
"DELETE",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -601,7 +601,7 @@ async def post_file_async(

filename = os.path.basename(local_file_path)

url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -656,7 +656,7 @@ async def get_file_async(
Examples:
>>> await client.get_file_async("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -707,7 +707,7 @@ async def get_video_async(
Examples:
>>> await client.get_video_async("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down
32 changes: 16 additions & 16 deletions agentrun/utils/data_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ async def get_async(
"""
return await self._make_request_async(
"GET",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -561,7 +561,7 @@ def get(
"""
return self._make_request(
"GET",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -596,7 +596,7 @@ async def post_async(

return await self._make_request_async(
"POST",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -632,7 +632,7 @@ def post(

return self._make_request(
"POST",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -663,7 +663,7 @@ async def put_async(
"""
return await self._make_request_async(
"PUT",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -694,7 +694,7 @@ def put(
"""
return self._make_request(
"PUT",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -725,7 +725,7 @@ async def patch_async(
"""
return await self._make_request_async(
"PATCH",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -756,7 +756,7 @@ def patch(
"""
return self._make_request(
"PATCH",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
data=data,
headers=headers,
config=config,
Expand Down Expand Up @@ -785,7 +785,7 @@ async def delete_async(
"""
return await self._make_request_async(
"DELETE",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -813,7 +813,7 @@ def delete(
"""
return self._make_request(
"DELETE",
self.with_path(path, query=query),
self.with_path(path, query=query, config=config),
headers=headers,
config=config,
)
Expand Down Expand Up @@ -853,7 +853,7 @@ async def post_file_async(

filename = os.path.basename(local_file_path)

url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -917,7 +917,7 @@ def post_file(

filename = os.path.basename(local_file_path)

url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -970,7 +970,7 @@ async def get_file_async(
Examples:
>>> await client.get_file_async("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -1021,7 +1021,7 @@ def get_file(
Examples:
>>> client.get_file("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -1070,7 +1070,7 @@ async def get_video_async(
Examples:
>>> await client.get_video_async("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down Expand Up @@ -1121,7 +1121,7 @@ def get_video(
Examples:
>>> client.get_video("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"})
"""
url = self.with_path(path, query=query)
url = self.with_path(path, query=query, config=config)
req_headers = self.config.get_headers()
req_headers.update(headers or {})
# Apply authentication (may modify URL, headers, and query)
Expand Down
119 changes: 119 additions & 0 deletions tests/unittests/utils/test_data_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1206,3 +1206,122 @@ def test_auth_with_sandbox_uses_ram_when_ak_sk_provided(
api.get_base_url().startswith("https://")
and "-ram." in api.get_base_url()
)


class TestDataAPIConfigForwarding:
"""测试 DataAPI 的 config 透传到 with_path 的行为(修复 issue #75)

当 DataAPI 实例初始化时没有提供 account_id(如通过 __get_client() 获取的无配置客户端),
但在调用 HTTP 方法时通过 config 参数传入 account_id,URL 应该使用该 account_id 构造。
"""

@respx.mock
def test_get_uses_call_time_config_for_url(self):
"""测试 get() 使用调用时传入的 config 构造 URL(不依赖实例 config 的 account_id)"""
# 实例创建时不提供 account_id(模拟 __get_client() 无配置的情况)
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
config=None,
namespace="sandboxes",
)

# 调用时传入带有 account_id 的 config
call_config = Config(
account_id="call-time-account",
access_key_id="",
access_key_secret="",
region_id="cn-hangzhou",
)

respx.get(
"https://call-time-account.agentrun-data.cn-hangzhou.aliyuncs.com/sandboxes"
).mock(return_value=httpx.Response(200, json={"code": "SUCCESS"}))

result = api.get("/", config=call_config)
assert result == {"code": "SUCCESS"}

@respx.mock
def test_post_uses_call_time_config_for_url(self):
"""测试 post() 使用调用时传入的 config 构造 URL"""
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
config=None,
namespace="sandboxes",
)

call_config = Config(
account_id="call-time-account",
access_key_id="",
access_key_secret="",
region_id="cn-hangzhou",
)

respx.post(
"https://call-time-account.agentrun-data.cn-hangzhou.aliyuncs.com/sandboxes"
).mock(return_value=httpx.Response(200, json={"code": "SUCCESS"}))

result = api.post("/", data={"key": "val"}, config=call_config)
assert result == {"code": "SUCCESS"}

@respx.mock
def test_delete_uses_call_time_config_for_url(self):
"""测试 delete() 使用调用时传入的 config 构造 URL"""
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
config=None,
namespace="sandboxes",
)

call_config = Config(
account_id="call-time-account",
access_key_id="",
access_key_secret="",
region_id="cn-hangzhou",
)

respx.delete(
"https://call-time-account.agentrun-data.cn-hangzhou.aliyuncs.com/sandboxes"
).mock(return_value=httpx.Response(200, json={"code": "SUCCESS"}))

result = api.delete("/", config=call_config)
assert result == {"code": "SUCCESS"}

@respx.mock
@pytest.mark.asyncio
async def test_post_async_uses_call_time_config_for_url(self):
"""测试 post_async() 使用调用时传入的 config 构造 URL"""
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
config=None,
namespace="sandboxes",
)

call_config = Config(
account_id="call-time-account",
access_key_id="",
access_key_secret="",
region_id="cn-hangzhou",
)

respx.post(
"https://call-time-account.agentrun-data.cn-hangzhou.aliyuncs.com/sandboxes"
).mock(return_value=httpx.Response(200, json={"code": "SUCCESS"}))

result = await api.post_async("/", data={"key": "val"}, config=call_config)
assert result == {"code": "SUCCESS"}

def test_no_account_id_without_call_time_config_raises(self):
"""测试未在实例 config 或调用 config 中设置 account_id 时抛出 ValueError"""
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
config=None,
namespace="sandboxes",
)

with pytest.raises(ValueError, match="account id is not set"):
api.with_path("/")
Loading