Modules, packages and imports
Every .py file is a module. See how import finds a file sitting next to your script, why a module runs only once, what __name__ == "__main__" means, and how an ADK agent folder is laid out.
A module is simply a Python file. tools.py is a module called tools. When another file says import tools, Python finds the file, runs it from top to bottom once, and gives you its functions and variables under the name tools. That is how a project grows past one file without copying code around.
Python looks for a module in a fixed order: built-in modules first, then the directories in sys.path. The first entry in sys.path is the folder that contains the script you ran, which is why a file next to your script can be imported by its bare name. After that come the standard library and your installed packages (the site-packages folder inside your virtual environment).
A package is a folder of modules with an __init__.py file in it. The file can be empty; its presence tells Python to treat the folder as a package, so you can write import my_agent.agent.
The trace runs agent.py, which imports the file below. The player shows one file at a time, so here is tools.py, the module being imported:
# tools.py: functions an agent can call. No agent code lives here.
MENU = {"idli": 40, "vada": 30, "filter coffee": 25}
def get_price(item: str) -> dict:
"""Returns the price of one menu item in rupees."""
if item not in MENU:
return {"status": "error", "error_message": f"{item} is not on the menu"}
return {"status": "success", "item": item, "price": MENU[item]}
def list_items() -> list[str]:
"""Returns every item on the menu."""
return list(MENU)
print("tools.py loaded as", __name__)
Press Run and watch the Output panel: the first line printed comes from tools.py, not from the file you ran. Run it yourself with python3 agent.py from inside the folder that holds both files.
# agent.py: the entry point. It imports tools.py instead of copying it.
import json
import tools
from tools import get_price
print("agent.py running as", __name__)
print(tools.list_items())
print(get_price("vada"))
print(tools.get_price("biryani"))
print(json.dumps(tools.MENU))
import tools # a second import prints nothing: the module is cached
if __name__ == "__main__":
print("Started directly, not imported.")Press Play to run the program line by line, or step with ← →.
Variables
Nothing defined yet.
Output
Nothing printed yet.
What to notice
- Importing runs the file. Every top-level statement in
tools.pyexecutes on the firstimport tools, including thatprint. Keep modules to definitions; put actions under the__main__guard. - Only once. The second
import toolsprints nothing: Python caches loaded modules insys.modules. Editingtools.pywhile a program runs changes nothing until you restart it. - Two ways to import.
import toolsgives youtools.get_price;from tools import get_pricegives youget_pricedirectly. Both refer to the same function. Avoidfrom tools import *: it hides where names came from. __name__tells a file how it was started. It is"__main__"in the file you ran and the module’s name everywhere else.if __name__ == "__main__":is where command-line behaviour goes, so importing the file stays side-effect free.- Don’t shadow the standard library. A file of yours called
json.pyorrandom.pysits first insys.pathand will be imported instead of the real one. The confusing errors that follow are a rite of passage; now you can skip it.
Why this matters for AI work
An ADK agent is a package. The Python quickstart’s adk create my_agent produces this layout, and adk run my_agent or adk web must be started from the parent folder, so that my_agent is importable:
my_agent/
__init__.py # makes the folder a package
agent.py # defines root_agent
.env # API keys, never committed
ADK imports my_agent.agent and looks for a variable called root_agent in it. Your tools live in agent.py or in sibling modules that agent.py imports, exactly like tools.py here. When an import fails in an agent project, the question is always the same: which folder is first in sys.path, and does the file you want sit under it?