Lab 6: Programmatic Execution: Apps and Runners
Goalβ
In this lab, you will move beyond the CLI and trigger your "Support Analyzer" agent from a Python script. You will learn how to wrap your agent in an App container and use an InMemoryRunner to handle multiple independent user sessions.
This will teach you the canonical way to execute an agent as part of a larger Python application (like a web server or a bot).
Step 1: Prepare the Projectβ
Environment setup: this lab modifies the
support_analyzerproject from Module 4, in place -- it's not a fresh project. If you're continuing the course in sequence,cdinto that project (inside youradk-trainingdirectory) and you're all set. If you're starting fresh at this module, you'll need that project first -- Module 4'slab-solution.mdhas the completesupport_analyzercode to recreate it, then come back here. Note thatlab-solution.mdusually only shows the contents ofagent.py; if that's not enough to get a working project (e.g. you still need to scaffold it withuv/adk create), check Module 4'slab.mdfor those setup steps.
-
Navigate to your
adk-training/support_analyzerdirectory:cd /path/to/your/adk-training/support_analyzer -
Create the execution script: In the same directory as your
agent.py, create a new Python file namedmain.py. This is where you will write the code to run your agent.
Python Skeleton (main.py)β
Complete the main.py script by following the comments.
import asyncio
import logging
from dotenv import load_dotenv
# --- Step 1: ADK Imports ---
# TODO: Import App from google.adk.apps
# TODO: Import InMemoryRunner from google.adk.runners
# TODO: Import root_agent from agent.py
from ... import ...
# Optional: Suppress noisy ADK/httpx logs
logging.getLogger("google.adk").setLevel(logging.WARNING)
load_dotenv()
# --- Step 2: Infrastructure Setup ---
# TODO: 1. Create the App instance named "support_app".
app = ...
# TODO: 2. Create the Runner instance using the app.
runner = ...
async def main():
print("--- User A (Alice) ---")
# --- Step 3: Run for Alice ---
# TODO: Use the runner's debug method to send Alice's billing issue:
# "I was overcharged $50". Don't forget the user_id!
events_a = ...
# --- Step 4: Process Events ---
# TODO: Loop through events_a and find the final response.
# Hint: use event.is_final_response()
for event in events_a:
...
print("\n--- User B (Bob) ---")
# --- Step 5: Run for Bob ---
# TODO: Use the SAME runner instance to send Bob's technical issue:
# "My wifi is slow". Use a different user_id.
...
if __name__ == "__main__":
asyncio.run(main())
Step 3: Run the Scriptβ
Once you have completed the script, you can execute it using uv run.
- Run the script from your
support_analyzerdirectory:uv run python main.py
Step 4: Observe the Outputβ
If your script is correct, you will see two distinct interactions printed to your consoleβone for Alice's billing issue and one for Bob's technical issue. Observe how the same Runner managed both interactions correctly using their user_id.
Lab Summaryβ
You have successfully run an agent programmatically using the modern App and Runner architecture. This is the foundation for integrating your agent into any larger Python application.
You have learned to:
- Wrap an agent in an
Appto manage infrastructure concerns. - Instantiate an
InMemoryRunnerfor easy local development. - Use
run_debug()to quickly execute agents and see their output. - Use
user_idto ensure that different users' conversations are isolated from one another.
Self-Reflection Questionsβ
- Why is the
Appclass considered "infrastructure" while theAgentis considered "intelligence"? - What would happen if you didn't provide a
user_idto the runner (or provided the same one for both Alice and Bob)? - In a production web server (like FastAPI), where would you put the code to instantiate the
Runner? Would you put it inside the request handler function or as a global variable? Why?
π Reference Solution Vaultβ
Module 06 Reference Solution Vault
Active Comprehension Gate β’ Zero Guessable URLs β’ Guided Verification