1. Introduction
Overview
In this codelab, you will deploy an ADK agent to Cloud Run as a backend service, and then deploy a gradio frontend for the ADK agent as a second Cloud Run service. This codelab shows how to require authentication to your ADK agent service and make authenticated calls to it from the gradio frontend service.
What you'll learn
- How to deploy an ADK agent to Cloud Run
- How to deploy a gradio app to Cloud Run
- How to make authenticated service-to-service calls in Cloud Run
2. Enable APIs
First, set your Google Cloud project.
gcloud config set project <YOUR_PROJECT_ID>
You can confirm your Google Cloud project by running the following command:
gcloud config get-value project
This codelab requires enabling the following APIs:
gcloud services enable run.googleapis.com \
compute.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
3. Setup and Requirements
In this section, you'll create a couple of service accounts and grant them the appropriate IAM roles. Each cloud run service will have its own Service Account.
First, set environment variables for this codelab that will be used throughout this codelab.
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>
export SERVICE_ACCOUNT_ADK="adk-agent-cr"
export SERVICE_ACCOUNT_ADDRESS_ADK=$SERVICE_ACCOUNT_ADK@$PROJECT_ID.iam.gserviceaccount.com
export SERVICE_ACCOUNT_GRADIO="adk-agent-gradio"
export SERVICE_ACCOUNT_ADDRESS_GRADIO=$SERVICE_ACCOUNT_GRADIO@$PROJECT_ID.iam.gserviceaccount.com
export AGENT_APP_NAME="multi_tool_agent"
Next, create the service account for the ADK agent.
gcloud iam service-accounts create $SERVICE_ACCOUNT_ADK \
--display-name="Service account for adk agent on cloud run"
And grant the ADK service account the "Vertex AI User" role
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_ADK" \
--role="roles/aiplatform.user"
Now, create the service account for the Gradio frontend
gcloud iam service-accounts create $SERVICE_ACCOUNT_GRADIO \
--display-name="Service account for gradio frontend cloud run"
And grant the Gradio frontend the Cloud Run invoker role, which will allow it to call the ADK agent hosted on Cloud Run.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_GRADIO" \
--role="roles/run.invoker"
4. Create an ADK app
In the next step, you'll create the code for the ADK quickstart application.
Note: at the end of the lab, your file structure should look like the following:
- codelab-gradio-adk <-- you'll deploy the ADK agent from here
- gradio-frontend <-- you'll deploy the gradio app from here
- app.py
- requirements.txt
- multi_tool_agent
- __init__.py
- agent.py
- requirements.txt
First, create a directory for the overall codelab
mkdir codelab-gradio-adk
cd codelab-gradio-adk
Now, create a directory for the ADK agent service.
mkdir multi_tool_agent && cd multi_tool_agent
Create a __init__.py file with the following contents:
from . import agent
Create a requirements.txt file:
google-adk
Create a file called agent.py
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent
def get_weather(city: str) -> dict:
"""Retrieves the current weather report for a specified city.
Args:
city (str): The name of the city for which to retrieve the weather report.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
return {
"status": "success",
"report": (
"The weather in New York is sunny with a temperature of 25 degrees"
" Celsius (77 degrees Fahrenheit)."
),
}
else:
return {
"status": "error",
"error_message": f"Weather information for '{city}' is not available.",
}
def get_current_time(city: str) -> dict:
"""Returns the current time in a specified city.
Args:
city (str): The name of the city for which to retrieve the current time.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
tz_identifier = "America/New_York"
else:
return {
"status": "error",
"error_message": (
f"Sorry, I don't have timezone information for {city}."
),
}
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
report = (
f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
)
return {"status": "success", "report": report}
root_agent = Agent(
name="weather_time_agent",
model="gemini-2.5-flash",
description=(
"Agent to answer questions about the time and weather in a city."
),
instruction=(
"You are a helpful agent who can answer user questions about the time and weather in a city."
),
tools=[get_weather, get_current_time],
)
5. Deploy the ADK agent
In this section, you'll deploy the ADK agent to Cloud Run. Then you'll verify the deployment worked using the dev web UI that's provided by ADK. Lastly, you'll require authenticated calls to this service.
Navigate to the parent folder.
NOTE: The ADK agent code must include the multi_tool_agent folder as its root folder.
cd ..
First, create the Cloud Run service:
NOTE: the --with_ui is optional to test with the Dev UI, as shown in an upcoming step:
NOTE: the -- command allows you to pass through command line flags to the underlying gcloud run deploy command.
NOTE: the uvx --from executes a command from the google-adk package. uvx will create a temporary virtual environment, install google-adk into it, run the specified command, and then tear down the environment.
uvx --from google-adk \
adk deploy cloud_run \
--project=$PROJECT_ID \
--region=$REGION \
--service_name=adk-agent-cr \
--with_ui \
./multi_tool_agent \
-- \
--service-account=$SERVICE_ACCOUNT_ADDRESS_ADK \
--allow-unauthenticated
Next, save the URL as an env var that you will use in the second part of this codelab
AGENT_SERVICE_URL=$(gcloud run services describe adk-agent-cr --region $REGION --format 'value(status.url)')
Now, try the agent
Open the service URL in your web browser and ask, tell me about the weather in new york. You should see a response similar to "The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit)."
Lastly, Secure the agent
Let's now secure access to the agent. In the next section, you'll deploy a Cloud Run service that makes an authenticated call to this backend service.
gcloud run services remove-iam-policy-binding adk-agent-cr \
--member="allUsers" \
--role="roles/run.invoker" \
--region=$REGION
6. Deploy a gradio front-end
In this step, you'll create a gradio frontend for your ADK agent
Note: You can have the gradio app in the same service as the ADK agent. This codelab provides 2 separate services to show how to make authenticated service to service calls in Cloud Run.
First, create an app alongside the multi_tool_agent folder
mkdir gradio-frontend && cd gradio-frontend
Next, create a requirements.txt file that contains the following
gradio
requests
google-auth
Now, create an app.py file
import gradio as gr
import requests
import json
import uuid
import os
import google.auth.transport.requests
import google.oauth2.id_token
# https://weather-time-service2-392295011265.us-west4.run.app
BASE_URL = os.environ.get("AGENT_SERVICE_URL")
# multi_tool_agent
APP_NAME = os.environ.get("AGENT_APP_NAME")
# Generate a unique user ID for each session of the Gradio app
USER_ID = f"gradio-user-{uuid.uuid4()}"
# API Endpoints
CREATE_SESSION_URL = f"{BASE_URL}/apps/{APP_NAME}/users/{USER_ID}/sessions"
RUN_SSE_URL = f"{BASE_URL}/run_sse"
def get_id_token():
"""Get an ID token to authenticate with the other Cloud Run service."""
audience = BASE_URL
request = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
return id_token
def create_session() -> str | None:
"""Creates a new session and returns the session ID."""
try:
id_token = get_id_token()
headers = {"Authorization": f"Bearer {id_token}"}
response = requests.post(CREATE_SESSION_URL, headers=headers)
response.raise_for_status()
return response.json().get("id")
except Exception as e:
print(f"Error creating session: {e}")
return None
def query_agent(prompt: str):
"""Sends a prompt to the agent and returns the streamed response."""
session_id = create_session()
if not session_id:
return "Error: Could not create a session."
id_token = get_id_token()
headers = {
"Content-Type": "application/json",
"Accept": "text/event-stream",
"Authorization": f"Bearer {id_token}",
}
payload = {
"app_name": APP_NAME,
"user_id": USER_ID,
"session_id": session_id,
"new_message": {"role": "user", "parts": [{"text": prompt}]},
"streaming": True
}
full_response = ""
try:
with requests.post(RUN_SSE_URL, headers=headers, json=payload, stream=True) as response:
response.raise_for_status()
for chunk in response.iter_lines():
if chunk and chunk.decode('utf-8').startswith('data:'):
json_data = chunk.decode('utf-8')[len('data:'):].strip()
try:
data = json.loads(json_data)
text = data.get("content", {}).get("parts", [{}])[0].get("text", "")
if text:
full_response = text
except json.JSONDecodeError:
pass # Ignore chunks that are not valid JSON
return full_response
except requests.exceptions.RequestException as e:
return f"An error occurred: {e}"
iface = gr.Interface(
fn=query_agent,
inputs=gr.Textbox(lines=2, placeholder="e.g., What's the weather in new york?"),
outputs="text",
title="Weather and Time Agent",
description="Ask a question about the weather or time in a specific location.",
)
if __name__ == "__main__":
iface.launch()
7. Deploy and test your gradio app
In this step, you'll deploy the front end gradio app to Cloud Run.
Make sure you are in the gradio app directory.
pwd
You should see codelab-gradio-adk/gradio-frontend
Now deploy your gradio app.
Note: although this gradio frontend service is a publicly available website, the backend service requires authentication. To illustrate why you might want to do this, you could add user authentication (e.g. Firebase Auth) to this frontend service and then only allow users who are signed in to make calls to the backend service.
gcloud run deploy my-adk-gradio-frontend \
--source . \
--region $REGION \
--allow-unauthenticated \
--set-env-vars AGENT_SERVICE_URL=$AGENT_SERVICE_URL,AGENT_APP_NAME=$AGENT_APP_NAME \
--service-account=$SERVICE_ACCOUNT_ADDRESS_GRADIO
once deployed, ask what's the weather in new york? and you should get a response similar to The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit).
8. Congratulations!
Congratulations for completing the codelab!
We recommend reviewing the documentation on hosting AI apps and agents documentation.
What we've covered
- How to deploy an ADK agent to Cloud Run
- How to deploy a gradio app to Cloud Run
- How to make authenticated service-to-service calls in Cloud Run
9. Clean up
To avoid inadvertent charges, for example, if the Cloud Run services are inadvertently invoked more times than your monthly Cloud Run invokement allocation in the free tier, you can delete the Cloud Run service you created in Step 6.
To delete the Cloud Run services, go to the Cloud Run Cloud Console at https://console.cloud.google.com/run and delete the my-adk-gradio-frontend and adk-agent-cr services.
To delete the entire project, go to Manage Resources, select the project you created in Step 2, and choose Delete. If you delete the project, you'll need to change projects in your Cloud SDK. You can view the list of all available projects by running gcloud projects list.