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.
Files changed (153) hide show
  1. google/adk/agents/run_config.py +4 -0
  2. google/adk/auth/auth_preprocessor.py +19 -16
  3. google/adk/cli/agent_graph.py +31 -5
  4. google/adk/cli/browser/index.html +1 -1
  5. google/adk/cli/browser/{main-XUU6OGCC.js → main-CU22TRPI.js} +30 -30
  6. google/adk/cli/cli.py +8 -8
  7. google/adk/cli/cli_deploy.py +2 -4
  8. google/adk/cli/cli_tools_click.py +57 -12
  9. google/adk/cli/fast_api.py +19 -9
  10. google/adk/flows/llm_flows/contents.py +21 -1
  11. google/adk/flows/llm_flows/functions.py +3 -1
  12. google/adk/models/google_llm.py +0 -1
  13. google/adk/runners.py +13 -2
  14. google/adk/version.py +1 -1
  15. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/METADATA +4 -2
  16. google_adk-0.0.4.dist-info/RECORD +175 -0
  17. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/WHEEL +1 -1
  18. google/adk/cli/media_streamer/__init__.py +0 -19
  19. google/adk/cli/media_streamer/index.html +0 -228
  20. google/adk/tests/__init__.py +0 -14
  21. google/adk/tests/integration/.env.example +0 -10
  22. google/adk/tests/integration/__init__.py +0 -18
  23. google/adk/tests/integration/conftest.py +0 -119
  24. google/adk/tests/integration/fixture/__init__.py +0 -14
  25. google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
  26. google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
  27. google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
  28. google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
  29. google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
  30. google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
  31. google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
  32. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
  33. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
  34. google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
  35. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
  36. google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
  37. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
  38. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
  39. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
  40. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
  41. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
  42. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
  43. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +0 -243
  44. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
  45. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
  46. google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
  47. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
  48. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
  49. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
  50. google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
  51. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
  52. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
  53. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
  54. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
  55. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
  56. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
  57. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
  58. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
  59. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
  60. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
  61. google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
  62. google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
  63. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  64. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
  65. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
  66. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
  67. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
  68. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
  69. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
  70. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
  71. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
  72. google/adk/tests/integration/models/__init__.py +0 -14
  73. google/adk/tests/integration/models/test_google_llm.py +0 -65
  74. google/adk/tests/integration/test_callback.py +0 -70
  75. google/adk/tests/integration/test_context_variable.py +0 -67
  76. google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
  77. google/adk/tests/integration/test_multi_agent.py +0 -28
  78. google/adk/tests/integration/test_multi_turn.py +0 -42
  79. google/adk/tests/integration/test_single_agent.py +0 -23
  80. google/adk/tests/integration/test_sub_agent.py +0 -26
  81. google/adk/tests/integration/test_system_instruction.py +0 -177
  82. google/adk/tests/integration/test_tools.py +0 -287
  83. google/adk/tests/integration/test_with_test_file.py +0 -34
  84. google/adk/tests/integration/tools/__init__.py +0 -14
  85. google/adk/tests/integration/utils/__init__.py +0 -16
  86. google/adk/tests/integration/utils/asserts.py +0 -75
  87. google/adk/tests/integration/utils/test_runner.py +0 -97
  88. google/adk/tests/unittests/__init__.py +0 -14
  89. google/adk/tests/unittests/agents/__init__.py +0 -14
  90. google/adk/tests/unittests/agents/test_base_agent.py +0 -407
  91. google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
  92. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
  93. google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
  94. google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
  95. google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
  96. google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
  97. google/adk/tests/unittests/artifacts/__init__.py +0 -14
  98. google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
  99. google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
  100. google/adk/tests/unittests/conftest.py +0 -73
  101. google/adk/tests/unittests/fast_api/__init__.py +0 -14
  102. google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
  103. google/adk/tests/unittests/flows/__init__.py +0 -14
  104. google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
  105. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
  106. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
  107. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
  108. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
  109. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
  110. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
  111. google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
  112. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
  113. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
  114. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
  115. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
  116. google/adk/tests/unittests/models/__init__.py +0 -14
  117. google/adk/tests/unittests/models/test_google_llm.py +0 -224
  118. google/adk/tests/unittests/models/test_litellm.py +0 -804
  119. google/adk/tests/unittests/models/test_models.py +0 -60
  120. google/adk/tests/unittests/sessions/__init__.py +0 -14
  121. google/adk/tests/unittests/sessions/test_session_service.py +0 -227
  122. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
  123. google/adk/tests/unittests/streaming/__init__.py +0 -14
  124. google/adk/tests/unittests/streaming/test_streaming.py +0 -50
  125. google/adk/tests/unittests/tools/__init__.py +0 -14
  126. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
  127. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
  128. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
  129. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
  130. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
  131. google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
  132. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
  133. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
  134. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
  135. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
  136. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
  137. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
  138. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
  139. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
  140. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
  141. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
  142. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
  143. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
  144. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
  145. google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
  146. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
  147. google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
  148. google/adk/tests/unittests/tools/test_base_tool.py +0 -141
  149. google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
  150. google/adk/tests/unittests/utils.py +0 -304
  151. google_adk-0.0.2.dist-info/RECORD +0 -308
  152. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/entry_points.txt +0 -0
  153. {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'