From 09f653fc4805e263fbf104759c066efaad31b69e Mon Sep 17 00:00:00 2001 From: Eitan Yarmush Date: Sat, 1 Feb 2025 17:40:04 +0000 Subject: [PATCH] run check --- .../src/autogen_ext/tools/http/_http_tool.py | 24 ++++++------ .../autogen-ext/tests/tools/http/conftest.py | 20 +++++----- .../tests/tools/http/test_http_tool.py | 38 +++++++++---------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py b/python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py index b4bdf891a6ae..7c9f847e9d43 100644 --- a/python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py +++ b/python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py @@ -90,7 +90,7 @@ class HttpTool(BaseTool[BaseModel, Any], Component[HttpToolConfig]): "properties": { "value": {"type": "string", "description": "The base64 value to decode"}, }, - "required": ["value"] + "required": ["value"], } # Create an HTTP tool for the weather API @@ -102,24 +102,23 @@ class HttpTool(BaseTool[BaseModel, Any], Component[HttpToolConfig]): port=443, path="/base64/{value}", method="GET", - json_schema=base64_schema + json_schema=base64_schema, ) + async def main(): # Create an assistant with the base64 tool model = OpenAIChatCompletionClient(model="gpt-4") - assistant = AssistantAgent( - "base64_assistant", - model_client=model, - tools=[base64_tool] - ) + assistant = AssistantAgent("base64_assistant", model_client=model, tools=[base64_tool]) # The assistant can now use the base64 tool to decode the string - response = await assistant.on_messages([ - TextMessage(content="Can you base64 decode the value 'YWJjZGU=', please?", source="user") - ], CancellationToken()) + response = await assistant.on_messages( + [TextMessage(content="Can you base64 decode the value 'YWJjZGU=', please?", source="user")], + CancellationToken(), + ) print(response.chat_message.content) + asyncio.run(main()) """ @@ -161,9 +160,9 @@ def __init__( input_model = create_model(json_schema) # Use Any as return type since HTTP responses can vary - return_type: Type[Any] = object + base_return_type: Type[Any] = object - super().__init__(input_model, return_type, name, description) + super().__init__(input_model, base_return_type, name, description) def _to_config(self) -> HttpToolConfig: copied_config = self.server_params.model_copy() @@ -188,7 +187,6 @@ async def run(self, args: BaseModel, cancellation_token: CancellationToken) -> A Exception: If tool execution fails """ - model_dump = args.model_dump() path_params = {k: v for k, v in model_dump.items() if k in self._path_params} # Remove path params from the model dump diff --git a/python/packages/autogen-ext/tests/tools/http/conftest.py b/python/packages/autogen-ext/tests/tools/http/conftest.py index fd3c5e4a537d..1f9485b6f7e7 100644 --- a/python/packages/autogen-ext/tests/tools/http/conftest.py +++ b/python/packages/autogen-ext/tests/tools/http/conftest.py @@ -4,8 +4,7 @@ import pytest import pytest_asyncio import uvicorn -from autogen_core import CancellationToken, ComponentModel -from autogen_ext.tools.http import HttpTool +from autogen_core import ComponentModel from fastapi import Body, FastAPI from pydantic import BaseModel, Field @@ -24,20 +23,19 @@ class TestResponse(BaseModel): @app.post("/test") -async def test_endpoint(body: TestArgs = Body(...)) -> TestResponse: +async def test_endpoint(body: TestArgs) -> TestResponse: return TestResponse(result=f"Received: {body.query} with value {body.value}") + @app.post("/test/{query}/{value}") async def test_path_params_endpoint(query: str, value: int) -> TestResponse: return TestResponse(result=f"Received: {query} with value {value}") + @app.put("/test/{query}/{value}") -async def test_path_params_and_body_endpoint( - query: str, - value: int, - body: dict = Body(...) -) -> TestResponse: - return TestResponse(result=f"Received: {query} with value {value} and extra {body.get("extra")}") +async def test_path_params_and_body_endpoint(query: str, value: int, body: dict) -> TestResponse: + return TestResponse(result=f"Received: {query} with value {value} and extra {body.get('extra')}") + @app.get("/test") async def test_get_endpoint(query: str, value: int) -> TestResponse: @@ -45,7 +43,7 @@ async def test_get_endpoint(query: str, value: int) -> TestResponse: @app.put("/test") -async def test_put_endpoint(body: TestArgs = Body(...)) -> TestResponse: +async def test_put_endpoint(body: TestArgs) -> TestResponse: return TestResponse(result=f"Received: {body.query} with value {body.value}") @@ -55,7 +53,7 @@ async def test_delete_endpoint(query: str, value: int) -> TestResponse: @app.patch("/test") -async def test_patch_endpoint(body: TestArgs = Body(...)) -> TestResponse: +async def test_patch_endpoint(body: TestArgs) -> TestResponse: return TestResponse(result=f"Received: {body.query} with value {body.value}") diff --git a/python/packages/autogen-ext/tests/tools/http/test_http_tool.py b/python/packages/autogen-ext/tests/tools/http/test_http_tool.py index defdc9134e2c..3756c48474d0 100644 --- a/python/packages/autogen-ext/tests/tools/http/test_http_tool.py +++ b/python/packages/autogen-ext/tests/tools/http/test_http_tool.py @@ -90,6 +90,7 @@ async def test_put_request(test_config: ComponentModel, test_server: None) -> No assert isinstance(result, str) assert json.loads(result)["result"] == "Received: test query with value 42" + @pytest.mark.asyncio async def test_path_params(test_config: ComponentModel, test_server: None) -> None: # Modify config to use path parameters @@ -102,6 +103,7 @@ async def test_path_params(test_config: ComponentModel, test_server: None) -> No assert isinstance(result, str) assert json.loads(result)["result"] == "Received: test query with value 42" + @pytest.mark.asyncio async def test_path_params_and_body(test_config: ComponentModel, test_server: None) -> None: # Modify config to use path parameters and include body parameters @@ -109,28 +111,22 @@ async def test_path_params_and_body(test_config: ComponentModel, test_server: No config.config["method"] = "PUT" config.config["path"] = "/test/{query}/{value}" config.config["json_schema"] = { - "type": "object", + "type": "object", "properties": { "query": {"type": "string", "description": "The test query"}, "value": {"type": "integer", "description": "A test value"}, - "extra": {"type": "string", "description": "Extra body parameter"} + "extra": {"type": "string", "description": "Extra body parameter"}, }, - "required": ["query", "value", "extra"] + "required": ["query", "value", "extra"], } tool = HttpTool.load_component(config) - result = await tool.run_json({ - "query": "test query", - "value": 42, - "extra": "extra data" - }, CancellationToken()) + result = await tool.run_json({"query": "test query", "value": 42, "extra": "extra data"}, CancellationToken()) assert isinstance(result, str) assert json.loads(result)["result"] == "Received: test query with value 42 and extra extra data" - - @pytest.mark.asyncio async def test_delete_request(test_config: ComponentModel, test_server: None) -> None: # Modify config for DELETE request @@ -161,7 +157,7 @@ async def test_patch_request(test_config: ComponentModel, test_server: None) -> async def test_invalid_schema(test_config: ComponentModel, test_server: None) -> None: # Create an invalid schema missing required properties config: ComponentModel = test_config.model_copy() - config.config["host"] = True # Incorrect type + config.config["host"] = True # Incorrect type with pytest.raises(ValidationError): # Should fail when trying to create model from invalid schema @@ -181,16 +177,16 @@ async def test_invalid_request(test_config: ComponentModel, test_server: None) - def test_config_serialization(test_config: ComponentModel) -> None: tool = HttpTool.load_component(test_config) - config = tool._to_config() - - assert config.name == test_config.config["name"] - assert config.description == test_config.config["description"] - assert config.host == test_config.config["host"] - assert config.port == test_config.config["port"] - assert config.path == test_config.config["path"] - assert config.scheme == test_config.config["scheme"] - assert config.method == test_config.config["method"] - assert config.headers == test_config.config["headers"] + config = tool.dump_component() + + assert config.config["name"] == test_config.config["name"] + assert config.config["description"] == test_config.config["description"] + assert config.config["host"] == test_config.config["host"] + assert config.config["port"] == test_config.config["port"] + assert config.config["path"] == test_config.config["path"] + assert config.config["scheme"] == test_config.config["scheme"] + assert config.config["method"] == test_config.config["method"] + assert config.config["headers"] == test_config.config["headers"] def test_config_deserialization(test_config: ComponentModel) -> None: