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,145 +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
- """Unit tests for AutoAuthCredentialExchanger."""
16
-
17
- from typing import Dict
18
- from typing import Optional
19
- from typing import Type
20
- from unittest.mock import MagicMock
21
-
22
- from google.adk.auth.auth_credential import AuthCredential
23
- from google.adk.auth.auth_credential import AuthCredentialTypes
24
- from google.adk.auth.auth_schemes import AuthScheme
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers.auto_auth_credential_exchanger import AutoAuthCredentialExchanger
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
27
- from google.adk.tools.openapi_tool.auth.credential_exchangers.oauth2_exchanger import OAuth2CredentialExchanger
28
- from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
29
- import pytest
30
-
31
-
32
- class MockCredentialExchanger(BaseAuthCredentialExchanger):
33
- """Mock credential exchanger for testing."""
34
-
35
- def exchange_credential(
36
- self,
37
- auth_scheme: AuthScheme,
38
- auth_credential: Optional[AuthCredential] = None,
39
- ) -> AuthCredential:
40
- """Mock exchange credential method."""
41
- return auth_credential
42
-
43
-
44
- @pytest.fixture
45
- def auto_exchanger():
46
- """Fixture for creating an AutoAuthCredentialExchanger instance."""
47
- return AutoAuthCredentialExchanger()
48
-
49
-
50
- @pytest.fixture
51
- def auth_scheme():
52
- """Fixture for creating a mock AuthScheme instance."""
53
- scheme = MagicMock(spec=AuthScheme)
54
- return scheme
55
-
56
-
57
- def test_init_with_custom_exchangers():
58
- """Test initialization with custom exchangers."""
59
- custom_exchangers: Dict[str, Type[BaseAuthCredentialExchanger]] = {
60
- AuthCredentialTypes.API_KEY: MockCredentialExchanger
61
- }
62
-
63
- auto_exchanger = AutoAuthCredentialExchanger(
64
- custom_exchangers=custom_exchangers
65
- )
66
-
67
- assert (
68
- auto_exchanger.exchangers[AuthCredentialTypes.API_KEY]
69
- == MockCredentialExchanger
70
- )
71
- assert (
72
- auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT]
73
- == OAuth2CredentialExchanger
74
- )
75
-
76
-
77
- def test_exchange_credential_no_auth_credential(auto_exchanger, auth_scheme):
78
- """Test exchange_credential with no auth_credential."""
79
-
80
- assert auto_exchanger.exchange_credential(auth_scheme, None) is None
81
-
82
-
83
- def test_exchange_credential_no_exchange(auto_exchanger, auth_scheme):
84
- """Test exchange_credential with NoExchangeCredentialExchanger."""
85
- auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
86
-
87
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
88
-
89
- assert result == auth_credential
90
-
91
-
92
- def test_exchange_credential_open_id_connect(auto_exchanger, auth_scheme):
93
- """Test exchange_credential with OpenID Connect scheme."""
94
- auth_credential = AuthCredential(
95
- auth_type=AuthCredentialTypes.OPEN_ID_CONNECT
96
- )
97
- mock_exchanger = MagicMock(spec=OAuth2CredentialExchanger)
98
- mock_exchanger.exchange_credential.return_value = "exchanged_credential"
99
- auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT] = (
100
- lambda: mock_exchanger
101
- )
102
-
103
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
104
-
105
- assert result == "exchanged_credential"
106
- mock_exchanger.exchange_credential.assert_called_once_with(
107
- auth_scheme, auth_credential
108
- )
109
-
110
-
111
- def test_exchange_credential_service_account(auto_exchanger, auth_scheme):
112
- """Test exchange_credential with Service Account scheme."""
113
- auth_credential = AuthCredential(
114
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT
115
- )
116
- mock_exchanger = MagicMock(spec=ServiceAccountCredentialExchanger)
117
- mock_exchanger.exchange_credential.return_value = "exchanged_credential_sa"
118
- auto_exchanger.exchangers[AuthCredentialTypes.SERVICE_ACCOUNT] = (
119
- lambda: mock_exchanger
120
- )
121
-
122
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
123
-
124
- assert result == "exchanged_credential_sa"
125
- mock_exchanger.exchange_credential.assert_called_once_with(
126
- auth_scheme, auth_credential
127
- )
128
-
129
-
130
- def test_exchange_credential_custom_exchanger(auto_exchanger, auth_scheme):
131
- """Test that exchange_credential calls the correct (custom) exchanger."""
132
- # Use a custom exchanger via the initialization
133
- mock_exchanger = MagicMock(spec=MockCredentialExchanger)
134
- mock_exchanger.exchange_credential.return_value = "custom_credential"
135
- auto_exchanger.exchangers[AuthCredentialTypes.API_KEY] = (
136
- lambda: mock_exchanger
137
- )
138
- auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
139
-
140
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
141
-
142
- assert result == "custom_credential"
143
- mock_exchanger.exchange_credential.assert_called_once_with(
144
- auth_scheme, auth_credential
145
- )
@@ -1,68 +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
- """Tests for the BaseAuthCredentialExchanger class."""
16
-
17
- from typing import Optional
18
- from unittest.mock import MagicMock
19
-
20
- from google.adk.auth.auth_credential import AuthCredential
21
- from google.adk.auth.auth_credential import AuthCredentialTypes
22
- from google.adk.auth.auth_schemes import AuthScheme
23
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
24
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
25
- import pytest
26
-
27
-
28
- class MockAuthCredentialExchanger(BaseAuthCredentialExchanger):
29
-
30
- def exchange_credential(
31
- self,
32
- auth_scheme: AuthScheme,
33
- auth_credential: Optional[AuthCredential] = None,
34
- ) -> AuthCredential:
35
- return AuthCredential(token="some-token")
36
-
37
-
38
- class TestBaseAuthCredentialExchanger:
39
- """Tests for the BaseAuthCredentialExchanger class."""
40
-
41
- @pytest.fixture
42
- def base_exchanger(self):
43
- return BaseAuthCredentialExchanger()
44
-
45
- @pytest.fixture
46
- def auth_scheme(self):
47
- scheme = MagicMock(spec=AuthScheme)
48
- scheme.type = "apiKey"
49
- scheme.name = "x-api-key"
50
- return scheme
51
-
52
- def test_exchange_credential_not_implemented(
53
- self, base_exchanger, auth_scheme
54
- ):
55
- auth_credential = AuthCredential(
56
- auth_type=AuthCredentialTypes.API_KEY, token="some-token"
57
- )
58
- with pytest.raises(NotImplementedError) as exc_info:
59
- base_exchanger.exchange_credential(auth_scheme, auth_credential)
60
- assert "Subclasses must implement exchange_credential." in str(
61
- exc_info.value
62
- )
63
-
64
- def test_auth_credential_missing_error(self):
65
- error_message = "Test missing credential"
66
- error = AuthCredentialMissingError(error_message)
67
- # assert error.message == error_message
68
- assert str(error) == error_message
@@ -1,153 +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
- """Tests for OAuth2CredentialExchanger."""
16
-
17
- import copy
18
- from unittest.mock import MagicMock
19
-
20
- from google.adk.auth.auth_credential import AuthCredential
21
- from google.adk.auth.auth_credential import AuthCredentialTypes
22
- from google.adk.auth.auth_credential import OAuth2Auth
23
- from google.adk.auth.auth_schemes import AuthSchemeType
24
- from google.adk.auth.auth_schemes import OpenIdConnectWithConfig
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers import OAuth2CredentialExchanger
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
27
- import pytest
28
-
29
-
30
- @pytest.fixture
31
- def oauth2_exchanger():
32
- return OAuth2CredentialExchanger()
33
-
34
-
35
- @pytest.fixture
36
- def auth_scheme():
37
- openid_config = OpenIdConnectWithConfig(
38
- type_=AuthSchemeType.openIdConnect,
39
- authorization_endpoint="https://example.com/auth",
40
- token_endpoint="https://example.com/token",
41
- scopes=["openid", "profile"],
42
- )
43
- return openid_config
44
-
45
-
46
- def test_check_scheme_credential_type_success(oauth2_exchanger, auth_scheme):
47
- auth_credential = AuthCredential(
48
- auth_type=AuthCredentialTypes.OAUTH2,
49
- oauth2=OAuth2Auth(
50
- client_id="test_client",
51
- client_secret="test_secret",
52
- redirect_uri="http://localhost:8080",
53
- ),
54
- )
55
- # Check that the method does not raise an exception
56
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
57
-
58
-
59
- def test_check_scheme_credential_type_missing_credential(
60
- oauth2_exchanger, auth_scheme
61
- ):
62
- # Test case: auth_credential is None
63
- with pytest.raises(ValueError) as exc_info:
64
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, None)
65
- assert "auth_credential is empty" in str(exc_info.value)
66
-
67
-
68
- def test_check_scheme_credential_type_invalid_scheme_type(
69
- oauth2_exchanger, auth_scheme: OpenIdConnectWithConfig
70
- ):
71
- """Test case: Invalid AuthSchemeType."""
72
- # Test case: Invalid AuthSchemeType
73
- invalid_scheme = copy.deepcopy(auth_scheme)
74
- invalid_scheme.type_ = AuthSchemeType.apiKey
75
- auth_credential = AuthCredential(
76
- auth_type=AuthCredentialTypes.OAUTH2,
77
- oauth2=OAuth2Auth(
78
- client_id="test_client",
79
- client_secret="test_secret",
80
- redirect_uri="http://localhost:8080",
81
- ),
82
- )
83
- with pytest.raises(ValueError) as exc_info:
84
- oauth2_exchanger._check_scheme_credential_type(
85
- invalid_scheme, auth_credential
86
- )
87
- assert "Invalid security scheme" in str(exc_info.value)
88
-
89
-
90
- def test_check_scheme_credential_type_missing_openid_connect(
91
- oauth2_exchanger, auth_scheme
92
- ):
93
- auth_credential = AuthCredential(
94
- auth_type=AuthCredentialTypes.OAUTH2,
95
- )
96
- with pytest.raises(ValueError) as exc_info:
97
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
98
- assert "auth_credential is not configured with oauth2" in str(exc_info.value)
99
-
100
-
101
- def test_generate_auth_token_success(
102
- oauth2_exchanger, auth_scheme, monkeypatch
103
- ):
104
- """Test case: Successful generation of access token."""
105
- # Test case: Successful generation of access token
106
- auth_credential = AuthCredential(
107
- auth_type=AuthCredentialTypes.OAUTH2,
108
- oauth2=OAuth2Auth(
109
- client_id="test_client",
110
- client_secret="test_secret",
111
- redirect_uri="http://localhost:8080",
112
- auth_response_uri="https://example.com/callback?code=test_code",
113
- token={"access_token": "test_access_token"},
114
- ),
115
- )
116
- updated_credential = oauth2_exchanger.generate_auth_token(auth_credential)
117
-
118
- assert updated_credential.auth_type == AuthCredentialTypes.HTTP
119
- assert updated_credential.http.scheme == "bearer"
120
- assert updated_credential.http.credentials.token == "test_access_token"
121
-
122
-
123
- def test_exchange_credential_generate_auth_token(
124
- oauth2_exchanger, auth_scheme, monkeypatch
125
- ):
126
- """Test exchange_credential when auth_response_uri is present."""
127
- auth_credential = AuthCredential(
128
- auth_type=AuthCredentialTypes.OAUTH2,
129
- oauth2=OAuth2Auth(
130
- client_id="test_client",
131
- client_secret="test_secret",
132
- redirect_uri="http://localhost:8080",
133
- auth_response_uri="https://example.com/callback?code=test_code",
134
- token={"access_token": "test_access_token"},
135
- ),
136
- )
137
-
138
- updated_credential = oauth2_exchanger.exchange_credential(
139
- auth_scheme, auth_credential
140
- )
141
-
142
- assert updated_credential.auth_type == AuthCredentialTypes.HTTP
143
- assert updated_credential.http.scheme == "bearer"
144
- assert updated_credential.http.credentials.token == "test_access_token"
145
-
146
-
147
- def test_exchange_credential_auth_missing(oauth2_exchanger, auth_scheme):
148
- """Test exchange_credential when auth_credential is missing."""
149
- with pytest.raises(ValueError) as exc_info:
150
- oauth2_exchanger.exchange_credential(auth_scheme, None)
151
- assert "auth_credential is empty. Please create AuthCredential using" in str(
152
- exc_info.value
153
- )
@@ -1,196 +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
- """Unit tests for the service account credential exchanger."""
16
-
17
- from unittest.mock import MagicMock
18
-
19
- from google.adk.auth.auth_credential import AuthCredential
20
- from google.adk.auth.auth_credential import AuthCredentialTypes
21
- from google.adk.auth.auth_credential import ServiceAccount
22
- from google.adk.auth.auth_credential import ServiceAccountCredential
23
- from google.adk.auth.auth_schemes import AuthScheme
24
- from google.adk.auth.auth_schemes import AuthSchemeType
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
27
- import google.auth
28
- import pytest
29
-
30
-
31
- @pytest.fixture
32
- def service_account_exchanger():
33
- return ServiceAccountCredentialExchanger()
34
-
35
-
36
- @pytest.fixture
37
- def auth_scheme():
38
- scheme = MagicMock(spec=AuthScheme)
39
- scheme.type_ = AuthSchemeType.oauth2
40
- scheme.description = "Google Service Account"
41
- return scheme
42
-
43
-
44
- def test_exchange_credential_success(
45
- service_account_exchanger, auth_scheme, monkeypatch
46
- ):
47
- """Test successful exchange of service account credentials."""
48
- mock_credentials = MagicMock()
49
- mock_credentials.token = "mock_access_token"
50
-
51
- # Mock the from_service_account_info method
52
- mock_from_service_account_info = MagicMock(return_value=mock_credentials)
53
- target_path = (
54
- "google.adk.tools.openapi_tool.auth.credential_exchangers."
55
- "service_account_exchanger.service_account.Credentials."
56
- "from_service_account_info"
57
- )
58
- monkeypatch.setattr(
59
- target_path,
60
- mock_from_service_account_info,
61
- )
62
-
63
- # Mock the refresh method
64
- mock_credentials.refresh = MagicMock()
65
-
66
- # Create a valid AuthCredential with service account info
67
- auth_credential = AuthCredential(
68
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
69
- service_account=ServiceAccount(
70
- service_account_credential=ServiceAccountCredential(
71
- type_="service_account",
72
- project_id="your_project_id",
73
- private_key_id="your_private_key_id",
74
- private_key="-----BEGIN PRIVATE KEY-----...",
75
- client_email="...@....iam.gserviceaccount.com",
76
- client_id="your_client_id",
77
- auth_uri="https://accounts.google.com/o/oauth2/auth",
78
- token_uri="https://oauth2.googleapis.com/token",
79
- auth_provider_x509_cert_url=(
80
- "https://www.googleapis.com/oauth2/v1/certs"
81
- ),
82
- client_x509_cert_url=(
83
- "https://www.googleapis.com/robot/v1/metadata/x509/..."
84
- ),
85
- universe_domain="googleapis.com",
86
- ),
87
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
88
- ),
89
- )
90
-
91
- result = service_account_exchanger.exchange_credential(
92
- auth_scheme, auth_credential
93
- )
94
-
95
- assert result.auth_type == AuthCredentialTypes.HTTP
96
- assert result.http.scheme == "bearer"
97
- assert result.http.credentials.token == "mock_access_token"
98
- mock_from_service_account_info.assert_called_once()
99
- mock_credentials.refresh.assert_called_once()
100
-
101
-
102
- def test_exchange_credential_use_default_credential_success(
103
- service_account_exchanger, auth_scheme, monkeypatch
104
- ):
105
- """Test successful exchange of service account credentials using default credential."""
106
- mock_credentials = MagicMock()
107
- mock_credentials.token = "mock_access_token"
108
- mock_google_auth_default = MagicMock(
109
- return_value=(mock_credentials, "test_project")
110
- )
111
- monkeypatch.setattr(google.auth, "default", mock_google_auth_default)
112
-
113
- auth_credential = AuthCredential(
114
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
115
- service_account=ServiceAccount(
116
- use_default_credential=True,
117
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
118
- ),
119
- )
120
-
121
- result = service_account_exchanger.exchange_credential(
122
- auth_scheme, auth_credential
123
- )
124
-
125
- assert result.auth_type == AuthCredentialTypes.HTTP
126
- assert result.http.scheme == "bearer"
127
- assert result.http.credentials.token == "mock_access_token"
128
- mock_google_auth_default.assert_called_once()
129
- mock_credentials.refresh.assert_called_once()
130
-
131
-
132
- def test_exchange_credential_missing_auth_credential(
133
- service_account_exchanger, auth_scheme
134
- ):
135
- """Test missing auth credential during exchange."""
136
- with pytest.raises(AuthCredentialMissingError) as exc_info:
137
- service_account_exchanger.exchange_credential(auth_scheme, None)
138
- assert "Service account credentials are missing" in str(exc_info.value)
139
-
140
-
141
- def test_exchange_credential_missing_service_account_info(
142
- service_account_exchanger, auth_scheme
143
- ):
144
- """Test missing service account info during exchange."""
145
- auth_credential = AuthCredential(
146
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
147
- )
148
- with pytest.raises(AuthCredentialMissingError) as exc_info:
149
- service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
150
- assert "Service account credentials are missing" in str(exc_info.value)
151
-
152
-
153
- def test_exchange_credential_exchange_failure(
154
- service_account_exchanger, auth_scheme, monkeypatch
155
- ):
156
- """Test failure during service account token exchange."""
157
- mock_from_service_account_info = MagicMock(
158
- side_effect=Exception("Failed to load credentials")
159
- )
160
- target_path = (
161
- "google.adk.tools.openapi_tool.auth.credential_exchangers."
162
- "service_account_exchanger.service_account.Credentials."
163
- "from_service_account_info"
164
- )
165
- monkeypatch.setattr(
166
- target_path,
167
- mock_from_service_account_info,
168
- )
169
-
170
- auth_credential = AuthCredential(
171
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
172
- service_account=ServiceAccount(
173
- service_account_credential=ServiceAccountCredential(
174
- type_="service_account",
175
- project_id="your_project_id",
176
- private_key_id="your_private_key_id",
177
- private_key="-----BEGIN PRIVATE KEY-----...",
178
- client_email="...@....iam.gserviceaccount.com",
179
- client_id="your_client_id",
180
- auth_uri="https://accounts.google.com/o/oauth2/auth",
181
- token_uri="https://oauth2.googleapis.com/token",
182
- auth_provider_x509_cert_url=(
183
- "https://www.googleapis.com/oauth2/v1/certs"
184
- ),
185
- client_x509_cert_url=(
186
- "https://www.googleapis.com/robot/v1/metadata/x509/..."
187
- ),
188
- universe_domain="googleapis.com",
189
- ),
190
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
191
- ),
192
- )
193
- with pytest.raises(AuthCredentialMissingError) as exc_info:
194
- service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
195
- assert "Failed to exchange service account token" in str(exc_info.value)
196
- mock_from_service_account_info.assert_called_once()