google-adk 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/adk/__init__.py +20 -0
- google/adk/agents/__init__.py +32 -0
- google/adk/agents/active_streaming_tool.py +38 -0
- google/adk/agents/base_agent.py +345 -0
- google/adk/agents/callback_context.py +112 -0
- google/adk/agents/invocation_context.py +181 -0
- google/adk/agents/langgraph_agent.py +140 -0
- google/adk/agents/live_request_queue.py +64 -0
- google/adk/agents/llm_agent.py +376 -0
- google/adk/agents/loop_agent.py +62 -0
- google/adk/agents/parallel_agent.py +96 -0
- google/adk/agents/readonly_context.py +46 -0
- google/adk/agents/remote_agent.py +50 -0
- google/adk/agents/run_config.py +87 -0
- google/adk/agents/sequential_agent.py +45 -0
- google/adk/agents/transcription_entry.py +34 -0
- google/adk/artifacts/__init__.py +23 -0
- google/adk/artifacts/base_artifact_service.py +128 -0
- google/adk/artifacts/gcs_artifact_service.py +195 -0
- google/adk/artifacts/in_memory_artifact_service.py +133 -0
- google/adk/auth/__init__.py +22 -0
- google/adk/auth/auth_credential.py +220 -0
- google/adk/auth/auth_handler.py +268 -0
- google/adk/auth/auth_preprocessor.py +116 -0
- google/adk/auth/auth_schemes.py +67 -0
- google/adk/auth/auth_tool.py +55 -0
- google/adk/cli/__init__.py +15 -0
- google/adk/cli/__main__.py +18 -0
- google/adk/cli/agent_graph.py +122 -0
- google/adk/cli/browser/adk_favicon.svg +17 -0
- google/adk/cli/browser/assets/audio-processor.js +51 -0
- google/adk/cli/browser/assets/config/runtime-config.json +3 -0
- google/adk/cli/browser/index.html +33 -0
- google/adk/cli/browser/main-XUU6OGCC.js +75 -0
- google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
- google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
- google/adk/cli/cli.py +181 -0
- google/adk/cli/cli_deploy.py +181 -0
- google/adk/cli/cli_eval.py +282 -0
- google/adk/cli/cli_tools_click.py +479 -0
- google/adk/cli/fast_api.py +774 -0
- google/adk/cli/media_streamer/__init__.py +19 -0
- google/adk/cli/media_streamer/index.html +228 -0
- google/adk/cli/utils/__init__.py +49 -0
- google/adk/cli/utils/envs.py +57 -0
- google/adk/cli/utils/evals.py +93 -0
- google/adk/cli/utils/logs.py +72 -0
- google/adk/code_executors/__init__.py +49 -0
- google/adk/code_executors/base_code_executor.py +97 -0
- google/adk/code_executors/code_execution_utils.py +256 -0
- google/adk/code_executors/code_executor_context.py +202 -0
- google/adk/code_executors/container_code_executor.py +196 -0
- google/adk/code_executors/unsafe_local_code_executor.py +71 -0
- google/adk/code_executors/vertex_ai_code_executor.py +234 -0
- google/adk/evaluation/__init__.py +31 -0
- google/adk/evaluation/agent_evaluator.py +329 -0
- google/adk/evaluation/evaluation_constants.py +24 -0
- google/adk/evaluation/evaluation_generator.py +270 -0
- google/adk/evaluation/response_evaluator.py +135 -0
- google/adk/evaluation/trajectory_evaluator.py +184 -0
- google/adk/events/__init__.py +21 -0
- google/adk/events/event.py +130 -0
- google/adk/events/event_actions.py +55 -0
- google/adk/examples/__init__.py +28 -0
- google/adk/examples/base_example_provider.py +35 -0
- google/adk/examples/example.py +27 -0
- google/adk/examples/example_util.py +123 -0
- google/adk/examples/vertex_ai_example_store.py +104 -0
- google/adk/flows/__init__.py +14 -0
- google/adk/flows/llm_flows/__init__.py +20 -0
- google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
- google/adk/flows/llm_flows/_code_execution.py +458 -0
- google/adk/flows/llm_flows/_nl_planning.py +129 -0
- google/adk/flows/llm_flows/agent_transfer.py +132 -0
- google/adk/flows/llm_flows/audio_transcriber.py +109 -0
- google/adk/flows/llm_flows/auto_flow.py +49 -0
- google/adk/flows/llm_flows/base_llm_flow.py +559 -0
- google/adk/flows/llm_flows/basic.py +72 -0
- google/adk/flows/llm_flows/contents.py +370 -0
- google/adk/flows/llm_flows/functions.py +486 -0
- google/adk/flows/llm_flows/identity.py +47 -0
- google/adk/flows/llm_flows/instructions.py +137 -0
- google/adk/flows/llm_flows/single_flow.py +57 -0
- google/adk/memory/__init__.py +35 -0
- google/adk/memory/base_memory_service.py +74 -0
- google/adk/memory/in_memory_memory_service.py +62 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
- google/adk/models/__init__.py +31 -0
- google/adk/models/anthropic_llm.py +243 -0
- google/adk/models/base_llm.py +87 -0
- google/adk/models/base_llm_connection.py +76 -0
- google/adk/models/gemini_llm_connection.py +200 -0
- google/adk/models/google_llm.py +331 -0
- google/adk/models/lite_llm.py +673 -0
- google/adk/models/llm_request.py +98 -0
- google/adk/models/llm_response.py +111 -0
- google/adk/models/registry.py +102 -0
- google/adk/planners/__init__.py +23 -0
- google/adk/planners/base_planner.py +66 -0
- google/adk/planners/built_in_planner.py +75 -0
- google/adk/planners/plan_re_act_planner.py +208 -0
- google/adk/runners.py +456 -0
- google/adk/sessions/__init__.py +41 -0
- google/adk/sessions/base_session_service.py +133 -0
- google/adk/sessions/database_session_service.py +522 -0
- google/adk/sessions/in_memory_session_service.py +206 -0
- google/adk/sessions/session.py +54 -0
- google/adk/sessions/state.py +71 -0
- google/adk/sessions/vertex_ai_session_service.py +356 -0
- google/adk/telemetry.py +189 -0
- google/adk/tests/__init__.py +14 -0
- google/adk/tests/integration/.env.example +10 -0
- google/adk/tests/integration/__init__.py +18 -0
- google/adk/tests/integration/conftest.py +119 -0
- google/adk/tests/integration/fixture/__init__.py +14 -0
- google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
- google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
- google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
- google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
- google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
- google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
- google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
- google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
- google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
- google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
- google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +243 -0
- google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
- google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
- google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
- google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
- google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
- google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
- google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
- google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
- google/adk/tests/integration/models/__init__.py +14 -0
- google/adk/tests/integration/models/test_google_llm.py +65 -0
- google/adk/tests/integration/test_callback.py +70 -0
- google/adk/tests/integration/test_context_variable.py +67 -0
- google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
- google/adk/tests/integration/test_multi_agent.py +28 -0
- google/adk/tests/integration/test_multi_turn.py +42 -0
- google/adk/tests/integration/test_single_agent.py +23 -0
- google/adk/tests/integration/test_sub_agent.py +26 -0
- google/adk/tests/integration/test_system_instruction.py +177 -0
- google/adk/tests/integration/test_tools.py +287 -0
- google/adk/tests/integration/test_with_test_file.py +34 -0
- google/adk/tests/integration/tools/__init__.py +14 -0
- google/adk/tests/integration/utils/__init__.py +16 -0
- google/adk/tests/integration/utils/asserts.py +75 -0
- google/adk/tests/integration/utils/test_runner.py +97 -0
- google/adk/tests/unittests/__init__.py +14 -0
- google/adk/tests/unittests/agents/__init__.py +14 -0
- google/adk/tests/unittests/agents/test_base_agent.py +407 -0
- google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
- google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
- google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
- google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
- google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
- google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
- google/adk/tests/unittests/artifacts/__init__.py +14 -0
- google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
- google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
- google/adk/tests/unittests/conftest.py +73 -0
- google/adk/tests/unittests/fast_api/__init__.py +14 -0
- google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
- google/adk/tests/unittests/flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
- google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
- google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
- google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
- google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
- google/adk/tests/unittests/models/__init__.py +14 -0
- google/adk/tests/unittests/models/test_google_llm.py +224 -0
- google/adk/tests/unittests/models/test_litellm.py +804 -0
- google/adk/tests/unittests/models/test_models.py +60 -0
- google/adk/tests/unittests/sessions/__init__.py +14 -0
- google/adk/tests/unittests/sessions/test_session_service.py +227 -0
- google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
- google/adk/tests/unittests/streaming/__init__.py +14 -0
- google/adk/tests/unittests/streaming/test_streaming.py +50 -0
- google/adk/tests/unittests/tools/__init__.py +14 -0
- google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
- google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
- google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
- google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
- google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
- google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
- google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
- google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
- google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
- google/adk/tests/unittests/tools/test_base_tool.py +141 -0
- google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
- google/adk/tests/unittests/utils.py +304 -0
- google/adk/tools/__init__.py +51 -0
- google/adk/tools/_automatic_function_calling_util.py +346 -0
- google/adk/tools/agent_tool.py +176 -0
- google/adk/tools/apihub_tool/__init__.py +19 -0
- google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
- google/adk/tools/apihub_tool/clients/__init__.py +13 -0
- google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
- google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
- google/adk/tools/application_integration_tool/__init__.py +19 -0
- google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
- google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
- google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
- google/adk/tools/base_tool.py +144 -0
- google/adk/tools/built_in_code_execution_tool.py +59 -0
- google/adk/tools/crewai_tool.py +72 -0
- google/adk/tools/example_tool.py +62 -0
- google/adk/tools/exit_loop_tool.py +23 -0
- google/adk/tools/function_parameter_parse_util.py +307 -0
- google/adk/tools/function_tool.py +87 -0
- google/adk/tools/get_user_choice_tool.py +28 -0
- google/adk/tools/google_api_tool/__init__.py +14 -0
- google/adk/tools/google_api_tool/google_api_tool.py +59 -0
- google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
- google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
- google/adk/tools/google_search_tool.py +68 -0
- google/adk/tools/langchain_tool.py +86 -0
- google/adk/tools/load_artifacts_tool.py +113 -0
- google/adk/tools/load_memory_tool.py +58 -0
- google/adk/tools/load_web_page.py +41 -0
- google/adk/tools/long_running_tool.py +39 -0
- google/adk/tools/mcp_tool/__init__.py +42 -0
- google/adk/tools/mcp_tool/conversion_utils.py +161 -0
- google/adk/tools/mcp_tool/mcp_tool.py +113 -0
- google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
- google/adk/tools/openapi_tool/__init__.py +21 -0
- google/adk/tools/openapi_tool/auth/__init__.py +19 -0
- google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
- google/adk/tools/openapi_tool/common/__init__.py +19 -0
- google/adk/tools/openapi_tool/common/common.py +300 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
- google/adk/tools/preload_memory_tool.py +72 -0
- google/adk/tools/retrieval/__init__.py +36 -0
- google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
- google/adk/tools/retrieval/files_retrieval.py +33 -0
- google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
- google/adk/tools/tool_context.py +90 -0
- google/adk/tools/toolbox_tool.py +46 -0
- google/adk/tools/transfer_to_agent_tool.py +21 -0
- google/adk/tools/vertex_ai_search_tool.py +96 -0
- google/adk/version.py +16 -0
- google_adk-0.0.1.dist-info/LICENSE.txt → google_adk-0.0.2.dist-info/LICENSE +32 -0
- google_adk-0.0.2.dist-info/METADATA +73 -0
- google_adk-0.0.2.dist-info/RECORD +308 -0
- {google_adk-0.0.1.dist-info → google_adk-0.0.2.dist-info}/WHEEL +1 -2
- google_adk-0.0.2.dist-info/entry_points.txt +3 -0
- agent_kit/__init__.py +0 -0
- google_adk-0.0.1.dist-info/METADATA +0 -15
- google_adk-0.0.1.dist-info/RECORD +0 -6
- google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,231 @@
|
|
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 copy
|
16
|
+
from typing import Any
|
17
|
+
from typing import Dict
|
18
|
+
from typing import List
|
19
|
+
from typing import Optional
|
20
|
+
|
21
|
+
from fastapi.openapi.models import Operation
|
22
|
+
from pydantic import BaseModel
|
23
|
+
|
24
|
+
from ....auth.auth_credential import AuthCredential
|
25
|
+
from ....auth.auth_schemes import AuthScheme
|
26
|
+
from ..common.common import ApiParameter
|
27
|
+
from ..common.common import to_snake_case
|
28
|
+
from .operation_parser import OperationParser
|
29
|
+
|
30
|
+
|
31
|
+
class OperationEndpoint(BaseModel):
|
32
|
+
base_url: str
|
33
|
+
path: str
|
34
|
+
method: str
|
35
|
+
|
36
|
+
|
37
|
+
class ParsedOperation(BaseModel):
|
38
|
+
name: str
|
39
|
+
description: str
|
40
|
+
endpoint: OperationEndpoint
|
41
|
+
operation: Operation
|
42
|
+
parameters: List[ApiParameter]
|
43
|
+
return_value: ApiParameter
|
44
|
+
auth_scheme: Optional[AuthScheme] = None
|
45
|
+
auth_credential: Optional[AuthCredential] = None
|
46
|
+
additional_context: Optional[Any] = None
|
47
|
+
|
48
|
+
|
49
|
+
class OpenApiSpecParser:
|
50
|
+
"""Generates Python code, JSON schema, and callables for an OpenAPI operation.
|
51
|
+
|
52
|
+
This class takes an OpenApiOperation object and provides methods to generate:
|
53
|
+
1. A string representation of a Python function that handles the operation.
|
54
|
+
2. A JSON schema representing the input parameters of the operation.
|
55
|
+
3. A callable Python object (a function) that can execute the operation.
|
56
|
+
"""
|
57
|
+
|
58
|
+
def parse(self, openapi_spec_dict: Dict[str, Any]) -> List[ParsedOperation]:
|
59
|
+
"""Extracts an OpenAPI spec dict into a list of ParsedOperation objects.
|
60
|
+
|
61
|
+
ParsedOperation objects are further used for generating RestApiTool.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
openapi_spec_dict: A dictionary representing the OpenAPI specification.
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
A list of ParsedOperation objects.
|
68
|
+
"""
|
69
|
+
|
70
|
+
openapi_spec_dict = self._resolve_references(openapi_spec_dict)
|
71
|
+
operations = self._collect_operations(openapi_spec_dict)
|
72
|
+
return operations
|
73
|
+
|
74
|
+
def _collect_operations(
|
75
|
+
self, openapi_spec: Dict[str, Any]
|
76
|
+
) -> List[ParsedOperation]:
|
77
|
+
"""Collects operations from an OpenAPI spec."""
|
78
|
+
operations = []
|
79
|
+
|
80
|
+
# Taking first server url, or default to empty string if not present
|
81
|
+
base_url = ""
|
82
|
+
if openapi_spec.get("servers"):
|
83
|
+
base_url = openapi_spec["servers"][0].get("url", "")
|
84
|
+
|
85
|
+
# Get global security scheme (if any)
|
86
|
+
global_scheme_name = None
|
87
|
+
if openapi_spec.get("security"):
|
88
|
+
# Use first scheme by default.
|
89
|
+
scheme_names = list(openapi_spec["security"][0].keys())
|
90
|
+
global_scheme_name = scheme_names[0] if scheme_names else None
|
91
|
+
|
92
|
+
auth_schemes = openapi_spec.get("components", {}).get("securitySchemes", {})
|
93
|
+
|
94
|
+
for path, path_item in openapi_spec.get("paths", {}).items():
|
95
|
+
if path_item is None:
|
96
|
+
continue
|
97
|
+
|
98
|
+
for method in (
|
99
|
+
"get",
|
100
|
+
"post",
|
101
|
+
"put",
|
102
|
+
"delete",
|
103
|
+
"patch",
|
104
|
+
"head",
|
105
|
+
"options",
|
106
|
+
"trace",
|
107
|
+
):
|
108
|
+
operation_dict = path_item.get(method)
|
109
|
+
if operation_dict is None:
|
110
|
+
continue
|
111
|
+
|
112
|
+
# If operation ID is missing, assign an operation id based on path
|
113
|
+
# and method
|
114
|
+
if "operationId" not in operation_dict:
|
115
|
+
temp_id = to_snake_case(f"{path}_{method}")
|
116
|
+
operation_dict["operationId"] = temp_id
|
117
|
+
|
118
|
+
url = OperationEndpoint(base_url=base_url, path=path, method=method)
|
119
|
+
operation = Operation.model_validate(operation_dict)
|
120
|
+
operation_parser = OperationParser(operation)
|
121
|
+
|
122
|
+
# Check for operation-specific auth scheme
|
123
|
+
auth_scheme_name = operation_parser.get_auth_scheme_name()
|
124
|
+
auth_scheme_name = (
|
125
|
+
auth_scheme_name if auth_scheme_name else global_scheme_name
|
126
|
+
)
|
127
|
+
auth_scheme = (
|
128
|
+
auth_schemes.get(auth_scheme_name) if auth_scheme_name else None
|
129
|
+
)
|
130
|
+
|
131
|
+
parsed_op = ParsedOperation(
|
132
|
+
name=operation_parser.get_function_name(),
|
133
|
+
description=operation.description or operation.summary or "",
|
134
|
+
endpoint=url,
|
135
|
+
operation=operation,
|
136
|
+
parameters=operation_parser.get_parameters(),
|
137
|
+
return_value=operation_parser.get_return_value(),
|
138
|
+
auth_scheme=auth_scheme,
|
139
|
+
auth_credential=None, # Placeholder
|
140
|
+
additional_context={},
|
141
|
+
)
|
142
|
+
operations.append(parsed_op)
|
143
|
+
|
144
|
+
return operations
|
145
|
+
|
146
|
+
def _resolve_references(self, openapi_spec: Dict[str, Any]) -> Dict[str, Any]:
|
147
|
+
"""Recursively resolves all $ref references in an OpenAPI specification.
|
148
|
+
|
149
|
+
Handles circular references correctly.
|
150
|
+
|
151
|
+
Args:
|
152
|
+
openapi_spec: A dictionary representing the OpenAPI specification.
|
153
|
+
|
154
|
+
Returns:
|
155
|
+
A dictionary representing the OpenAPI specification with all references
|
156
|
+
resolved.
|
157
|
+
"""
|
158
|
+
|
159
|
+
openapi_spec = copy.deepcopy(openapi_spec) # Work on a copy
|
160
|
+
resolved_cache = {} # Cache resolved references
|
161
|
+
|
162
|
+
def resolve_ref(ref_string, current_doc):
|
163
|
+
"""Resolves a single $ref string."""
|
164
|
+
parts = ref_string.split("/")
|
165
|
+
if parts[0] != "#":
|
166
|
+
raise ValueError(f"External references not supported: {ref_string}")
|
167
|
+
|
168
|
+
current = current_doc
|
169
|
+
for part in parts[1:]:
|
170
|
+
if part in current:
|
171
|
+
current = current[part]
|
172
|
+
else:
|
173
|
+
return None # Reference not found
|
174
|
+
return current
|
175
|
+
|
176
|
+
def recursive_resolve(obj, current_doc, seen_refs=None):
|
177
|
+
"""Recursively resolves references, handling circularity.
|
178
|
+
|
179
|
+
Args:
|
180
|
+
obj: The object to traverse.
|
181
|
+
current_doc: Document to search for refs.
|
182
|
+
seen_refs: A set to track already-visited references (for circularity
|
183
|
+
detection).
|
184
|
+
|
185
|
+
Returns:
|
186
|
+
The resolved object.
|
187
|
+
"""
|
188
|
+
if seen_refs is None:
|
189
|
+
seen_refs = set() # Initialize the set if it's the first call
|
190
|
+
|
191
|
+
if isinstance(obj, dict):
|
192
|
+
if "$ref" in obj and isinstance(obj["$ref"], str):
|
193
|
+
ref_string = obj["$ref"]
|
194
|
+
|
195
|
+
# Check for circularity
|
196
|
+
if ref_string in seen_refs and ref_string not in resolved_cache:
|
197
|
+
# Circular reference detected! Return a *copy* of the object,
|
198
|
+
# but *without* the $ref. This breaks the cycle while
|
199
|
+
# still maintaining the overall structure.
|
200
|
+
return {k: v for k, v in obj.items() if k != "$ref"}
|
201
|
+
|
202
|
+
seen_refs.add(ref_string) # Add the reference to the set
|
203
|
+
|
204
|
+
# Check if we have a cached resolved value
|
205
|
+
if ref_string in resolved_cache:
|
206
|
+
return copy.deepcopy(resolved_cache[ref_string])
|
207
|
+
|
208
|
+
resolved_value = resolve_ref(ref_string, current_doc)
|
209
|
+
if resolved_value is not None:
|
210
|
+
# Recursively resolve the *resolved* value,
|
211
|
+
# passing along the 'seen_refs' set
|
212
|
+
resolved_value = recursive_resolve(
|
213
|
+
resolved_value, current_doc, seen_refs
|
214
|
+
)
|
215
|
+
resolved_cache[ref_string] = resolved_value
|
216
|
+
return copy.deepcopy(resolved_value) # return the cached result
|
217
|
+
else:
|
218
|
+
return obj # return original if no resolved value.
|
219
|
+
|
220
|
+
else:
|
221
|
+
new_dict = {}
|
222
|
+
for key, value in obj.items():
|
223
|
+
new_dict[key] = recursive_resolve(value, current_doc, seen_refs)
|
224
|
+
return new_dict
|
225
|
+
|
226
|
+
elif isinstance(obj, list):
|
227
|
+
return [recursive_resolve(item, current_doc, seen_refs) for item in obj]
|
228
|
+
else:
|
229
|
+
return obj
|
230
|
+
|
231
|
+
return recursive_resolve(openapi_spec, openapi_spec)
|
@@ -0,0 +1,144 @@
|
|
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 json
|
16
|
+
import logging
|
17
|
+
from typing import Any
|
18
|
+
from typing import Dict
|
19
|
+
from typing import Final
|
20
|
+
from typing import List
|
21
|
+
from typing import Literal
|
22
|
+
from typing import Optional
|
23
|
+
|
24
|
+
import yaml
|
25
|
+
|
26
|
+
from ....auth.auth_credential import AuthCredential
|
27
|
+
from ....auth.auth_schemes import AuthScheme
|
28
|
+
from .openapi_spec_parser import OpenApiSpecParser
|
29
|
+
from .rest_api_tool import RestApiTool
|
30
|
+
|
31
|
+
logger = logging.getLogger(__name__)
|
32
|
+
|
33
|
+
|
34
|
+
class OpenAPIToolset:
|
35
|
+
"""Class for parsing OpenAPI spec into a list of RestApiTool.
|
36
|
+
|
37
|
+
Usage:
|
38
|
+
```
|
39
|
+
# Initialize OpenAPI toolset from a spec string.
|
40
|
+
openapi_toolset = OpenAPIToolset(spec_str=openapi_spec_str,
|
41
|
+
spec_str_type="json")
|
42
|
+
# Or, initialize OpenAPI toolset from a spec dictionary.
|
43
|
+
openapi_toolset = OpenAPIToolset(spec_dict=openapi_spec_dict)
|
44
|
+
|
45
|
+
# Add all tools to an agent.
|
46
|
+
agent = Agent(
|
47
|
+
tools=[*openapi_toolset.get_tools()]
|
48
|
+
)
|
49
|
+
# Or, add a single tool to an agent.
|
50
|
+
agent = Agent(
|
51
|
+
tools=[openapi_toolset.get_tool('tool_name')]
|
52
|
+
)
|
53
|
+
```
|
54
|
+
"""
|
55
|
+
|
56
|
+
def __init__(
|
57
|
+
self,
|
58
|
+
*,
|
59
|
+
spec_dict: Optional[Dict[str, Any]] = None,
|
60
|
+
spec_str: Optional[str] = None,
|
61
|
+
spec_str_type: Literal["json", "yaml"] = "json",
|
62
|
+
auth_scheme: Optional[AuthScheme] = None,
|
63
|
+
auth_credential: Optional[AuthCredential] = None,
|
64
|
+
):
|
65
|
+
"""Initializes the OpenAPIToolset.
|
66
|
+
|
67
|
+
Usage:
|
68
|
+
```
|
69
|
+
# Initialize OpenAPI toolset from a spec string.
|
70
|
+
openapi_toolset = OpenAPIToolset(spec_str=openapi_spec_str,
|
71
|
+
spec_str_type="json")
|
72
|
+
# Or, initialize OpenAPI toolset from a spec dictionary.
|
73
|
+
openapi_toolset = OpenAPIToolset(spec_dict=openapi_spec_dict)
|
74
|
+
|
75
|
+
# Add all tools to an agent.
|
76
|
+
agent = Agent(
|
77
|
+
tools=[*openapi_toolset.get_tools()]
|
78
|
+
)
|
79
|
+
# Or, add a single tool to an agent.
|
80
|
+
agent = Agent(
|
81
|
+
tools=[openapi_toolset.get_tool('tool_name')]
|
82
|
+
)
|
83
|
+
```
|
84
|
+
|
85
|
+
Args:
|
86
|
+
spec_dict: The OpenAPI spec dictionary. If provided, it will be used
|
87
|
+
instead of loading the spec from a string.
|
88
|
+
spec_str: The OpenAPI spec string in JSON or YAML format. It will be used
|
89
|
+
when spec_dict is not provided.
|
90
|
+
spec_str_type: The type of the OpenAPI spec string. Can be "json" or
|
91
|
+
"yaml".
|
92
|
+
auth_scheme: The auth scheme to use for all tools. Use AuthScheme or use
|
93
|
+
helpers in `google.adk.tools.openapi_tool.auth.auth_helpers`
|
94
|
+
auth_credential: The auth credential to use for all tools. Use
|
95
|
+
AuthCredential or use helpers in
|
96
|
+
`google.adk.tools.openapi_tool.auth.auth_helpers`
|
97
|
+
"""
|
98
|
+
if not spec_dict:
|
99
|
+
spec_dict = self._load_spec(spec_str, spec_str_type)
|
100
|
+
self.tools: Final[List[RestApiTool]] = list(self._parse(spec_dict))
|
101
|
+
if auth_scheme or auth_credential:
|
102
|
+
self._configure_auth_all(auth_scheme, auth_credential)
|
103
|
+
|
104
|
+
def _configure_auth_all(
|
105
|
+
self, auth_scheme: AuthScheme, auth_credential: AuthCredential
|
106
|
+
):
|
107
|
+
"""Configure auth scheme and credential for all tools."""
|
108
|
+
|
109
|
+
for tool in self.tools:
|
110
|
+
if auth_scheme:
|
111
|
+
tool.configure_auth_scheme(auth_scheme)
|
112
|
+
if auth_credential:
|
113
|
+
tool.configure_auth_credential(auth_credential)
|
114
|
+
|
115
|
+
def get_tools(self) -> List[RestApiTool]:
|
116
|
+
"""Get all tools in the toolset."""
|
117
|
+
return self.tools
|
118
|
+
|
119
|
+
def get_tool(self, tool_name: str) -> Optional[RestApiTool]:
|
120
|
+
"""Get a tool by name."""
|
121
|
+
matching_tool = filter(lambda t: t.name == tool_name, self.tools)
|
122
|
+
return next(matching_tool, None)
|
123
|
+
|
124
|
+
def _load_spec(
|
125
|
+
self, spec_str: str, spec_type: Literal["json", "yaml"]
|
126
|
+
) -> Dict[str, Any]:
|
127
|
+
"""Loads the OpenAPI spec string into adictionary."""
|
128
|
+
if spec_type == "json":
|
129
|
+
return json.loads(spec_str)
|
130
|
+
elif spec_type == "yaml":
|
131
|
+
return yaml.safe_load(spec_str)
|
132
|
+
else:
|
133
|
+
raise ValueError(f"Unsupported spec type: {spec_type}")
|
134
|
+
|
135
|
+
def _parse(self, openapi_spec_dict: Dict[str, Any]) -> List[RestApiTool]:
|
136
|
+
"""Parse OpenAPI spec into a list of RestApiTool."""
|
137
|
+
operations = OpenApiSpecParser().parse(openapi_spec_dict)
|
138
|
+
|
139
|
+
tools = []
|
140
|
+
for o in operations:
|
141
|
+
tool = RestApiTool.from_parsed_operation(o)
|
142
|
+
logger.info("Parsed tool: %s", tool.name)
|
143
|
+
tools.append(tool)
|
144
|
+
return tools
|
@@ -0,0 +1,260 @@
|
|
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 inspect
|
16
|
+
from textwrap import dedent
|
17
|
+
from typing import Any
|
18
|
+
from typing import Dict
|
19
|
+
from typing import List
|
20
|
+
from typing import Optional
|
21
|
+
from typing import Union
|
22
|
+
|
23
|
+
from fastapi.encoders import jsonable_encoder
|
24
|
+
from fastapi.openapi.models import Operation
|
25
|
+
from fastapi.openapi.models import Parameter
|
26
|
+
from fastapi.openapi.models import Schema
|
27
|
+
|
28
|
+
from ..common.common import ApiParameter
|
29
|
+
from ..common.common import PydocHelper
|
30
|
+
from ..common.common import to_snake_case
|
31
|
+
|
32
|
+
|
33
|
+
class OperationParser:
|
34
|
+
"""Generates parameters for Python functions from an OpenAPI operation.
|
35
|
+
|
36
|
+
This class processes an OpenApiOperation object and provides helper methods
|
37
|
+
to extract information needed to generate Python function declarations,
|
38
|
+
docstrings, signatures, and JSON schemas. It handles parameter processing,
|
39
|
+
name deduplication, and type hint generation.
|
40
|
+
"""
|
41
|
+
|
42
|
+
def __init__(
|
43
|
+
self, operation: Union[Operation, Dict[str, Any], str], should_parse=True
|
44
|
+
):
|
45
|
+
"""Initializes the OperationParser with an OpenApiOperation.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
operation: The OpenApiOperation object or a dictionary to process.
|
49
|
+
should_parse: Whether to parse the operation during initialization.
|
50
|
+
"""
|
51
|
+
if isinstance(operation, dict):
|
52
|
+
self.operation = Operation.model_validate(operation)
|
53
|
+
elif isinstance(operation, str):
|
54
|
+
self.operation = Operation.model_validate_json(operation)
|
55
|
+
else:
|
56
|
+
self.operation = operation
|
57
|
+
|
58
|
+
self.params: List[ApiParameter] = []
|
59
|
+
self.return_value: Optional[ApiParameter] = None
|
60
|
+
if should_parse:
|
61
|
+
self._process_operation_parameters()
|
62
|
+
self._process_request_body()
|
63
|
+
self._process_return_value()
|
64
|
+
self._dedupe_param_names()
|
65
|
+
|
66
|
+
@classmethod
|
67
|
+
def load(
|
68
|
+
cls,
|
69
|
+
operation: Union[Operation, Dict[str, Any]],
|
70
|
+
params: List[ApiParameter],
|
71
|
+
return_value: Optional[ApiParameter] = None,
|
72
|
+
) -> 'OperationParser':
|
73
|
+
parser = cls(operation, should_parse=False)
|
74
|
+
parser.params = params
|
75
|
+
parser.return_value = return_value
|
76
|
+
return parser
|
77
|
+
|
78
|
+
def _process_operation_parameters(self):
|
79
|
+
"""Processes parameters from the OpenAPI operation."""
|
80
|
+
parameters = self.operation.parameters or []
|
81
|
+
for param in parameters:
|
82
|
+
if isinstance(param, Parameter):
|
83
|
+
original_name = param.name
|
84
|
+
description = param.description or ''
|
85
|
+
location = param.in_ or ''
|
86
|
+
schema = param.schema_ or {} # Use schema_ instead of .schema
|
87
|
+
|
88
|
+
self.params.append(
|
89
|
+
ApiParameter(
|
90
|
+
original_name=original_name,
|
91
|
+
param_location=location,
|
92
|
+
param_schema=schema,
|
93
|
+
description=description,
|
94
|
+
)
|
95
|
+
)
|
96
|
+
|
97
|
+
def _process_request_body(self):
|
98
|
+
"""Processes the request body from the OpenAPI operation."""
|
99
|
+
request_body = self.operation.requestBody
|
100
|
+
if not request_body:
|
101
|
+
return
|
102
|
+
|
103
|
+
content = request_body.content or {}
|
104
|
+
if not content:
|
105
|
+
return
|
106
|
+
|
107
|
+
# If request body is an object, expand the properties as parameters
|
108
|
+
for _, media_type_object in content.items():
|
109
|
+
schema = media_type_object.schema_ or {}
|
110
|
+
description = request_body.description or ''
|
111
|
+
|
112
|
+
if schema and schema.type == 'object':
|
113
|
+
for prop_name, prop_details in schema.properties.items():
|
114
|
+
self.params.append(
|
115
|
+
ApiParameter(
|
116
|
+
original_name=prop_name,
|
117
|
+
param_location='body',
|
118
|
+
param_schema=prop_details,
|
119
|
+
description=prop_details.description,
|
120
|
+
)
|
121
|
+
)
|
122
|
+
|
123
|
+
elif schema and schema.type == 'array':
|
124
|
+
self.params.append(
|
125
|
+
ApiParameter(
|
126
|
+
original_name='array',
|
127
|
+
param_location='body',
|
128
|
+
param_schema=schema,
|
129
|
+
description=description,
|
130
|
+
)
|
131
|
+
)
|
132
|
+
else:
|
133
|
+
self.params.append(
|
134
|
+
# Empty name for unnamed body param
|
135
|
+
ApiParameter(
|
136
|
+
original_name='',
|
137
|
+
param_location='body',
|
138
|
+
param_schema=schema,
|
139
|
+
description=description,
|
140
|
+
)
|
141
|
+
)
|
142
|
+
break # Process first mime type only
|
143
|
+
|
144
|
+
def _dedupe_param_names(self):
|
145
|
+
"""Deduplicates parameter names to avoid conflicts."""
|
146
|
+
params_cnt = {}
|
147
|
+
for param in self.params:
|
148
|
+
name = param.py_name
|
149
|
+
if name not in params_cnt:
|
150
|
+
params_cnt[name] = 0
|
151
|
+
else:
|
152
|
+
params_cnt[name] += 1
|
153
|
+
param.py_name = f'{name}_{params_cnt[name] -1}'
|
154
|
+
|
155
|
+
def _process_return_value(self) -> Parameter:
|
156
|
+
"""Returns a Parameter object representing the return type."""
|
157
|
+
responses = self.operation.responses or {}
|
158
|
+
# Default to Any if no 2xx response or if schema is missing
|
159
|
+
return_schema = Schema(type='Any')
|
160
|
+
|
161
|
+
# Take the 20x response with the smallest response code.
|
162
|
+
valid_codes = list(
|
163
|
+
filter(lambda k: k.startswith('2'), list(responses.keys()))
|
164
|
+
)
|
165
|
+
min_20x_status_code = min(valid_codes) if valid_codes else None
|
166
|
+
|
167
|
+
if min_20x_status_code and responses[min_20x_status_code].content:
|
168
|
+
content = responses[min_20x_status_code].content
|
169
|
+
for mime_type in content:
|
170
|
+
if content[mime_type].schema_:
|
171
|
+
return_schema = content[mime_type].schema_
|
172
|
+
break
|
173
|
+
|
174
|
+
self.return_value = ApiParameter(
|
175
|
+
original_name='',
|
176
|
+
param_location='',
|
177
|
+
param_schema=return_schema,
|
178
|
+
)
|
179
|
+
|
180
|
+
def get_function_name(self) -> str:
|
181
|
+
"""Returns the generated function name."""
|
182
|
+
operation_id = self.operation.operationId
|
183
|
+
if not operation_id:
|
184
|
+
raise ValueError('Operation ID is missing')
|
185
|
+
return to_snake_case(operation_id)[:60]
|
186
|
+
|
187
|
+
def get_return_type_hint(self) -> str:
|
188
|
+
"""Returns the return type hint string (like 'str', 'int', etc.)."""
|
189
|
+
return self.return_value.type_hint
|
190
|
+
|
191
|
+
def get_return_type_value(self) -> Any:
|
192
|
+
"""Returns the return type value (like str, int, List[str], etc.)."""
|
193
|
+
return self.return_value.type_value
|
194
|
+
|
195
|
+
def get_parameters(self) -> List[ApiParameter]:
|
196
|
+
"""Returns the list of Parameter objects."""
|
197
|
+
return self.params
|
198
|
+
|
199
|
+
def get_return_value(self) -> ApiParameter:
|
200
|
+
"""Returns the list of Parameter objects."""
|
201
|
+
return self.return_value
|
202
|
+
|
203
|
+
def get_auth_scheme_name(self) -> str:
|
204
|
+
"""Returns the name of the auth scheme for this operation from the spec."""
|
205
|
+
if self.operation.security:
|
206
|
+
scheme_name = list(self.operation.security[0].keys())[0]
|
207
|
+
return scheme_name
|
208
|
+
return ''
|
209
|
+
|
210
|
+
def get_pydoc_string(self) -> str:
|
211
|
+
"""Returns the generated PyDoc string."""
|
212
|
+
pydoc_params = [param.to_pydoc_string() for param in self.params]
|
213
|
+
pydoc_description = (
|
214
|
+
self.operation.summary or self.operation.description or ''
|
215
|
+
)
|
216
|
+
pydoc_return = PydocHelper.generate_return_doc(
|
217
|
+
self.operation.responses or {}
|
218
|
+
)
|
219
|
+
pydoc_arg_list = chr(10).join(
|
220
|
+
f' {param_doc}' for param_doc in pydoc_params
|
221
|
+
)
|
222
|
+
return dedent(f"""
|
223
|
+
\"\"\"{pydoc_description}
|
224
|
+
|
225
|
+
Args:
|
226
|
+
{pydoc_arg_list}
|
227
|
+
|
228
|
+
{pydoc_return}
|
229
|
+
\"\"\"
|
230
|
+
""").strip()
|
231
|
+
|
232
|
+
def get_json_schema(self) -> Dict[str, Any]:
|
233
|
+
"""Returns the JSON schema for the function arguments."""
|
234
|
+
properties = {
|
235
|
+
p.py_name: jsonable_encoder(p.param_schema, exclude_none=True)
|
236
|
+
for p in self.params
|
237
|
+
}
|
238
|
+
return {
|
239
|
+
'properties': properties,
|
240
|
+
'required': [p.py_name for p in self.params],
|
241
|
+
'title': f"{self.operation.operationId or 'unnamed'}_Arguments",
|
242
|
+
'type': 'object',
|
243
|
+
}
|
244
|
+
|
245
|
+
def get_signature_parameters(self) -> List[inspect.Parameter]:
|
246
|
+
"""Returns a list of inspect.Parameter objects for the function."""
|
247
|
+
return [
|
248
|
+
inspect.Parameter(
|
249
|
+
param.py_name,
|
250
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
251
|
+
annotation=param.type_value,
|
252
|
+
)
|
253
|
+
for param in self.params
|
254
|
+
]
|
255
|
+
|
256
|
+
def get_annotations(self) -> Dict[str, Any]:
|
257
|
+
"""Returns a dictionary of parameter annotations for the function."""
|
258
|
+
annotations = {p.py_name: p.type_value for p in self.params}
|
259
|
+
annotations['return'] = self.get_return_type_value()
|
260
|
+
return annotations
|