google-adk 0.0.1__py3-none-any.whl → 0.0.3__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 (345) hide show
  1. google/adk/._version.py +0 -0
  2. google/adk/__init__.py +20 -0
  3. google/adk/agents/__init__.py +32 -0
  4. google/adk/agents/active_streaming_tool.py +38 -0
  5. google/adk/agents/base_agent.py +345 -0
  6. google/adk/agents/callback_context.py +112 -0
  7. google/adk/agents/invocation_context.py +181 -0
  8. google/adk/agents/langgraph_agent.py +140 -0
  9. google/adk/agents/live_request_queue.py +64 -0
  10. google/adk/agents/llm_agent.py +376 -0
  11. google/adk/agents/loop_agent.py +62 -0
  12. google/adk/agents/parallel_agent.py +96 -0
  13. google/adk/agents/readonly_context.py +46 -0
  14. google/adk/agents/remote_agent.py +50 -0
  15. google/adk/agents/run_config.py +87 -0
  16. google/adk/agents/sequential_agent.py +45 -0
  17. google/adk/agents/transcription_entry.py +34 -0
  18. google/adk/artifacts/__init__.py +23 -0
  19. google/adk/artifacts/base_artifact_service.py +128 -0
  20. google/adk/artifacts/gcs_artifact_service.py +195 -0
  21. google/adk/artifacts/in_memory_artifact_service.py +133 -0
  22. google/adk/auth/__init__.py +22 -0
  23. google/adk/auth/auth_credential.py +220 -0
  24. google/adk/auth/auth_handler.py +268 -0
  25. google/adk/auth/auth_preprocessor.py +116 -0
  26. google/adk/auth/auth_schemes.py +67 -0
  27. google/adk/auth/auth_tool.py +55 -0
  28. google/adk/cli/__init__.py +15 -0
  29. google/adk/cli/__main__.py +18 -0
  30. google/adk/cli/agent_graph.py +148 -0
  31. google/adk/cli/browser/adk_favicon.svg +17 -0
  32. google/adk/cli/browser/assets/audio-processor.js +51 -0
  33. google/adk/cli/browser/assets/config/runtime-config.json +3 -0
  34. google/adk/cli/browser/index.html +33 -0
  35. google/adk/cli/browser/main-SY2WYYGV.js +75 -0
  36. google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
  37. google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
  38. google/adk/cli/cli.py +181 -0
  39. google/adk/cli/cli_deploy.py +181 -0
  40. google/adk/cli/cli_eval.py +282 -0
  41. google/adk/cli/cli_tools_click.py +524 -0
  42. google/adk/cli/fast_api.py +784 -0
  43. google/adk/cli/utils/__init__.py +49 -0
  44. google/adk/cli/utils/envs.py +57 -0
  45. google/adk/cli/utils/evals.py +93 -0
  46. google/adk/cli/utils/logs.py +72 -0
  47. google/adk/code_executors/__init__.py +49 -0
  48. google/adk/code_executors/base_code_executor.py +97 -0
  49. google/adk/code_executors/code_execution_utils.py +256 -0
  50. google/adk/code_executors/code_executor_context.py +202 -0
  51. google/adk/code_executors/container_code_executor.py +196 -0
  52. google/adk/code_executors/unsafe_local_code_executor.py +71 -0
  53. google/adk/code_executors/vertex_ai_code_executor.py +234 -0
  54. google/adk/docs/Makefile +20 -0
  55. google/adk/docs/build/doctrees/google-adk.doctree +0 -0
  56. google/adk/docs/build/html/_sources/google-adk.rst.txt +98 -0
  57. google/adk/docs/build/html/_sources/index.rst.txt +7 -0
  58. google/adk/docs/build/html/_static/autodoc_pydantic.css +27 -0
  59. google/adk/docs/build/html/_static/basic.css +925 -0
  60. google/adk/docs/build/html/_static/debug.css +85 -0
  61. google/adk/docs/build/html/_static/doctools.js +156 -0
  62. google/adk/docs/build/html/_static/documentation_options.js +29 -0
  63. google/adk/docs/build/html/_static/file.png +0 -0
  64. google/adk/docs/build/html/_static/language_data.js +199 -0
  65. google/adk/docs/build/html/_static/minus.png +0 -0
  66. google/adk/docs/build/html/_static/plus.png +0 -0
  67. google/adk/docs/build/html/_static/pygments.css +274 -0
  68. google/adk/docs/build/html/_static/scripts/furo-extensions.js +16 -0
  69. google/adk/docs/build/html/_static/scripts/furo.js +19 -0
  70. google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +7 -0
  71. google/adk/docs/build/html/_static/scripts/furo.js.map +1 -0
  72. google/adk/docs/build/html/_static/searchtools.js +620 -0
  73. google/adk/docs/build/html/_static/skeleton.css +312 -0
  74. google/adk/docs/build/html/_static/sphinx_highlight.js +170 -0
  75. google/adk/docs/build/html/_static/styles/furo-extensions.css +18 -0
  76. google/adk/docs/build/html/_static/styles/furo-extensions.css.map +1 -0
  77. google/adk/docs/build/html/_static/styles/furo.css +18 -0
  78. google/adk/docs/build/html/_static/styles/furo.css.map +1 -0
  79. google/adk/docs/build/html/genindex.html +861 -0
  80. google/adk/docs/build/html/google-adk.html +5461 -0
  81. google/adk/docs/build/html/index.html +567 -0
  82. google/adk/docs/build/html/objects.inv +0 -0
  83. google/adk/docs/build/html/py-modindex.html +373 -0
  84. google/adk/docs/build/html/search.html +333 -0
  85. google/adk/docs/build/html/searchindex.js +17 -0
  86. google/adk/docs/source/conf.py +133 -0
  87. google/adk/docs/source/google-adk.rst +98 -0
  88. google/adk/docs/source/index.rst +7 -0
  89. google/adk/evaluation/__init__.py +31 -0
  90. google/adk/evaluation/agent_evaluator.py +329 -0
  91. google/adk/evaluation/evaluation_constants.py +24 -0
  92. google/adk/evaluation/evaluation_generator.py +270 -0
  93. google/adk/evaluation/response_evaluator.py +135 -0
  94. google/adk/evaluation/trajectory_evaluator.py +184 -0
  95. google/adk/events/__init__.py +21 -0
  96. google/adk/events/event.py +130 -0
  97. google/adk/events/event_actions.py +55 -0
  98. google/adk/examples/__init__.py +28 -0
  99. google/adk/examples/base_example_provider.py +35 -0
  100. google/adk/examples/example.py +27 -0
  101. google/adk/examples/example_util.py +123 -0
  102. google/adk/examples/vertex_ai_example_store.py +104 -0
  103. google/adk/flows/__init__.py +14 -0
  104. google/adk/flows/llm_flows/__init__.py +20 -0
  105. google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
  106. google/adk/flows/llm_flows/_code_execution.py +458 -0
  107. google/adk/flows/llm_flows/_nl_planning.py +129 -0
  108. google/adk/flows/llm_flows/agent_transfer.py +132 -0
  109. google/adk/flows/llm_flows/audio_transcriber.py +109 -0
  110. google/adk/flows/llm_flows/auto_flow.py +49 -0
  111. google/adk/flows/llm_flows/base_llm_flow.py +559 -0
  112. google/adk/flows/llm_flows/basic.py +72 -0
  113. google/adk/flows/llm_flows/contents.py +370 -0
  114. google/adk/flows/llm_flows/functions.py +486 -0
  115. google/adk/flows/llm_flows/identity.py +47 -0
  116. google/adk/flows/llm_flows/instructions.py +137 -0
  117. google/adk/flows/llm_flows/single_flow.py +57 -0
  118. google/adk/memory/__init__.py +35 -0
  119. google/adk/memory/base_memory_service.py +74 -0
  120. google/adk/memory/in_memory_memory_service.py +62 -0
  121. google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
  122. google/adk/models/__init__.py +31 -0
  123. google/adk/models/anthropic_llm.py +243 -0
  124. google/adk/models/base_llm.py +87 -0
  125. google/adk/models/base_llm_connection.py +76 -0
  126. google/adk/models/gemini_llm_connection.py +200 -0
  127. google/adk/models/google_llm.py +331 -0
  128. google/adk/models/lite_llm.py +673 -0
  129. google/adk/models/llm_request.py +98 -0
  130. google/adk/models/llm_response.py +111 -0
  131. google/adk/models/registry.py +102 -0
  132. google/adk/planners/__init__.py +23 -0
  133. google/adk/planners/base_planner.py +66 -0
  134. google/adk/planners/built_in_planner.py +75 -0
  135. google/adk/planners/plan_re_act_planner.py +208 -0
  136. google/adk/runners.py +456 -0
  137. google/adk/sessions/__init__.py +41 -0
  138. google/adk/sessions/base_session_service.py +133 -0
  139. google/adk/sessions/database_session_service.py +522 -0
  140. google/adk/sessions/in_memory_session_service.py +206 -0
  141. google/adk/sessions/session.py +54 -0
  142. google/adk/sessions/state.py +71 -0
  143. google/adk/sessions/vertex_ai_session_service.py +356 -0
  144. google/adk/telemetry.py +189 -0
  145. google/adk/tests/__init__.py +14 -0
  146. google/adk/tests/integration/.env.example +10 -0
  147. google/adk/tests/integration/__init__.py +18 -0
  148. google/adk/tests/integration/conftest.py +119 -0
  149. google/adk/tests/integration/fixture/__init__.py +14 -0
  150. google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
  151. google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
  152. google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
  153. google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
  154. google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
  155. google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
  156. google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
  157. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
  158. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
  159. google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
  160. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
  161. google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
  162. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
  163. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
  164. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
  165. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
  166. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
  167. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
  168. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
  169. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
  170. google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
  171. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
  172. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
  173. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
  174. google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
  175. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
  176. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
  177. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
  178. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
  179. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
  180. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
  181. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
  182. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
  183. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
  184. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
  185. google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
  186. google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
  187. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  188. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
  189. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
  190. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
  191. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
  192. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
  193. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
  194. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
  195. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
  196. google/adk/tests/integration/models/__init__.py +14 -0
  197. google/adk/tests/integration/models/test_google_llm.py +65 -0
  198. google/adk/tests/integration/test_callback.py +70 -0
  199. google/adk/tests/integration/test_context_variable.py +67 -0
  200. google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
  201. google/adk/tests/integration/test_multi_agent.py +28 -0
  202. google/adk/tests/integration/test_multi_turn.py +42 -0
  203. google/adk/tests/integration/test_single_agent.py +23 -0
  204. google/adk/tests/integration/test_sub_agent.py +26 -0
  205. google/adk/tests/integration/test_system_instruction.py +177 -0
  206. google/adk/tests/integration/test_tools.py +287 -0
  207. google/adk/tests/integration/test_with_test_file.py +34 -0
  208. google/adk/tests/integration/tools/__init__.py +14 -0
  209. google/adk/tests/integration/utils/__init__.py +16 -0
  210. google/adk/tests/integration/utils/asserts.py +75 -0
  211. google/adk/tests/integration/utils/test_runner.py +97 -0
  212. google/adk/tests/unittests/__init__.py +14 -0
  213. google/adk/tests/unittests/agents/__init__.py +14 -0
  214. google/adk/tests/unittests/agents/test_base_agent.py +407 -0
  215. google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
  216. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
  217. google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
  218. google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
  219. google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
  220. google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
  221. google/adk/tests/unittests/artifacts/__init__.py +14 -0
  222. google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
  223. google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
  224. google/adk/tests/unittests/conftest.py +73 -0
  225. google/adk/tests/unittests/fast_api/__init__.py +14 -0
  226. google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
  227. google/adk/tests/unittests/flows/__init__.py +14 -0
  228. google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
  229. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
  230. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
  231. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
  232. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
  233. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
  234. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
  235. google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
  236. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
  237. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
  238. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
  239. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
  240. google/adk/tests/unittests/models/__init__.py +14 -0
  241. google/adk/tests/unittests/models/test_google_llm.py +224 -0
  242. google/adk/tests/unittests/models/test_litellm.py +804 -0
  243. google/adk/tests/unittests/models/test_models.py +60 -0
  244. google/adk/tests/unittests/sessions/__init__.py +14 -0
  245. google/adk/tests/unittests/sessions/test_session_service.py +227 -0
  246. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
  247. google/adk/tests/unittests/streaming/__init__.py +14 -0
  248. google/adk/tests/unittests/streaming/test_streaming.py +50 -0
  249. google/adk/tests/unittests/tools/__init__.py +14 -0
  250. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
  251. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
  252. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
  253. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
  254. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
  255. google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
  256. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
  257. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
  258. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
  259. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
  260. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
  261. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
  262. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
  263. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
  264. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
  265. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
  266. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
  267. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
  268. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
  269. google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
  270. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
  271. google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
  272. google/adk/tests/unittests/tools/test_base_tool.py +141 -0
  273. google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
  274. google/adk/tests/unittests/utils.py +304 -0
  275. google/adk/tools/__init__.py +51 -0
  276. google/adk/tools/_automatic_function_calling_util.py +346 -0
  277. google/adk/tools/agent_tool.py +176 -0
  278. google/adk/tools/apihub_tool/__init__.py +19 -0
  279. google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
  280. google/adk/tools/apihub_tool/clients/__init__.py +13 -0
  281. google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
  282. google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
  283. google/adk/tools/application_integration_tool/__init__.py +19 -0
  284. google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
  285. google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
  286. google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
  287. google/adk/tools/base_tool.py +144 -0
  288. google/adk/tools/built_in_code_execution_tool.py +59 -0
  289. google/adk/tools/crewai_tool.py +72 -0
  290. google/adk/tools/example_tool.py +62 -0
  291. google/adk/tools/exit_loop_tool.py +23 -0
  292. google/adk/tools/function_parameter_parse_util.py +307 -0
  293. google/adk/tools/function_tool.py +87 -0
  294. google/adk/tools/get_user_choice_tool.py +28 -0
  295. google/adk/tools/google_api_tool/__init__.py +14 -0
  296. google/adk/tools/google_api_tool/google_api_tool.py +59 -0
  297. google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
  298. google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
  299. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
  300. google/adk/tools/google_search_tool.py +68 -0
  301. google/adk/tools/langchain_tool.py +86 -0
  302. google/adk/tools/load_artifacts_tool.py +113 -0
  303. google/adk/tools/load_memory_tool.py +58 -0
  304. google/adk/tools/load_web_page.py +41 -0
  305. google/adk/tools/long_running_tool.py +39 -0
  306. google/adk/tools/mcp_tool/__init__.py +42 -0
  307. google/adk/tools/mcp_tool/conversion_utils.py +161 -0
  308. google/adk/tools/mcp_tool/mcp_tool.py +113 -0
  309. google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
  310. google/adk/tools/openapi_tool/__init__.py +21 -0
  311. google/adk/tools/openapi_tool/auth/__init__.py +19 -0
  312. google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
  313. google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
  314. google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
  315. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
  316. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
  317. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
  318. google/adk/tools/openapi_tool/common/__init__.py +19 -0
  319. google/adk/tools/openapi_tool/common/common.py +300 -0
  320. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
  321. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
  322. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
  323. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
  324. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
  325. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
  326. google/adk/tools/preload_memory_tool.py +72 -0
  327. google/adk/tools/retrieval/__init__.py +36 -0
  328. google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
  329. google/adk/tools/retrieval/files_retrieval.py +33 -0
  330. google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
  331. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
  332. google/adk/tools/tool_context.py +90 -0
  333. google/adk/tools/toolbox_tool.py +46 -0
  334. google/adk/tools/transfer_to_agent_tool.py +21 -0
  335. google/adk/tools/vertex_ai_search_tool.py +96 -0
  336. google/adk/version.py +16 -0
  337. google_adk-0.0.3.dist-info/METADATA +73 -0
  338. google_adk-0.0.3.dist-info/RECORD +340 -0
  339. {google_adk-0.0.1.dist-info → google_adk-0.0.3.dist-info}/WHEEL +1 -2
  340. google_adk-0.0.3.dist-info/entry_points.txt +3 -0
  341. agent_kit/__init__.py +0 -0
  342. google_adk-0.0.1.dist-info/LICENSE.txt +0 -170
  343. google_adk-0.0.1.dist-info/METADATA +0 -15
  344. google_adk-0.0.1.dist-info/RECORD +0 -6
  345. google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,498 @@
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 typing import Any
16
+ from typing import Dict
17
+ from typing import List
18
+ from typing import Literal
19
+ from typing import Optional
20
+ from typing import Tuple
21
+
22
+ from fastapi.openapi.models import APIKey
23
+ from fastapi.openapi.models import APIKeyIn
24
+ from fastapi.openapi.models import HTTPBase
25
+ from fastapi.openapi.models import HTTPBearer
26
+ from fastapi.openapi.models import OAuth2
27
+ from fastapi.openapi.models import OpenIdConnect
28
+ from fastapi.openapi.models import Schema
29
+ from pydantic import BaseModel
30
+ from pydantic import ValidationError
31
+ import requests
32
+
33
+ from ....auth.auth_credential import AuthCredential
34
+ from ....auth.auth_credential import AuthCredentialTypes
35
+ from ....auth.auth_credential import HttpAuth
36
+ from ....auth.auth_credential import HttpCredentials
37
+ from ....auth.auth_credential import OAuth2Auth
38
+ from ....auth.auth_credential import ServiceAccount
39
+ from ....auth.auth_credential import ServiceAccountCredential
40
+ from ....auth.auth_schemes import AuthScheme
41
+ from ....auth.auth_schemes import AuthSchemeType
42
+ from ....auth.auth_schemes import OpenIdConnectWithConfig
43
+ from ..common.common import ApiParameter
44
+
45
+
46
+ class OpenIdConfig(BaseModel):
47
+ """Represents OpenID Connect configuration.
48
+
49
+ Attributes:
50
+ client_id: The client ID.
51
+ auth_uri: The authorization URI.
52
+ token_uri: The token URI.
53
+ client_secret: The client secret.
54
+
55
+ Example:
56
+ config = OpenIdConfig(
57
+ client_id="your_client_id",
58
+ auth_uri="https://accounts.google.com/o/oauth2/auth",
59
+ token_uri="https://oauth2.googleapis.com/token",
60
+ client_secret="your_client_secret",
61
+ redirect
62
+ )
63
+ """
64
+
65
+ client_id: str
66
+ auth_uri: str
67
+ token_uri: str
68
+ client_secret: str
69
+ redirect_uri: Optional[str]
70
+
71
+
72
+ def token_to_scheme_credential(
73
+ token_type: Literal["apikey", "oauth2Token"],
74
+ location: Optional[Literal["header", "query", "cookie"]] = None,
75
+ name: Optional[str] = None,
76
+ credential_value: Optional[str] = None,
77
+ ) -> Tuple[AuthScheme, AuthCredential]:
78
+ """Creates a AuthScheme and AuthCredential for API key or bearer token.
79
+
80
+ Examples:
81
+ ```
82
+ # API Key in header
83
+ auth_scheme, auth_credential = token_to_scheme_credential("apikey", "header",
84
+ "X-API-Key", "your_api_key_value")
85
+
86
+ # API Key in query parameter
87
+ auth_scheme, auth_credential = token_to_scheme_credential("apikey", "query",
88
+ "api_key", "your_api_key_value")
89
+
90
+ # OAuth2 Bearer Token in Authorization header
91
+ auth_scheme, auth_credential = token_to_scheme_credential("oauth2Token",
92
+ "header", "Authorization", "your_bearer_token_value")
93
+ ```
94
+
95
+ Args:
96
+ type: 'apikey' or 'oauth2Token'.
97
+ location: 'header', 'query', or 'cookie' (only 'header' for oauth2Token).
98
+ name: The name of the header, query parameter, or cookie.
99
+ credential_value: The value of the API Key/ Token.
100
+
101
+ Returns:
102
+ Tuple: (AuthScheme, AuthCredential)
103
+
104
+ Raises:
105
+ ValueError: For invalid type or location.
106
+ """
107
+ if token_type == "apikey":
108
+ in_: APIKeyIn
109
+ if location == "header":
110
+ in_ = APIKeyIn.header
111
+ elif location == "query":
112
+ in_ = APIKeyIn.query
113
+ elif location == "cookie":
114
+ in_ = APIKeyIn.cookie
115
+ else:
116
+ raise ValueError(f"Invalid location for apiKey: {location}")
117
+ auth_scheme = APIKey(**{
118
+ "type": AuthSchemeType.apiKey,
119
+ "in": in_,
120
+ "name": name,
121
+ })
122
+ if credential_value:
123
+ auth_credential = AuthCredential(
124
+ auth_type=AuthCredentialTypes.API_KEY, api_key=credential_value
125
+ )
126
+ else:
127
+ auth_credential = None
128
+
129
+ return auth_scheme, auth_credential
130
+
131
+ elif token_type == "oauth2Token":
132
+ # ignore location. OAuth2 Bearer Token is always in Authorization header.
133
+ auth_scheme = HTTPBearer(
134
+ bearerFormat="JWT"
135
+ ) # Common format, can be omitted.
136
+ if credential_value:
137
+ auth_credential = AuthCredential(
138
+ auth_type=AuthCredentialTypes.HTTP,
139
+ http=HttpAuth(
140
+ scheme="bearer",
141
+ credentials=HttpCredentials(token=credential_value),
142
+ ),
143
+ )
144
+ else:
145
+ auth_credential = None
146
+
147
+ return auth_scheme, auth_credential
148
+
149
+ else:
150
+ raise ValueError(f"Invalid security scheme type: {type}")
151
+
152
+
153
+ def service_account_dict_to_scheme_credential(
154
+ config: Dict[str, Any],
155
+ scopes: List[str],
156
+ ) -> Tuple[AuthScheme, AuthCredential]:
157
+ """Creates AuthScheme and AuthCredential for Google Service Account.
158
+
159
+ Returns a bearer token scheme, and a service account credential.
160
+
161
+ Args:
162
+ config: A ServiceAccount object containing the Google Service Account
163
+ configuration.
164
+ scopes: A list of scopes to be used.
165
+
166
+ Returns:
167
+ Tuple: (AuthScheme, AuthCredential)
168
+ """
169
+ auth_scheme = HTTPBearer(bearerFormat="JWT")
170
+ service_account = ServiceAccount(
171
+ service_account_credential=ServiceAccountCredential.model_construct(
172
+ **config
173
+ ),
174
+ scopes=scopes,
175
+ )
176
+ auth_credential = AuthCredential(
177
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
178
+ service_account=service_account,
179
+ )
180
+ return auth_scheme, auth_credential
181
+
182
+
183
+ def service_account_scheme_credential(
184
+ config: ServiceAccount,
185
+ ) -> Tuple[AuthScheme, AuthCredential]:
186
+ """Creates AuthScheme and AuthCredential for Google Service Account.
187
+
188
+ Returns a bearer token scheme, and a service account credential.
189
+
190
+ Args:
191
+ config: A ServiceAccount object containing the Google Service Account
192
+ configuration.
193
+
194
+ Returns:
195
+ Tuple: (AuthScheme, AuthCredential)
196
+ """
197
+ auth_scheme = HTTPBearer(bearerFormat="JWT")
198
+ auth_credential = AuthCredential(
199
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT, service_account=config
200
+ )
201
+ return auth_scheme, auth_credential
202
+
203
+
204
+ def openid_dict_to_scheme_credential(
205
+ config_dict: Dict[str, Any],
206
+ scopes: List[str],
207
+ credential_dict: Dict[str, Any],
208
+ ) -> Tuple[OpenIdConnectWithConfig, AuthCredential]:
209
+ """Constructs OpenID scheme and credential from configuration and credential dictionaries.
210
+
211
+ Args:
212
+ config_dict: Dictionary containing OpenID Connect configuration, must
213
+ include at least 'authorization_endpoint' and 'token_endpoint'.
214
+ scopes: List of scopes to be used.
215
+ credential_dict: Dictionary containing credential information, must
216
+ include 'client_id', 'client_secret', and 'scopes'. May optionally
217
+ include 'redirect_uri'.
218
+
219
+ Returns:
220
+ Tuple: (OpenIdConnectWithConfig, AuthCredential)
221
+
222
+ Raises:
223
+ ValueError: If required fields are missing in the input dictionaries.
224
+ """
225
+
226
+ # Validate and create the OpenIdConnectWithConfig scheme
227
+ try:
228
+ config_dict["scopes"] = scopes
229
+ # If user provides the OpenID Config as a static dict, it may not contain
230
+ # openIdConnect URL.
231
+ if "openIdConnectUrl" not in config_dict:
232
+ config_dict["openIdConnectUrl"] = ""
233
+ openid_scheme = OpenIdConnectWithConfig.model_validate(config_dict)
234
+ except ValidationError as e:
235
+ raise ValueError(f"Invalid OpenID Connect configuration: {e}") from e
236
+
237
+ # Attempt to adjust credential_dict if this is a key downloaded from Google
238
+ # OAuth config
239
+ if len(list(credential_dict.values())) == 1:
240
+ credential_value = list(credential_dict.values())[0]
241
+ if "client_id" in credential_value and "client_secret" in credential_value:
242
+ credential_dict = credential_value
243
+
244
+ # Validate credential_dict
245
+ required_credential_fields = ["client_id", "client_secret"]
246
+ missing_fields = [
247
+ field
248
+ for field in required_credential_fields
249
+ if field not in credential_dict
250
+ ]
251
+ if missing_fields:
252
+ raise ValueError(
253
+ "Missing required fields in credential_dict:"
254
+ f" {', '.join(missing_fields)}"
255
+ )
256
+
257
+ # Construct AuthCredential
258
+ auth_credential = AuthCredential(
259
+ auth_type=AuthCredentialTypes.OPEN_ID_CONNECT,
260
+ oauth2=OAuth2Auth(
261
+ client_id=credential_dict["client_id"],
262
+ client_secret=credential_dict["client_secret"],
263
+ redirect_uri=credential_dict.get("redirect_uri", None),
264
+ ),
265
+ )
266
+
267
+ return openid_scheme, auth_credential
268
+
269
+
270
+ def openid_url_to_scheme_credential(
271
+ openid_url: str, scopes: List[str], credential_dict: Dict[str, Any]
272
+ ) -> Tuple[OpenIdConnectWithConfig, AuthCredential]:
273
+ """Constructs OpenID scheme and credential from OpenID URL, scopes, and credential dictionary.
274
+
275
+ Fetches OpenID configuration from the provided URL.
276
+
277
+ Args:
278
+ openid_url: The OpenID Connect discovery URL.
279
+ scopes: List of scopes to be used.
280
+ credential_dict: Dictionary containing credential information, must
281
+ include at least "client_id" and "client_secret", may optionally include
282
+ "redirect_uri" and "scope"
283
+
284
+ Returns:
285
+ Tuple: (AuthScheme, AuthCredential)
286
+
287
+ Raises:
288
+ ValueError: If the OpenID URL is invalid, fetching fails, or required
289
+ fields are missing.
290
+ requests.exceptions.RequestException: If there's an error during the
291
+ HTTP request.
292
+ """
293
+ try:
294
+ response = requests.get(openid_url, timeout=10)
295
+ response.raise_for_status()
296
+ config_dict = response.json()
297
+ except requests.exceptions.RequestException as e:
298
+ raise ValueError(
299
+ f"Failed to fetch OpenID configuration from {openid_url}: {e}"
300
+ ) from e
301
+ except ValueError as e:
302
+ raise ValueError(
303
+ "Invalid JSON response from OpenID configuration endpoint"
304
+ f" {openid_url}: {e}"
305
+ ) from e
306
+
307
+ # Add openIdConnectUrl to config dict
308
+ config_dict["openIdConnectUrl"] = openid_url
309
+
310
+ return openid_dict_to_scheme_credential(config_dict, scopes, credential_dict)
311
+
312
+
313
+ INTERNAL_AUTH_PREFIX = "_auth_prefix_vaf_"
314
+
315
+
316
+ def credential_to_param(
317
+ auth_scheme: AuthScheme,
318
+ auth_credential: AuthCredential,
319
+ ) -> Tuple[Optional[ApiParameter], Optional[Dict[str, Any]]]:
320
+ """Converts AuthCredential and AuthScheme to a Parameter and a dictionary for additional kwargs.
321
+
322
+ This function now supports all credential types returned by the exchangers:
323
+ - API Key
324
+ - HTTP Bearer (for Bearer tokens, OAuth2, Service Account, OpenID Connect)
325
+ - OAuth2 and OpenID Connect (returns None, None, as the token is now a Bearer
326
+ token)
327
+ - Service Account (returns None, None, as the token is now a Bearer token)
328
+
329
+ Args:
330
+ auth_scheme: The AuthScheme object.
331
+ auth_credential: The AuthCredential object.
332
+
333
+ Returns:
334
+ Tuple: (ApiParameter, Dict[str, Any])
335
+ """
336
+ if not auth_credential:
337
+ return None, None
338
+
339
+ if (
340
+ auth_scheme.type_ == AuthSchemeType.apiKey
341
+ and auth_credential
342
+ and auth_credential.api_key
343
+ ):
344
+ param_name = auth_scheme.name or ""
345
+ python_name = INTERNAL_AUTH_PREFIX + param_name
346
+ if auth_scheme.in_ == APIKeyIn.header:
347
+ param_location = "header"
348
+ elif auth_scheme.in_ == APIKeyIn.query:
349
+ param_location = "query"
350
+ elif auth_scheme.in_ == APIKeyIn.cookie:
351
+ param_location = "cookie"
352
+ else:
353
+ raise ValueError(f"Invalid API Key location: {auth_scheme.in_}")
354
+
355
+ param = ApiParameter(
356
+ original_name=param_name,
357
+ param_location=param_location,
358
+ param_schema=Schema(type="string"),
359
+ description=auth_scheme.description or "",
360
+ py_name=python_name,
361
+ )
362
+ kwargs = {param.py_name: auth_credential.api_key}
363
+ return param, kwargs
364
+
365
+ # TODO(cheliu): Split handling for OpenIDConnect scheme and native HTTPBearer
366
+ # Scheme
367
+ elif (
368
+ auth_credential and auth_credential.auth_type == AuthCredentialTypes.HTTP
369
+ ):
370
+ if (
371
+ auth_credential
372
+ and auth_credential.http
373
+ and auth_credential.http.credentials
374
+ and auth_credential.http.credentials.token
375
+ ):
376
+ param = ApiParameter(
377
+ original_name="Authorization",
378
+ param_location="header",
379
+ param_schema=Schema(type="string"),
380
+ description=auth_scheme.description or "Bearer token",
381
+ py_name=INTERNAL_AUTH_PREFIX + "Authorization",
382
+ )
383
+ kwargs = {
384
+ param.py_name: f"Bearer {auth_credential.http.credentials.token}"
385
+ }
386
+ return param, kwargs
387
+ elif (
388
+ auth_credential
389
+ and auth_credential.http
390
+ and auth_credential.http.credentials
391
+ and (
392
+ auth_credential.http.credentials.username
393
+ or auth_credential.http.credentials.password
394
+ )
395
+ ):
396
+ # Basic Auth is explicitly NOT supported
397
+ raise NotImplementedError("Basic Authentication is not supported.")
398
+ else:
399
+ raise ValueError("Invalid HTTP auth credentials")
400
+
401
+ # Service Account tokens, OAuth2 Tokens and OpenID Tokens are now handled as
402
+ # Bearer tokens.
403
+ elif (auth_scheme.type_ == AuthSchemeType.oauth2 and auth_credential) or (
404
+ auth_scheme.type_ == AuthSchemeType.openIdConnect and auth_credential
405
+ ):
406
+ if (
407
+ auth_credential.http
408
+ and auth_credential.http.credentials
409
+ and auth_credential.http.credentials.token
410
+ ):
411
+ param = ApiParameter(
412
+ original_name="Authorization",
413
+ param_location="header",
414
+ param_schema=Schema(type="string"),
415
+ description=auth_scheme.description or "Bearer token",
416
+ py_name=INTERNAL_AUTH_PREFIX + "Authorization",
417
+ )
418
+ kwargs = {
419
+ param.py_name: f"Bearer {auth_credential.http.credentials.token}"
420
+ }
421
+ return param, kwargs
422
+ return None, None
423
+ else:
424
+ raise ValueError("Invalid security scheme and credential combination")
425
+
426
+
427
+ def dict_to_auth_scheme(data: Dict[str, Any]) -> AuthScheme:
428
+ """Converts a dictionary to a FastAPI AuthScheme object.
429
+
430
+ Args:
431
+ data: The dictionary representing the security scheme.
432
+
433
+ Returns:
434
+ A AuthScheme object (APIKey, HTTPBase, OAuth2, OpenIdConnect, or
435
+ HTTPBearer).
436
+
437
+ Raises:
438
+ ValueError: If the 'type' field is missing or invalid, or if the
439
+ dictionary cannot be converted to the corresponding Pydantic model.
440
+
441
+ Example:
442
+ ```python
443
+ api_key_data = {
444
+ "type": "apiKey",
445
+ "in": "header",
446
+ "name": "X-API-Key",
447
+ }
448
+ api_key_scheme = dict_to_auth_scheme(api_key_data)
449
+
450
+ bearer_data = {
451
+ "type": "http",
452
+ "scheme": "bearer",
453
+ "bearerFormat": "JWT",
454
+ }
455
+ bearer_scheme = dict_to_auth_scheme(bearer_data)
456
+
457
+
458
+ oauth2_data = {
459
+ "type": "oauth2",
460
+ "flows": {
461
+ "authorizationCode": {
462
+ "authorizationUrl": "https://example.com/auth",
463
+ "tokenUrl": "https://example.com/token",
464
+ }
465
+ }
466
+ }
467
+ oauth2_scheme = dict_to_auth_scheme(oauth2_data)
468
+
469
+ openid_data = {
470
+ "type": "openIdConnect",
471
+ "openIdConnectUrl": "https://example.com/.well-known/openid-configuration"
472
+ }
473
+ openid_scheme = dict_to_auth_scheme(openid_data)
474
+
475
+
476
+ ```
477
+ """
478
+ if "type" not in data:
479
+ raise ValueError("Missing 'type' field in security scheme dictionary.")
480
+
481
+ security_type = data["type"]
482
+ try:
483
+ if security_type == "apiKey":
484
+ return APIKey.model_validate(data)
485
+ elif security_type == "http":
486
+ if data.get("scheme") == "bearer":
487
+ return HTTPBearer.model_validate(data)
488
+ else:
489
+ return HTTPBase.model_validate(data) # Generic HTTP
490
+ elif security_type == "oauth2":
491
+ return OAuth2.model_validate(data)
492
+ elif security_type == "openIdConnect":
493
+ return OpenIdConnect.model_validate(data)
494
+ else:
495
+ raise ValueError(f"Invalid security scheme type: {security_type}")
496
+
497
+ except ValidationError as e:
498
+ raise ValueError(f"Invalid security scheme data: {e}") from e
@@ -0,0 +1,25 @@
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 .auto_auth_credential_exchanger import AutoAuthCredentialExchanger
16
+ from .base_credential_exchanger import BaseAuthCredentialExchanger
17
+ from .oauth2_exchanger import OAuth2CredentialExchanger
18
+ from .service_account_exchanger import ServiceAccountCredentialExchanger
19
+
20
+ __all__ = [
21
+ 'AutoAuthCredentialExchanger',
22
+ 'BaseAuthCredentialExchanger',
23
+ 'OAuth2CredentialExchanger',
24
+ 'ServiceAccountCredentialExchanger',
25
+ ]
@@ -0,0 +1,105 @@
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 typing import Dict
16
+ from typing import Optional
17
+ from typing import Type
18
+
19
+ from .....auth.auth_credential import AuthCredential
20
+ from .....auth.auth_credential import AuthCredentialTypes
21
+ from .....auth.auth_schemes import AuthScheme
22
+ from .base_credential_exchanger import BaseAuthCredentialExchanger
23
+ from .oauth2_exchanger import OAuth2CredentialExchanger
24
+ from .service_account_exchanger import ServiceAccountCredentialExchanger
25
+
26
+
27
+ class AutoAuthCredentialExchanger(BaseAuthCredentialExchanger):
28
+ """Automatically selects the appropriate credential exchanger based on the auth scheme.
29
+
30
+ Optionally, an override can be provided to use a specific exchanger for a
31
+ given auth scheme.
32
+
33
+ Example (common case):
34
+ ```
35
+ exchanger = AutoAuthCredentialExchanger()
36
+ auth_credential = exchanger.exchange_credential(
37
+ auth_scheme=service_account_scheme,
38
+ auth_credential=service_account_credential,
39
+ )
40
+ # Returns an oauth token in the form of a bearer token.
41
+ ```
42
+
43
+ Example (use CustomAuthExchanger for OAuth2):
44
+ ```
45
+ exchanger = AutoAuthCredentialExchanger(
46
+ custom_exchangers={
47
+ AuthScheme.OAUTH2: CustomAuthExchanger,
48
+ }
49
+ )
50
+ ```
51
+
52
+ Attributes:
53
+ exchangers: A dictionary mapping auth scheme to credential exchanger class.
54
+ """
55
+
56
+ def __init__(
57
+ self,
58
+ custom_exchangers: Optional[
59
+ Dict[str, Type[BaseAuthCredentialExchanger]]
60
+ ] = None,
61
+ ):
62
+ """Initializes the AutoAuthCredentialExchanger.
63
+
64
+ Args:
65
+ custom_exchangers: Optional dictionary for adding or overriding auth
66
+ exchangers. The key is the auth scheme, and the value is the credential
67
+ exchanger class.
68
+ """
69
+ self.exchangers = {
70
+ AuthCredentialTypes.OAUTH2: OAuth2CredentialExchanger,
71
+ AuthCredentialTypes.OPEN_ID_CONNECT: OAuth2CredentialExchanger,
72
+ AuthCredentialTypes.SERVICE_ACCOUNT: ServiceAccountCredentialExchanger,
73
+ }
74
+
75
+ if custom_exchangers:
76
+ self.exchangers.update(custom_exchangers)
77
+
78
+ def exchange_credential(
79
+ self,
80
+ auth_scheme: AuthScheme,
81
+ auth_credential: Optional[AuthCredential] = None,
82
+ ) -> Optional[AuthCredential]:
83
+ """Automatically exchanges for the credential uses the appropriate credential exchanger.
84
+
85
+ Args:
86
+ auth_scheme (AuthScheme): The security scheme.
87
+ auth_credential (AuthCredential): Optional. The authentication
88
+ credential.
89
+
90
+ Returns: (AuthCredential)
91
+ A new AuthCredential object containing the exchanged credential.
92
+
93
+ """
94
+ if not auth_credential:
95
+ return None
96
+
97
+ exchanger_class = self.exchangers.get(
98
+ auth_credential.auth_type if auth_credential else None
99
+ )
100
+
101
+ if not exchanger_class:
102
+ return auth_credential
103
+
104
+ exchanger = exchanger_class()
105
+ return exchanger.exchange_credential(auth_scheme, auth_credential)
@@ -0,0 +1,55 @@
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 abc
16
+ from typing import Optional
17
+
18
+ from .....auth.auth_credential import (
19
+ AuthCredential,
20
+ )
21
+ from .....auth.auth_schemes import AuthScheme
22
+
23
+
24
+ class AuthCredentialMissingError(Exception):
25
+ """Exception raised when required authentication credentials are missing."""
26
+
27
+ def __init__(self, message: str):
28
+ super().__init__(message)
29
+ self.message = message
30
+
31
+
32
+ class BaseAuthCredentialExchanger:
33
+ """Base class for authentication credential exchangers."""
34
+
35
+ @abc.abstractmethod
36
+ def exchange_credential(
37
+ self,
38
+ auth_scheme: AuthScheme,
39
+ auth_credential: Optional[AuthCredential] = None,
40
+ ) -> AuthCredential:
41
+ """Exchanges the provided authentication credential for a usable token/credential.
42
+
43
+ Args:
44
+ auth_scheme: The security scheme.
45
+ auth_credential: The authentication credential.
46
+
47
+ Returns:
48
+ An updated AuthCredential object containing the fetched credential.
49
+ For simple schemes like API key, it may return the original credential
50
+ if no exchange is needed.
51
+
52
+ Raises:
53
+ NotImplementedError: If the method is not implemented by a subclass.
54
+ """
55
+ raise NotImplementedError("Subclasses must implement exchange_credential.")