google-adk 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/adk/agents/run_config.py +4 -0
- google/adk/auth/auth_preprocessor.py +19 -16
- google/adk/cli/agent_graph.py +31 -5
- google/adk/cli/browser/index.html +1 -1
- google/adk/cli/browser/{main-XUU6OGCC.js → main-CU22TRPI.js} +30 -30
- google/adk/cli/cli.py +8 -8
- google/adk/cli/cli_deploy.py +2 -4
- google/adk/cli/cli_tools_click.py +57 -12
- google/adk/cli/fast_api.py +19 -9
- google/adk/flows/llm_flows/contents.py +21 -1
- google/adk/flows/llm_flows/functions.py +3 -1
- google/adk/models/google_llm.py +0 -1
- google/adk/runners.py +13 -2
- google/adk/version.py +1 -1
- {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/METADATA +4 -2
- google_adk-0.0.4.dist-info/RECORD +175 -0
- {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/WHEEL +1 -1
- google/adk/cli/media_streamer/__init__.py +0 -19
- google/adk/cli/media_streamer/index.html +0 -228
- google/adk/tests/__init__.py +0 -14
- google/adk/tests/integration/.env.example +0 -10
- google/adk/tests/integration/__init__.py +0 -18
- google/adk/tests/integration/conftest.py +0 -119
- google/adk/tests/integration/fixture/__init__.py +0 -14
- google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
- google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
- google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
- google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
- google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
- google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
- google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
- google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
- google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
- google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
- google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
- google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
- google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +0 -243
- google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
- google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
- google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
- google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
- google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
- google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
- google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
- google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
- google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
- google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
- google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
- google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
- google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
- google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
- google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
- google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
- google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
- google/adk/tests/integration/models/__init__.py +0 -14
- google/adk/tests/integration/models/test_google_llm.py +0 -65
- google/adk/tests/integration/test_callback.py +0 -70
- google/adk/tests/integration/test_context_variable.py +0 -67
- google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
- google/adk/tests/integration/test_multi_agent.py +0 -28
- google/adk/tests/integration/test_multi_turn.py +0 -42
- google/adk/tests/integration/test_single_agent.py +0 -23
- google/adk/tests/integration/test_sub_agent.py +0 -26
- google/adk/tests/integration/test_system_instruction.py +0 -177
- google/adk/tests/integration/test_tools.py +0 -287
- google/adk/tests/integration/test_with_test_file.py +0 -34
- google/adk/tests/integration/tools/__init__.py +0 -14
- google/adk/tests/integration/utils/__init__.py +0 -16
- google/adk/tests/integration/utils/asserts.py +0 -75
- google/adk/tests/integration/utils/test_runner.py +0 -97
- google/adk/tests/unittests/__init__.py +0 -14
- google/adk/tests/unittests/agents/__init__.py +0 -14
- google/adk/tests/unittests/agents/test_base_agent.py +0 -407
- google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
- google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
- google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
- google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
- google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
- google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
- google/adk/tests/unittests/artifacts/__init__.py +0 -14
- google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
- google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
- google/adk/tests/unittests/conftest.py +0 -73
- google/adk/tests/unittests/fast_api/__init__.py +0 -14
- google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
- google/adk/tests/unittests/flows/__init__.py +0 -14
- google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
- google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
- google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
- google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
- google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
- google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
- google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
- google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
- google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
- google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
- google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
- google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
- google/adk/tests/unittests/models/__init__.py +0 -14
- google/adk/tests/unittests/models/test_google_llm.py +0 -224
- google/adk/tests/unittests/models/test_litellm.py +0 -804
- google/adk/tests/unittests/models/test_models.py +0 -60
- google/adk/tests/unittests/sessions/__init__.py +0 -14
- google/adk/tests/unittests/sessions/test_session_service.py +0 -227
- google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
- google/adk/tests/unittests/streaming/__init__.py +0 -14
- google/adk/tests/unittests/streaming/test_streaming.py +0 -50
- google/adk/tests/unittests/tools/__init__.py +0 -14
- google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
- google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
- google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
- google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
- google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
- google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
- google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
- google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
- google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
- google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
- google/adk/tests/unittests/tools/test_base_tool.py +0 -141
- google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
- google/adk/tests/unittests/utils.py +0 -304
- google_adk-0.0.2.dist-info/RECORD +0 -308
- {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/entry_points.txt +0 -0
- {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,139 +0,0 @@
|
|
1
|
-
# Copyright 2025 Google LLC
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
import os
|
16
|
-
from typing import Dict
|
17
|
-
|
18
|
-
from fastapi.openapi.models import APIKey
|
19
|
-
from fastapi.openapi.models import APIKeyIn
|
20
|
-
from fastapi.openapi.models import MediaType
|
21
|
-
from fastapi.openapi.models import OAuth2
|
22
|
-
from fastapi.openapi.models import ParameterInType
|
23
|
-
from fastapi.openapi.models import SecuritySchemeType
|
24
|
-
from google.adk.auth.auth_credential import AuthCredential
|
25
|
-
from google.adk.auth.auth_credential import AuthCredentialTypes
|
26
|
-
from google.adk.tools.openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset
|
27
|
-
from google.adk.tools.openapi_tool.openapi_spec_parser.rest_api_tool import RestApiTool
|
28
|
-
import pytest
|
29
|
-
import yaml
|
30
|
-
|
31
|
-
|
32
|
-
def load_spec(file_path: str) -> Dict:
|
33
|
-
"""Loads the OpenAPI specification from a YAML file."""
|
34
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
35
|
-
return yaml.safe_load(f)
|
36
|
-
|
37
|
-
|
38
|
-
@pytest.fixture
|
39
|
-
def openapi_spec() -> Dict:
|
40
|
-
"""Fixture to load the OpenAPI specification."""
|
41
|
-
current_dir = os.path.dirname(os.path.abspath(__file__))
|
42
|
-
# Join the directory path with the filename
|
43
|
-
yaml_path = os.path.join(current_dir, "test.yaml")
|
44
|
-
return load_spec(yaml_path)
|
45
|
-
|
46
|
-
|
47
|
-
def test_openapi_toolset_initialization_from_dict(openapi_spec: Dict):
|
48
|
-
"""Test initialization of OpenAPIToolset with a dictionary."""
|
49
|
-
toolset = OpenAPIToolset(spec_dict=openapi_spec)
|
50
|
-
assert isinstance(toolset.tools, list)
|
51
|
-
assert len(toolset.tools) == 5
|
52
|
-
assert all(isinstance(tool, RestApiTool) for tool in toolset.tools)
|
53
|
-
|
54
|
-
|
55
|
-
def test_openapi_toolset_initialization_from_yaml_string(openapi_spec: Dict):
|
56
|
-
"""Test initialization of OpenAPIToolset with a YAML string."""
|
57
|
-
spec_str = yaml.dump(openapi_spec)
|
58
|
-
toolset = OpenAPIToolset(spec_str=spec_str, spec_str_type="yaml")
|
59
|
-
assert isinstance(toolset.tools, list)
|
60
|
-
assert len(toolset.tools) == 5
|
61
|
-
assert all(isinstance(tool, RestApiTool) for tool in toolset.tools)
|
62
|
-
|
63
|
-
|
64
|
-
def test_openapi_toolset_tool_existing(openapi_spec: Dict):
|
65
|
-
"""Test the tool() method for an existing tool."""
|
66
|
-
toolset = OpenAPIToolset(spec_dict=openapi_spec)
|
67
|
-
tool_name = "calendar_calendars_insert" # Example operationId from the spec
|
68
|
-
tool = toolset.get_tool(tool_name)
|
69
|
-
assert isinstance(tool, RestApiTool)
|
70
|
-
assert tool.name == tool_name
|
71
|
-
assert tool.description == "Creates a secondary calendar."
|
72
|
-
assert tool.endpoint.method == "post"
|
73
|
-
assert tool.endpoint.base_url == "https://www.googleapis.com/calendar/v3"
|
74
|
-
assert tool.endpoint.path == "/calendars"
|
75
|
-
assert tool.is_long_running is False
|
76
|
-
assert tool.operation.operationId == "calendar.calendars.insert"
|
77
|
-
assert tool.operation.description == "Creates a secondary calendar."
|
78
|
-
assert isinstance(
|
79
|
-
tool.operation.requestBody.content["application/json"], MediaType
|
80
|
-
)
|
81
|
-
assert len(tool.operation.responses) == 1
|
82
|
-
response = tool.operation.responses["200"]
|
83
|
-
assert response.description == "Successful response"
|
84
|
-
assert isinstance(response.content["application/json"], MediaType)
|
85
|
-
assert isinstance(tool.auth_scheme, OAuth2)
|
86
|
-
|
87
|
-
tool_name = "calendar_calendars_get"
|
88
|
-
tool = toolset.get_tool(tool_name)
|
89
|
-
assert isinstance(tool, RestApiTool)
|
90
|
-
assert tool.name == tool_name
|
91
|
-
assert tool.description == "Returns metadata for a calendar."
|
92
|
-
assert tool.endpoint.method == "get"
|
93
|
-
assert tool.endpoint.base_url == "https://www.googleapis.com/calendar/v3"
|
94
|
-
assert tool.endpoint.path == "/calendars/{calendarId}"
|
95
|
-
assert tool.is_long_running is False
|
96
|
-
assert tool.operation.operationId == "calendar.calendars.get"
|
97
|
-
assert tool.operation.description == "Returns metadata for a calendar."
|
98
|
-
assert len(tool.operation.parameters) == 1
|
99
|
-
assert tool.operation.parameters[0].name == "calendarId"
|
100
|
-
assert tool.operation.parameters[0].in_ == ParameterInType.path
|
101
|
-
assert tool.operation.parameters[0].required is True
|
102
|
-
assert tool.operation.parameters[0].schema_.type == "string"
|
103
|
-
assert (
|
104
|
-
tool.operation.parameters[0].description
|
105
|
-
== "Calendar identifier. To retrieve calendar IDs call the"
|
106
|
-
" calendarList.list method. If you want to access the primary calendar"
|
107
|
-
' of the currently logged in user, use the "primary" keyword.'
|
108
|
-
)
|
109
|
-
assert isinstance(tool.auth_scheme, OAuth2)
|
110
|
-
|
111
|
-
assert isinstance(toolset.get_tool("calendar_calendars_update"), RestApiTool)
|
112
|
-
assert isinstance(toolset.get_tool("calendar_calendars_delete"), RestApiTool)
|
113
|
-
assert isinstance(toolset.get_tool("calendar_calendars_patch"), RestApiTool)
|
114
|
-
|
115
|
-
|
116
|
-
def test_openapi_toolset_tool_non_existing(openapi_spec: Dict):
|
117
|
-
"""Test the tool() method for a non-existing tool."""
|
118
|
-
toolset = OpenAPIToolset(spec_dict=openapi_spec)
|
119
|
-
tool = toolset.get_tool("non_existent_tool")
|
120
|
-
assert tool is None
|
121
|
-
|
122
|
-
|
123
|
-
def test_openapi_toolset_configure_auth_on_init(openapi_spec: Dict):
|
124
|
-
"""Test configuring auth during initialization."""
|
125
|
-
|
126
|
-
auth_scheme = APIKey(**{
|
127
|
-
"in": APIKeyIn.header, # Use alias name in dict
|
128
|
-
"name": "api_key",
|
129
|
-
"type": SecuritySchemeType.http,
|
130
|
-
})
|
131
|
-
auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
|
132
|
-
toolset = OpenAPIToolset(
|
133
|
-
spec_dict=openapi_spec,
|
134
|
-
auth_scheme=auth_scheme,
|
135
|
-
auth_credential=auth_credential,
|
136
|
-
)
|
137
|
-
for tool in toolset.tools:
|
138
|
-
assert tool.auth_scheme == auth_scheme
|
139
|
-
assert tool.auth_credential == auth_credential
|
@@ -1,406 +0,0 @@
|
|
1
|
-
# Copyright 2025 Google LLC
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
from fastapi.openapi.models import MediaType
|
16
|
-
from fastapi.openapi.models import Operation
|
17
|
-
from fastapi.openapi.models import Parameter
|
18
|
-
from fastapi.openapi.models import RequestBody
|
19
|
-
from fastapi.openapi.models import Response
|
20
|
-
from fastapi.openapi.models import Schema
|
21
|
-
from google.adk.tools.openapi_tool.common.common import ApiParameter
|
22
|
-
from google.adk.tools.openapi_tool.openapi_spec_parser.operation_parser import OperationParser
|
23
|
-
import pytest
|
24
|
-
|
25
|
-
|
26
|
-
@pytest.fixture
|
27
|
-
def sample_operation() -> Operation:
|
28
|
-
"""Fixture to provide a sample OpenAPI Operation object."""
|
29
|
-
return Operation(
|
30
|
-
operationId='test_operation',
|
31
|
-
summary='Test Summary',
|
32
|
-
description='Test Description',
|
33
|
-
parameters=[
|
34
|
-
Parameter(**{
|
35
|
-
'name': 'param1',
|
36
|
-
'in': 'query',
|
37
|
-
'schema': Schema(type='string'),
|
38
|
-
'description': 'Parameter 1',
|
39
|
-
}),
|
40
|
-
Parameter(**{
|
41
|
-
'name': 'param2',
|
42
|
-
'in': 'header',
|
43
|
-
'schema': Schema(type='string'),
|
44
|
-
'description': 'Parameter 2',
|
45
|
-
}),
|
46
|
-
],
|
47
|
-
requestBody=RequestBody(
|
48
|
-
content={
|
49
|
-
'application/json': MediaType(
|
50
|
-
schema=Schema(
|
51
|
-
type='object',
|
52
|
-
properties={
|
53
|
-
'prop1': Schema(
|
54
|
-
type='string', description='Property 1'
|
55
|
-
),
|
56
|
-
'prop2': Schema(
|
57
|
-
type='integer', description='Property 2'
|
58
|
-
),
|
59
|
-
},
|
60
|
-
)
|
61
|
-
)
|
62
|
-
},
|
63
|
-
description='Request body description',
|
64
|
-
),
|
65
|
-
responses={
|
66
|
-
'200': Response(
|
67
|
-
description='Success',
|
68
|
-
content={
|
69
|
-
'application/json': MediaType(schema=Schema(type='string'))
|
70
|
-
},
|
71
|
-
),
|
72
|
-
'400': Response(description='Client Error'),
|
73
|
-
},
|
74
|
-
security=[{'oauth2': ['resource: read', 'resource: write']}],
|
75
|
-
)
|
76
|
-
|
77
|
-
|
78
|
-
def test_operation_parser_initialization(sample_operation):
|
79
|
-
"""Test initialization of OperationParser."""
|
80
|
-
parser = OperationParser(sample_operation)
|
81
|
-
assert parser.operation == sample_operation
|
82
|
-
assert len(parser.params) == 4 # 2 params + 2 request body props
|
83
|
-
assert parser.return_value is not None
|
84
|
-
|
85
|
-
|
86
|
-
def test_process_operation_parameters(sample_operation):
|
87
|
-
"""Test _process_operation_parameters method."""
|
88
|
-
parser = OperationParser(sample_operation, should_parse=False)
|
89
|
-
parser._process_operation_parameters()
|
90
|
-
assert len(parser.params) == 2
|
91
|
-
assert parser.params[0].original_name == 'param1'
|
92
|
-
assert parser.params[0].param_location == 'query'
|
93
|
-
assert parser.params[1].original_name == 'param2'
|
94
|
-
assert parser.params[1].param_location == 'header'
|
95
|
-
|
96
|
-
|
97
|
-
def test_process_request_body(sample_operation):
|
98
|
-
"""Test _process_request_body method."""
|
99
|
-
parser = OperationParser(sample_operation, should_parse=False)
|
100
|
-
parser._process_request_body()
|
101
|
-
assert len(parser.params) == 2 # 2 properties in request body
|
102
|
-
assert parser.params[0].original_name == 'prop1'
|
103
|
-
assert parser.params[0].param_location == 'body'
|
104
|
-
assert parser.params[1].original_name == 'prop2'
|
105
|
-
assert parser.params[1].param_location == 'body'
|
106
|
-
|
107
|
-
|
108
|
-
def test_process_request_body_array():
|
109
|
-
"""Test _process_request_body method with array schema."""
|
110
|
-
operation = Operation(
|
111
|
-
requestBody=RequestBody(
|
112
|
-
content={
|
113
|
-
'application/json': MediaType(
|
114
|
-
schema=Schema(
|
115
|
-
type='array',
|
116
|
-
items=Schema(
|
117
|
-
type='object',
|
118
|
-
properties={
|
119
|
-
'item_prop1': Schema(
|
120
|
-
type='string', description='Item Property 1'
|
121
|
-
),
|
122
|
-
'item_prop2': Schema(
|
123
|
-
type='integer', description='Item Property 2'
|
124
|
-
),
|
125
|
-
},
|
126
|
-
),
|
127
|
-
)
|
128
|
-
)
|
129
|
-
}
|
130
|
-
)
|
131
|
-
)
|
132
|
-
|
133
|
-
parser = OperationParser(operation, should_parse=False)
|
134
|
-
parser._process_request_body()
|
135
|
-
assert len(parser.params) == 1
|
136
|
-
assert parser.params[0].original_name == 'array'
|
137
|
-
assert parser.params[0].param_location == 'body'
|
138
|
-
# Check that schema is correctly propagated and is a dictionary
|
139
|
-
assert parser.params[0].param_schema.type == 'array'
|
140
|
-
assert parser.params[0].param_schema.items.type == 'object'
|
141
|
-
assert 'item_prop1' in parser.params[0].param_schema.items.properties
|
142
|
-
assert 'item_prop2' in parser.params[0].param_schema.items.properties
|
143
|
-
assert (
|
144
|
-
parser.params[0].param_schema.items.properties['item_prop1'].description
|
145
|
-
== 'Item Property 1'
|
146
|
-
)
|
147
|
-
assert (
|
148
|
-
parser.params[0].param_schema.items.properties['item_prop2'].description
|
149
|
-
== 'Item Property 2'
|
150
|
-
)
|
151
|
-
|
152
|
-
|
153
|
-
def test_process_request_body_no_name():
|
154
|
-
"""Test _process_request_body with a schema that has no properties (unnamed)"""
|
155
|
-
operation = Operation(
|
156
|
-
requestBody=RequestBody(
|
157
|
-
content={'application/json': MediaType(schema=Schema(type='string'))}
|
158
|
-
)
|
159
|
-
)
|
160
|
-
parser = OperationParser(operation, should_parse=False)
|
161
|
-
parser._process_request_body()
|
162
|
-
assert len(parser.params) == 1
|
163
|
-
assert parser.params[0].original_name == '' # No name
|
164
|
-
assert parser.params[0].param_location == 'body'
|
165
|
-
|
166
|
-
|
167
|
-
def test_dedupe_param_names(sample_operation):
|
168
|
-
"""Test _dedupe_param_names method."""
|
169
|
-
parser = OperationParser(sample_operation, should_parse=False)
|
170
|
-
# Add duplicate named parameters.
|
171
|
-
parser.params = [
|
172
|
-
ApiParameter(original_name='test', param_location='', param_schema={}),
|
173
|
-
ApiParameter(original_name='test', param_location='', param_schema={}),
|
174
|
-
ApiParameter(original_name='test', param_location='', param_schema={}),
|
175
|
-
]
|
176
|
-
parser._dedupe_param_names()
|
177
|
-
assert parser.params[0].py_name == 'test'
|
178
|
-
assert parser.params[1].py_name == 'test_0'
|
179
|
-
assert parser.params[2].py_name == 'test_1'
|
180
|
-
|
181
|
-
|
182
|
-
def test_process_return_value(sample_operation):
|
183
|
-
"""Test _process_return_value method."""
|
184
|
-
parser = OperationParser(sample_operation, should_parse=False)
|
185
|
-
parser._process_return_value()
|
186
|
-
assert parser.return_value is not None
|
187
|
-
assert parser.return_value.type_hint == 'str'
|
188
|
-
|
189
|
-
|
190
|
-
def test_process_return_value_no_2xx(sample_operation):
|
191
|
-
"""Tests _process_return_value when no 2xx response exists."""
|
192
|
-
operation_no_2xx = Operation(
|
193
|
-
responses={'400': Response(description='Client Error')}
|
194
|
-
)
|
195
|
-
parser = OperationParser(operation_no_2xx, should_parse=False)
|
196
|
-
parser._process_return_value()
|
197
|
-
assert parser.return_value is not None
|
198
|
-
assert parser.return_value.type_hint == 'Any'
|
199
|
-
|
200
|
-
|
201
|
-
def test_process_return_value_multiple_2xx(sample_operation):
|
202
|
-
"""Tests _process_return_value when multiple 2xx responses exist."""
|
203
|
-
operation_multi_2xx = Operation(
|
204
|
-
responses={
|
205
|
-
'201': Response(
|
206
|
-
description='Success',
|
207
|
-
content={
|
208
|
-
'application/json': MediaType(schema=Schema(type='integer'))
|
209
|
-
},
|
210
|
-
),
|
211
|
-
'202': Response(
|
212
|
-
description='Success',
|
213
|
-
content={'text/plain': MediaType(schema=Schema(type='string'))},
|
214
|
-
),
|
215
|
-
'200': Response(
|
216
|
-
description='Success',
|
217
|
-
content={
|
218
|
-
'application/pdf': MediaType(schema=Schema(type='boolean'))
|
219
|
-
},
|
220
|
-
),
|
221
|
-
'400': Response(
|
222
|
-
description='Failure',
|
223
|
-
content={
|
224
|
-
'application/xml': MediaType(schema=Schema(type='object'))
|
225
|
-
},
|
226
|
-
),
|
227
|
-
}
|
228
|
-
)
|
229
|
-
|
230
|
-
parser = OperationParser(operation_multi_2xx, should_parse=False)
|
231
|
-
parser._process_return_value()
|
232
|
-
|
233
|
-
assert parser.return_value is not None
|
234
|
-
# Take the content type of the 200 response since it's the smallest response
|
235
|
-
# code
|
236
|
-
assert parser.return_value.param_schema.type == 'boolean'
|
237
|
-
|
238
|
-
|
239
|
-
def test_process_return_value_no_content(sample_operation):
|
240
|
-
"""Test when 2xx response has no content"""
|
241
|
-
operation_no_content = Operation(
|
242
|
-
responses={'200': Response(description='Success', content={})}
|
243
|
-
)
|
244
|
-
parser = OperationParser(operation_no_content, should_parse=False)
|
245
|
-
parser._process_return_value()
|
246
|
-
assert parser.return_value.type_hint == 'Any'
|
247
|
-
|
248
|
-
|
249
|
-
def test_process_return_value_no_schema(sample_operation):
|
250
|
-
"""Tests when the 2xx response's content has no schema."""
|
251
|
-
operation_no_schema = Operation(
|
252
|
-
responses={
|
253
|
-
'200': Response(
|
254
|
-
description='Success',
|
255
|
-
content={'application/json': MediaType(schema=None)},
|
256
|
-
)
|
257
|
-
}
|
258
|
-
)
|
259
|
-
parser = OperationParser(operation_no_schema, should_parse=False)
|
260
|
-
parser._process_return_value()
|
261
|
-
assert parser.return_value.type_hint == 'Any'
|
262
|
-
|
263
|
-
|
264
|
-
def test_get_function_name(sample_operation):
|
265
|
-
"""Test get_function_name method."""
|
266
|
-
parser = OperationParser(sample_operation)
|
267
|
-
assert parser.get_function_name() == 'test_operation'
|
268
|
-
|
269
|
-
|
270
|
-
def test_get_function_name_missing_id():
|
271
|
-
"""Tests get_function_name when operationId is missing"""
|
272
|
-
operation = Operation() # No ID
|
273
|
-
parser = OperationParser(operation)
|
274
|
-
with pytest.raises(ValueError, match='Operation ID is missing'):
|
275
|
-
parser.get_function_name()
|
276
|
-
|
277
|
-
|
278
|
-
def test_get_return_type_hint(sample_operation):
|
279
|
-
"""Test get_return_type_hint method."""
|
280
|
-
parser = OperationParser(sample_operation)
|
281
|
-
assert parser.get_return_type_hint() == 'str'
|
282
|
-
|
283
|
-
|
284
|
-
def test_get_return_type_value(sample_operation):
|
285
|
-
"""Test get_return_type_value method."""
|
286
|
-
parser = OperationParser(sample_operation)
|
287
|
-
assert parser.get_return_type_value() == str
|
288
|
-
|
289
|
-
|
290
|
-
def test_get_parameters(sample_operation):
|
291
|
-
"""Test get_parameters method."""
|
292
|
-
parser = OperationParser(sample_operation)
|
293
|
-
params = parser.get_parameters()
|
294
|
-
assert len(params) == 4 # Correct count after processing
|
295
|
-
assert all(isinstance(p, ApiParameter) for p in params)
|
296
|
-
|
297
|
-
|
298
|
-
def test_get_return_value(sample_operation):
|
299
|
-
"""Test get_return_value method."""
|
300
|
-
parser = OperationParser(sample_operation)
|
301
|
-
return_value = parser.get_return_value()
|
302
|
-
assert isinstance(return_value, ApiParameter)
|
303
|
-
|
304
|
-
|
305
|
-
def test_get_auth_scheme_name(sample_operation):
|
306
|
-
"""Test get_auth_scheme_name method."""
|
307
|
-
parser = OperationParser(sample_operation)
|
308
|
-
assert parser.get_auth_scheme_name() == 'oauth2'
|
309
|
-
|
310
|
-
|
311
|
-
def test_get_auth_scheme_name_no_security():
|
312
|
-
"""Test get_auth_scheme_name when no security is present."""
|
313
|
-
operation = Operation(responses={})
|
314
|
-
parser = OperationParser(operation)
|
315
|
-
assert parser.get_auth_scheme_name() == ''
|
316
|
-
|
317
|
-
|
318
|
-
def test_get_pydoc_string(sample_operation):
|
319
|
-
"""Test get_pydoc_string method."""
|
320
|
-
parser = OperationParser(sample_operation)
|
321
|
-
pydoc_string = parser.get_pydoc_string()
|
322
|
-
assert 'Test Summary' in pydoc_string
|
323
|
-
assert 'Args:' in pydoc_string
|
324
|
-
assert 'param1 (str): Parameter 1' in pydoc_string
|
325
|
-
assert 'prop1 (str): Property 1' in pydoc_string
|
326
|
-
assert 'Returns (str):' in pydoc_string
|
327
|
-
assert 'Success' in pydoc_string
|
328
|
-
|
329
|
-
|
330
|
-
def test_get_json_schema(sample_operation):
|
331
|
-
"""Test get_json_schema method."""
|
332
|
-
parser = OperationParser(sample_operation)
|
333
|
-
json_schema = parser.get_json_schema()
|
334
|
-
assert json_schema['title'] == 'test_operation_Arguments'
|
335
|
-
assert json_schema['type'] == 'object'
|
336
|
-
assert 'param1' in json_schema['properties']
|
337
|
-
assert 'prop1' in json_schema['properties']
|
338
|
-
assert 'param1' in json_schema['required']
|
339
|
-
assert 'prop1' in json_schema['required']
|
340
|
-
|
341
|
-
|
342
|
-
def test_get_signature_parameters(sample_operation):
|
343
|
-
"""Test get_signature_parameters method."""
|
344
|
-
parser = OperationParser(sample_operation)
|
345
|
-
signature_params = parser.get_signature_parameters()
|
346
|
-
assert len(signature_params) == 4
|
347
|
-
assert signature_params[0].name == 'param1'
|
348
|
-
assert signature_params[0].annotation == str
|
349
|
-
assert signature_params[2].name == 'prop1'
|
350
|
-
assert signature_params[2].annotation == str
|
351
|
-
|
352
|
-
|
353
|
-
def test_get_annotations(sample_operation):
|
354
|
-
"""Test get_annotations method."""
|
355
|
-
parser = OperationParser(sample_operation)
|
356
|
-
annotations = parser.get_annotations()
|
357
|
-
assert len(annotations) == 5 # 4 parameters + return
|
358
|
-
assert annotations['param1'] == str
|
359
|
-
assert annotations['prop1'] == str
|
360
|
-
assert annotations['return'] == str
|
361
|
-
|
362
|
-
|
363
|
-
def test_load():
|
364
|
-
"""Test the load classmethod."""
|
365
|
-
operation = Operation(operationId='my_op') # Minimal operation
|
366
|
-
params = [
|
367
|
-
ApiParameter(
|
368
|
-
original_name='p1',
|
369
|
-
param_location='',
|
370
|
-
param_schema={'type': 'integer'},
|
371
|
-
)
|
372
|
-
]
|
373
|
-
return_value = ApiParameter(
|
374
|
-
original_name='', param_location='', param_schema={'type': 'string'}
|
375
|
-
)
|
376
|
-
|
377
|
-
parser = OperationParser.load(operation, params, return_value)
|
378
|
-
|
379
|
-
assert isinstance(parser, OperationParser)
|
380
|
-
assert parser.operation == operation
|
381
|
-
assert parser.params == params
|
382
|
-
assert parser.return_value == return_value
|
383
|
-
assert (
|
384
|
-
parser.get_function_name() == 'my_op'
|
385
|
-
) # Check that the operation is loaded
|
386
|
-
|
387
|
-
|
388
|
-
def test_operation_parser_with_dict():
|
389
|
-
"""Test initialization of OperationParser with a dictionary."""
|
390
|
-
operation_dict = {
|
391
|
-
'operationId': 'test_dict_operation',
|
392
|
-
'parameters': [
|
393
|
-
{'name': 'dict_param', 'in': 'query', 'schema': {'type': 'string'}}
|
394
|
-
],
|
395
|
-
'responses': {
|
396
|
-
'200': {
|
397
|
-
'description': 'Dict Success',
|
398
|
-
'content': {'application/json': {'schema': {'type': 'string'}}},
|
399
|
-
}
|
400
|
-
},
|
401
|
-
}
|
402
|
-
parser = OperationParser(operation_dict)
|
403
|
-
assert parser.operation.operationId == 'test_dict_operation'
|
404
|
-
assert len(parser.params) == 1
|
405
|
-
assert parser.params[0].original_name == 'dict_param'
|
406
|
-
assert parser.return_value.type_hint == 'str'
|