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.

10 min Free

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”.

Ready
# 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 ← →.

00/09

Variables

Nothing defined yet.

Output

Nothing printed yet.

What to notice

  1. Modes say what you intend. "r" reads (the default), "w" writes and erases any existing file, "a" appends. The tutorial recommends giving encoding="utf-8" so text reads the same on every machine.
  2. The file is closed when the with block ends. f.closed is True on the next line. Using f after that raises ValueError: I/O operation on closed file.
  3. dumps/loads work on strings; dump/load work on files. json.dump(result, f) writes straight into an open file, and json.load(f) reads one back. The trailing s means string.
  4. JSON and Python spell things differently. True becomes true, None becomes null, tuples become lists, and dict keys must be strings. Converting back gives you dicts and lists, never your own classes.
  5. CSV values are always strings. row["amount"] is '40', so you convert with int() or float() before doing arithmetic. DictReader uses the first row as field names; DictWriter with writeheader() does the reverse.
  6. 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.

Check your understanding

1. What does with open("out.json", "w") as f: guarantee?
2. json.dumps({"rain": False}) produces which text?
3. A CSV row read with DictReader has amount set to 40 in the file. What is row["amount"]?