Skip to content

Commit 8d1b775

Browse files
amitmodakAmit Modak
andauthored
feat: add ADK agent samples Parameter Manager (#14103)
Co-authored-by: Amit Modak <amitmodak@google.com>
1 parent ddf7dcb commit 8d1b775

11 files changed

Lines changed: 504 additions & 0 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# ADK Parameter Manager Samples
2+
3+
This directory contains samples demonstrating how to use the Agent Development Kit (ADK) with Google Cloud Parameter Manager.
4+
5+
## Folders
6+
* `agent_global`: Sample for accessing parameters from a global Parameter Manager instance.
7+
* `agent_regional`: Sample for accessing parameters from a regional Parameter Manager endpoint.
8+
9+
## Prerequisites
10+
11+
1. **Create and activate a virtual environment**:
12+
```bash
13+
python3 -m venv .venv
14+
source .venv/bin/activate
15+
```
16+
17+
2. **Set up Application Default Credentials**:
18+
```bash
19+
gcloud auth application-default login
20+
```
21+
22+
3. **Install dependencies**:
23+
You need to install dependencies for the specific sample or test you want to run.
24+
25+
For global agent samples and tests:
26+
```bash
27+
pip install -r agent_global/requirements.txt
28+
```
29+
30+
For regional agent samples and tests:
31+
```bash
32+
pip install -r agent_regional/requirements.txt
33+
```
34+
35+
4. **Set up environment variables**:
36+
* `GOOGLE_CLOUD_PROJECT`: Your Google Cloud Project ID. (Required for both samples and tests).
37+
38+
The following environment variables are **only required when running the samples manually**. The tests will generate and use their own temporary parameters automatically.
39+
40+
* `ADK_TEST_PARAMETER_ID`: The ID of the parameter to access.
41+
* `ADK_TEST_PARAMETER_VERSION` (Optional): The version of the parameter (defaults to `latest`).
42+
* `GOOGLE_CLOUD_PROJECT_LOCATION` (Required for regional samples): The region where the parameter is located (e.g., `us-central1`).
43+
44+
## Running the Samples
45+
46+
The samples are designed to be run from this directory (`snippets-adk`) using the `adk run` command.
47+
48+
### Global Parameter Manager Agent
49+
50+
1. **Create a `.env` file** alongside `agent.py` in the `agent_global` directory:
51+
```env
52+
GOOGLE_GENAI_USE_VERTEXAI=1
53+
GOOGLE_CLOUD_PROJECT=your-project-id
54+
GOOGLE_CLOUD_LOCATION=us-central1
55+
```
56+
*Note: Replace `your-project-id` with your GCP project ID.*
57+
58+
2. **Run the agent**:
59+
```bash
60+
export GOOGLE_CLOUD_PROJECT="your-project-id"
61+
export ADK_TEST_PARAMETER_ID="your-parameter-id"
62+
adk run agent_global
63+
```
64+
65+
### Regional Parameter Manager Agent
66+
67+
1. **Create a `.env` file** alongside `agent.py` in the `agent_regional` directory:
68+
```env
69+
GOOGLE_GENAI_USE_VERTEXAI=1
70+
GOOGLE_CLOUD_PROJECT=your-project-id
71+
GOOGLE_CLOUD_LOCATION=us-central1
72+
```
73+
*Note: Replace `your-project-id` with your GCP project ID.*
74+
75+
2. **Run the agent**:
76+
```bash
77+
export GOOGLE_CLOUD_PROJECT="your-project-id"
78+
export GOOGLE_CLOUD_PROJECT_LOCATION="us-central1"
79+
export ADK_TEST_PARAMETER_ID="your-parameter-id"
80+
adk run agent_regional
81+
```
82+
83+
## Running the Tests
84+
85+
The tests are located within the specific agent folders and run the samples using `adk run`.
86+
87+
To run tests for the global agent:
88+
```bash
89+
pip install -r agent_global/requirements.txt
90+
pip install -r agent_global/requirements-test.txt
91+
pytest agent_global/snippets_adk_test.py
92+
```
93+
94+
To run tests for the regional agent:
95+
```bash
96+
pip install -r agent_regional/requirements.txt
97+
pip install -r agent_regional/requirements-test.txt
98+
pytest agent_regional/snippets_adk_test.py
99+
```
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2026 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""
17+
ADK agent for accessing parameters from global Parameter Manager.
18+
"""
19+
20+
import os
21+
22+
from google.adk import Agent
23+
from google.adk.integrations.parameter_manager.parameter_client import ParameterManagerClient
24+
25+
# Fetch parameter from global Parameter Manager
26+
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
27+
parameter_id = os.environ.get("ADK_TEST_PARAMETER_ID")
28+
parameter_version = os.environ.get("ADK_TEST_PARAMETER_VERSION", "latest")
29+
30+
if not project_id or not parameter_id:
31+
raise ValueError("GOOGLE_CLOUD_PROJECT and ADK_TEST_PARAMETER_ID environment variables must be set.")
32+
33+
resource_name = f"projects/{project_id}/locations/global/parameters/{parameter_id}/versions/{parameter_version}"
34+
35+
print("Fetching parameter from global Parameter Manager...")
36+
# Initialize Parameter Manager Client
37+
client = ParameterManagerClient()
38+
39+
# Fetch parameter
40+
try:
41+
parameter_payload = client.get_parameter(resource_name)
42+
print("Successfully fetched parameter.")
43+
except Exception as e:
44+
print(f"Error fetching parameter: {e}")
45+
raise e
46+
47+
# Initialize Agent
48+
root_agent = Agent(
49+
model='gemini-2.5-flash',
50+
name='root_agent',
51+
description='A helpful assistant for user questions.',
52+
instruction='Answer user questions to the best of your knowledge',
53+
)
54+
55+
print("Agent initialized successfully.")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2026 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+
# Default TEST_CONFIG_OVERRIDE for python repos.
16+
17+
TEST_CONFIG_OVERRIDE = {
18+
# You can opt out from the test for specific Python versions.
19+
"ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"],
20+
# Old samples are opted out of enforcing Python type hints
21+
# All new samples should feature them
22+
"enforce_type_hints": True,
23+
# An envvar key for determining the project id to use.
24+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
25+
# A dictionary you want to inject into your test.
26+
"envs": {},
27+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==8.2.0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-adk[extensions]>=1.30
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import subprocess
17+
import time
18+
from typing import Iterator
19+
import uuid
20+
21+
from google.api_core import exceptions
22+
from google.cloud import parametermanager_v1
23+
import pytest
24+
25+
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
26+
PARENT_DIR = os.path.dirname(CURRENT_DIR)
27+
28+
29+
@pytest.fixture()
30+
def client() -> parametermanager_v1.ParameterManagerClient:
31+
return parametermanager_v1.ParameterManagerClient()
32+
33+
34+
@pytest.fixture()
35+
def project_id() -> str:
36+
return os.environ["GOOGLE_CLOUD_PROJECT"]
37+
38+
39+
@pytest.fixture()
40+
def parameter_id(
41+
client: parametermanager_v1.ParameterManagerClient, project_id: str
42+
) -> Iterator[str]:
43+
parameter_id = f"python-adk-test-{uuid.uuid4()}"
44+
yield parameter_id
45+
46+
# Teardown: delete the version then the parameter
47+
version_path = client.parameter_version_path(project_id, "global", parameter_id, "1")
48+
parameter_path = client.parameter_path(project_id, "global", parameter_id)
49+
50+
print("Deleting parameter version 1...")
51+
try:
52+
time.sleep(1)
53+
client.delete_parameter_version(request={"name": version_path})
54+
except exceptions.NotFound:
55+
pass
56+
57+
print(f"Deleting parameter {parameter_id}...")
58+
try:
59+
time.sleep(2)
60+
client.delete_parameter(name=parameter_path)
61+
except exceptions.NotFound:
62+
pass
63+
64+
65+
def test_agent_global(
66+
client: parametermanager_v1.ParameterManagerClient, project_id: str, parameter_id: str
67+
) -> None:
68+
# Create the parameter
69+
parent = client.common_location_path(project_id, "global")
70+
print(f"Creating parameter {parameter_id}...")
71+
client.create_parameter(
72+
request={
73+
"parent": parent,
74+
"parameter_id": parameter_id,
75+
}
76+
)
77+
78+
# Add a version
79+
parameter_path = client.parameter_path(project_id, "global", parameter_id)
80+
print(f"Adding version to {parameter_id}...")
81+
client.create_parameter_version(
82+
request={
83+
"parent": parameter_path,
84+
"parameter_version_id": "1",
85+
"parameter_version": {
86+
"payload": {"data": b"test-payload"}
87+
},
88+
}
89+
)
90+
91+
# Set environment variables required by the agent
92+
os.environ["ADK_TEST_PARAMETER_ID"] = parameter_id
93+
os.environ["ADK_TEST_PARAMETER_VERSION"] = "1"
94+
95+
print(f"Running adk run agent_global from {PARENT_DIR}...")
96+
# Run the sample using adk run
97+
result = subprocess.run(
98+
["adk", "run", "agent_global"],
99+
input="exit\n",
100+
capture_output=True,
101+
text=True,
102+
cwd=PARENT_DIR,
103+
)
104+
105+
print("STDOUT:")
106+
print(result.stdout)
107+
print("STDERR:")
108+
print(result.stderr)
109+
110+
assert result.returncode == 0
111+
assert "Successfully fetched parameter" in result.stdout
112+
assert "Agent initialized successfully" in result.stdout
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2026 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""
17+
ADK agent for accessing parameters from regional Parameter Manager.
18+
"""
19+
20+
import os
21+
22+
from google.adk import Agent
23+
from google.adk.integrations.parameter_manager.parameter_client import ParameterManagerClient
24+
25+
# Fetch parameter from regional Parameter Manager
26+
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
27+
location = os.environ.get("GOOGLE_CLOUD_PROJECT_LOCATION")
28+
parameter_id = os.environ.get("ADK_TEST_PARAMETER_ID")
29+
parameter_version = os.environ.get("ADK_TEST_PARAMETER_VERSION", "latest")
30+
31+
if not project_id or not location or not parameter_id:
32+
raise ValueError("GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_LOCATION, and ADK_TEST_PARAMETER_ID environment variables must be set.")
33+
34+
resource_name = f"projects/{project_id}/locations/{location}/parameters/{parameter_id}/versions/{parameter_version}"
35+
36+
print(f"Fetching parameter from regional Parameter Manager ({location})...")
37+
# Initialize Parameter Manager Client (Regional)
38+
client = ParameterManagerClient(location=location)
39+
40+
# Fetch parameter
41+
try:
42+
parameter_payload = client.get_parameter(resource_name)
43+
print("Successfully fetched parameter.")
44+
except Exception as e:
45+
print(f"Error fetching parameter: {e}")
46+
raise e
47+
48+
# Initialize Agent
49+
root_agent = Agent(
50+
model='gemini-2.5-flash',
51+
name='root_agent',
52+
description='A helpful assistant for user questions.',
53+
instruction='Answer user questions to the best of your knowledge',
54+
)
55+
56+
print("Agent initialized successfully.")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2026 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+
# Default TEST_CONFIG_OVERRIDE for python repos.
16+
17+
TEST_CONFIG_OVERRIDE = {
18+
# You can opt out from the test for specific Python versions.
19+
"ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"],
20+
# Old samples are opted out of enforcing Python type hints
21+
# All new samples should feature them
22+
"enforce_type_hints": True,
23+
# An envvar key for determining the project id to use.
24+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
25+
# A dictionary you want to inject into your test.
26+
"envs": {},
27+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==8.2.0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-adk[extensions]>=1.30

0 commit comments

Comments
 (0)