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.

10 min Free

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.

Modules, packages and importsReady
# 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 ← →.

00/11

Variables

Nothing defined yet.

Output

Nothing printed yet.

What to notice

  1. Importing runs the file. Every top-level statement in tools.py executes on the first import tools, including that print. Keep modules to definitions; put actions under the __main__ guard.
  2. Only once. The second import tools prints nothing: Python caches loaded modules in sys.modules. Editing tools.py while a program runs changes nothing until you restart it.
  3. Two ways to import. import tools gives you tools.get_price; from tools import get_price gives you get_price directly. Both refer to the same function. Avoid from tools import *: it hides where names came from.
  4. __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.
  5. Don’t shadow the standard library. A file of yours called json.py or random.py sits first in sys.path and 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?

Check your understanding

1. agent.py imports tools twice. How many times does the print at the bottom of tools.py run?
2. Where does Python look first for a module named tools?
3. Inside an imported file called agent.py, what is __name__?