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