Files, JSON and CSV
Read and write files safely with "with", turn a tool result into JSON text and back, and read a CSV file row by row with DictReader. The program writes two small files to /tmp.
Data has to leave your program eventually: a tool result saved for later, a list of orders someone exported from a spreadsheet, an evaluation file for an agent. Python handles the two formats you will meet most, JSON and CSV, with modules in the standard library, and handles the file itself with open().
The habit to copy is with open(path) as f:. The with statement makes the file a context manager: when the indented block ends, for any reason including an error, the file is closed and its contents are flushed to disk. You never write f.close() and never leak a file handle.
JSON is the language of tool calls and API responses. json.dumps(obj) turns a dict or list into JSON text; json.loads(text) turns it back, and types survive the trip: 31 stays an int, False becomes false and comes back as False. CSV is just lines of comma-separated text, so every value you read from it is a string until you convert it.
Press Run for the JSON round trip, then switch Try it to “CSV with DictReader”.
# Save a tool result as JSON, then total up orders from a CSV file.
import csv
import json
result = {"status": "success", "city": "Chennai", "temp_c": 31, "rain": False}
text = json.dumps(result) # Python dict -> JSON string
print(text)
with open("/tmp/tool_result.json", "w", encoding="utf-8") as f:
f.write(text) # the file is closed when the block ends
print("closed?", f.closed)
with open("/tmp/tool_result.json", encoding="utf-8") as f:
loaded = json.loads(f.read()) # JSON string -> Python dict
print(loaded["temp_c"] + 1, loaded["rain"])
with open("/tmp/orders.csv", "w", newline="", encoding="utf-8") as f:
f.write("order_id,item,amount\n1042,idli,40\n1043,filter coffee,25\n")
total = 0
with open("/tmp/orders.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
print(row)
total += int(row["amount"]) # CSV values are always strings
print("Total:", total)Press Play to run the program line by line, or step with ← →.
Variables
Nothing defined yet.
Output
Nothing printed yet.
What to notice
- Modes say what you intend.
"r"reads (the default),"w"writes and erases any existing file,"a"appends. The tutorial recommends givingencoding="utf-8"so text reads the same on every machine. - The file is closed when the
withblock ends.f.closedisTrueon the next line. Usingfafter that raisesValueError: I/O operation on closed file. dumps/loadswork on strings;dump/loadwork on files.json.dump(result, f)writes straight into an open file, andjson.load(f)reads one back. The trailingsmeans string.- JSON and Python spell things differently.
Truebecomestrue,Nonebecomesnull, tuples become lists, and dict keys must be strings. Converting back gives you dicts and lists, never your own classes. - CSV values are always strings.
row["amount"]is'40', so you convert withint()orfloat()before doing arithmetic.DictReaderuses the first row as field names;DictWriterwithwriteheader()does the reverse. - Open CSV files with
newline="". The csv docs ask for it so the module can handle line endings itself; without it you can get blank lines on Windows.
Why this matters for AI work
Every tool result an agent produces becomes JSON before the model sees it, and every structured reply comes back as JSON text that something has to loads. Evaluation sets, session exports and logs are JSON files; test data and reports are often CSV. When a tool returns a dict with a datetime or a custom object inside, json.dumps raises TypeError, which is why tool results stick to strings, numbers, bools, lists and dicts. Knowing where the string ends and the Python object begins saves hours of debugging.