19 Modules and Packages
19.1 The Wall
AI wrote import requests at the top of your script. You ran it and got ModuleNotFoundError: No module named 'requests'. You had no idea whether requests was something you needed to install, something built into Python, or something AI made up entirely.
In another case, AI split your code into three files and used from chatbot.responses import get_response. You did not understand what the dots meant, where Python looked for files, or why it could not find the module you were staring at in your file browser.
This chapter fixes that.
19.2 Thinking Session
19.2.1 Getting Oriented
What is the difference between a module and a package in Python? When AI writes import json versus import requests, one works immediately and the other does not. Why? How do I know which modules come with Python (standard library) and which need to be installed?
Your AI should explain: the standard library (json, os, sys, datetime, random, pathlib) comes with Python. Third-party packages (requests, flask, pandas) need to be installed with pip install. A module is a single .py file. A package is a directory with an __init__.py file containing modules.
19.2.2 Go Deeper
Explain the different ways to import in Python: import module, from module import function, from module import *, and import module as alias. When does AI use each one? Which are considered good practice and which should I avoid?
import module is safest. You always see where things come from (module.function()). from module import function is fine for specific, well-known names. from module import * is dangerous. It pollutes your namespace and you cannot tell where names come from. import module as alias is conventional for some libraries (import numpy as np).
How do I organise my own code into multiple files? If I have a chatbot with separate files for responses, history, and the main loop, how do I import between them? What is __init__.py and why does AI put it in directories?
19.2.3 Challenge It
What is wrong with these imports?
from os import *
import json
from my_project import helper # file exists in same directory
import pandas # never installedLine 1: import * imports everything from os, pollutes namespace with hundreds of names. Line 3: might fail depending on how you run the script, relative imports depend on the project structure and whether you are running as a script or module. Line 4: ModuleNotFoundError if pandas is not installed. AI frequently imports packages it assumes are installed.
19.2.4 What You Should Have Learned
- Standard library vs third-party:
jsonbuilt-in,requestsneedspip install import moduleis preferred overfrom module import *- Packages are directories with
__init__.py pip install package_nameinstalls third-party packagesModuleNotFoundErrormeans the module is not installed or not found- Organise your own code: one concern per file, clear imports
19.3 The Gap
You can now read AI-generated import statements and know immediately whether something needs installation, comes with Python, or is a local file. When AI structures a project with multiple files, you understand how the pieces connect.
In the Building Session, you will split your chatbot into a proper package.
19.4 Building Session
19.4.1 The Spec
Split your chatbot into a package with multiple modules:
chatbot/. The package directorychatbot/__init__.py, package markerchatbot/config.py, constants (BOT_NAME, VERSION, RESPONSES, KEYWORDS)chatbot/responses.py, classify_input() and get_response()chatbot/history.py, load_history() and save_history()chatbot/main.py. The main looprun.py, entry point that imports and runs main()
19.4.2 Prompt It
Restructure my chatbot into a package for v1.9. Create this structure:
chatbot/ init.py (empty or with version) config.py (BOT_NAME, VERSION, RESPONSES dict, KEYWORDS dict) responses.py (classify_input, get_response, imports from config) history.py (load_history, save_history, imports json) main.py (main function, imports from other modules) run.py (entry point: from chatbot.main import main; main())
Show me the import statements for each file and the key functions. Keep the existing features from v1.7.
19.4.3 Read the Code
Your AI will produce something like this:
# chatbot/config.py
BOT_NAME = "PyBot"
VERSION = "1.9"
HISTORY_FILE = "chat_history.json"
RESPONSES = {
"greeting": ["Hello!", "Hi there!"],
"farewell": ["Goodbye!", "See you!"],
"question": ["Good question!", "Let me think..."],
"default": ["Interesting!", "Tell me more."],
}
KEYWORDS = {
"hello": "greeting",
"hi": "greeting",
"bye": "farewell",
"goodbye": "farewell",
}# chatbot/responses.py
import random
from chatbot.config import RESPONSES, KEYWORDS
def classify_input(text):
words = text.lower().split()
for word in words:
if word in KEYWORDS:
return KEYWORDS[word]
if "?" in text:
return "question"
return "default"
def get_response(user_input):
category = classify_input(user_input)
responses = RESPONSES.get(category, RESPONSES["default"])
return random.choice(responses), category == "farewell"# run.py
from chatbot.main import main
if __name__ == "__main__":
main()Each file imports only what it needs. config.py has no imports. It is pure data. responses.py imports from config using the package path from chatbot.config import .... run.py is the entry point, one line. The __init__.py file can be empty; it just tells Python this directory is a package.
19.4.4 Stretch It
Add a chatbot/utils.py module with a debug_log() function and a format_message() function. Import them in main.py. Also add __version__ = "1.9" to __init__.py so users can check import chatbot; print(chatbot.__version__).
19.5 Your Chatbot So Far
- Ch 1-17: Full features with persistence, error handling, debug mode
- Ch 18: Test suite
- Ch 19: Split into a proper package with separate modules
19.6 Quick Reference
# Import styles
import json # full module
from datetime import datetime # specific item
import numpy as np # alias
# Install third-party
# pip install requests
# Package structure
# mypackage/
# __init__.py
# module1.py
# module2.py
# Import from your package
from mypackage.module1 import my_function
# Common standard library
import json # JSON data
import os # file system
import sys # system
import datetime # dates/times
import random # randomness
import pathlib # file paths