The problem: Values in memory normally disappear when Python stops, but AI applications need documents, datasets, settings, logs, cached embeddings, and evaluation results to survive. They must also exchange structured data, commonly as JSON.
What you will learn: You will follow data between Python objects and stored bytes using safe file handling, paths, UTF-8 text, CSV, JSON, and JSONL. You will also separate three jobs that are often confused: reading bytes, parsing a format, and validating what the data means.
1. File Handling
A Python variable lives in memory and normally disappears when the process ends. A file stores bytes on a device so another runโor another programโcan use the information later.
Python object in memory
โ encode or serialize
bytes stored in a file
โ read, decode, or parse
new Python object in memory
Plain text needs an encoding such as UTF-8. JSON and CSV add rules for representing structured values. Reading a file does not prove its content is valid or safe, so parsing and validation are separate jobs.
Memory That Survives the Program
Reading and writing files lets your program persist data beyond a single run โ and load in data (documents, datasets) that already exists.
Picture a File as Stored Bytes
A file is a notebook page: you can open it, read whatโs written, add new lines, or start a fresh page.
Why Programs Need Persistent Data
Variables disappear the moment your program ends. Files let data survive between runs โ a document you want to process, a log you want to review later, results you want to save.
2. Reading Files
Syntax
with open("filename.txt", "r") as f:
content = f.read()
Example
# Assume notes.txt already exists with some text in it
with open("notes.txt", "w") as f:
f.write("Python is a great language for building AI applications.\n")
f.write("Retrieval-Augmented Generation combines search with generation.\n")
with open("notes.txt", "r") as f:
content = f.read()
print(content)
Expected Output:
Python is a great language for building AI applications.
Retrieval-Augmented Generation combines search with generation.
How It Works
open(filename, mode)opens a file."r"= read,"w"= write (overwrites),"a"= append.with ... as f:is a context manager (youโll learn the general concept in Module 10) โ it automatically closes the file when youโre done, even if an error occurs. Always prefer this over manually callingf.close().f.read()returns the entire fileโs contents as one string.
โ ๏ธ Common Beginner Mistake: Forgetting
withand manually managingopen()/close()โ if an error happens between them, the file never gets closed properly, which can corrupt data or leak file handles. Always usewith.
Reading line by line
with open("notes.txt", "r") as f:
for line in f:
print("Line:", line.strip())
Expected Output:
Line: Python is a great language for building AI applications.
Line: Retrieval-Augmented Generation combines search with generation.
๐ค How Is This Used in AI? Loading a document into memory before cleaning, chunking, and embedding it โ the very first step of a RAG ingestion pipeline.
3. Writing Files
summary = "Python is essential for AI development."
with open("summary.txt", "w") as f:
f.write(summary)
๐ค How Is This Used in AI? Saving a modelโs generated output, saving processed/cleaned text before embedding, or writing evaluation results to disk for later review.
4. Appending Files
with open("log.txt", "a") as f:
f.write("Request processed successfully.\n")
๐ง Intuition: "w" starts a fresh page every time (erasing what was
there); "a" keeps adding to the bottom of the existing page.
๐ค How Is This Used in AI? Logging every request an AI service handles โ you want each new log entry added, never overwriting the ones before it.
โ ๏ธ Common Beginner Mistake: Using
"w"when you meant"a"โ silently erasing an entire log file every time your program runs is a very common, very avoidable bug.
5. Working with Paths
from pathlib import Path
data_folder = Path("data")
file_path = data_folder / "documents" / "notes.txt"
print(file_path)
print(file_path.name)
print(file_path.suffix)
Expected Output:
data/documents/notes.txt
notes.txt
.txt
๐ง Intuition: pathlib.Path treats file paths as objects you can
combine with /, instead of fragile string concatenation that behaves
differently on Windows vs. Mac/Linux.
๐ค How Is This Used in AI? Locating a folder of documents to ingest, or
building the output path for a saved embeddings file โ pathlib is the
modern, reliable standard for this in real projects.
6. CSV Files
What Is It?
CSV (Comma-Separated Values) is a simple, common format for tabular data โ rows and columns, like a spreadsheet, stored as plain text.
import csv
# Writing a CSV of evaluation results
rows = [
{"question": "What is Python?", "score": 0.9},
{"question": "What is RAG?", "score": 0.85},
]
with open("results.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["question", "score"])
writer.writeheader()
writer.writerows(rows)
# Reading it back
with open("results.csv", "r") as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
Expected Output:
{'question': 'What is Python?', 'score': '0.9'}
{'question': 'What is RAG?', 'score': '0.85'}
โ ๏ธ Note: Everything read from a CSV arrives as a string โ notice
'score': '0.9'has quotes. Youโd needfloat(row["score"])to use it as an actual number (recall Module 1โs type conversion).
๐ค How Is This Used in AI? Storing model evaluation results, labeled training examples, or benchmark datasets โ CSV is still extremely common for tabular AI data, especially before it gets loaded into Pandas (Module 9).
7. JSON
What Is It?
JSON (JavaScript Object Notation) is a text format for structured data built from the exact same shapes as Python dicts and lists โ which is why it maps so cleanly onto Python.
{
"model": "gpt-4o-mini",
"temperature": 0.7,
"messages": [{ "role": "user", "content": "Hello" }]
}
Python converts dictionaries and lists to and from JSON using the standard library json module:
graph LR
subgraph Python Memory
dict["Python Dict / List"]
end
subgraph Disk or Network API
jsonStr["JSON String (raw text)"]
end
dict -->|"json.dumps() / json.dump()"| jsonStr
jsonStr -->|"json.loads() / json.load()"| dict
๐ง Intuition
JSON is the universal shipping format for structured data across the internet โ nearly every API (including every LLM API) sends and receives JSON.
8. Reading JSON
import json
json_text = '{"model": "gpt-4o-mini", "temperature": 0.7, "messages": [{"role": "user", "content": "Hello"}]}'
data = json.loads(json_text) # JSON string -> Python dict
print(data["model"])
print(data["messages"][0]["content"])
print(type(data))
Expected Output:
gpt-4o-mini
Hello
<class 'dict'>
Reading from a .json file works the same way, using json.load(f)
(no โsโ) on an open file object:
with open("config.json", "r") as f:
config = json.load(f)
[!IMPORTANT] Production Alert: Dealing with Markdown JSON Fences from LLMs In production RAG and agent architectures, you will often ask an LLM to generate output formatted strictly as JSON. However, LLMs have a strong habit of wrapping their JSON outputs inside markdown code blocks:
```json { "action": "search", "query": "vector databases" } ```If you feed this raw text directly to
json.loads(), Python will crash with ajson.JSONDecodeErrorbecause standard JSON parsers do not recognize markdown fences (```jsonand```) as valid JSON.To handle this defensively in production, you should strip the markdown fences before calling
loads():raw_response = """```json {"action": "search", "query": "vector databases"} ```""" # Clean up markdown fences if present clean_json_text = raw_response.strip() if clean_json_text.startswith("```json"): clean_json_text = clean_json_text[7:] if clean_json_text.endswith("```"): clean_json_text = clean_json_text[:-3] clean_json_text = clean_json_text.strip() data = json.loads(clean_json_text) print(data["query"]) # 'vector databases'
9. Writing JSON
result = {
"question": "What is RAG?",
"answer": "RAG combines retrieval with generation.",
"sources": ["doc1.txt", "doc2.txt"],
"confidence": 0.87
}
json_string = json.dumps(result, indent=2) # Python dict -> JSON string
print(json_string)
with open("result.json", "w") as f:
json.dump(result, f, indent=2) # write directly to a file
Expected Output:
{
"question": "What is RAG?",
"answer": "RAG combines retrieval with generation.",
"sources": [
"doc1.txt",
"doc2.txt"
],
"confidence": 0.87
}
๐ง Intuition: loads/dumps work with strings; load/dump
(no โsโ) work directly with open files. indent=2 just makes the
output human-readable.
๐ก JSONLines (JSONL) for AI Datasets & Fine-Tuning
When preparing datasets for fine-tuning (like OpenAI fine-tuning datasets) or when saving massive streams of logs, you will use JSONLines (.jsonl) instead of a single massive JSON array.
In a JSONLines file, every single line is a self-contained, valid JSON object, separated by a newline character (\n). This allows you to stream and read files line-by-line without loading a massive 10GB JSON array into RAM at once.
Writing a .jsonl file:
import json
dataset = [
{"messages": [{"role": "user", "content": "Hi"}, {"role": "assistant", "content": "Hello"}]},
{"messages": [{"role": "user", "content": "Solve 2+2"}, {"role": "assistant", "content": "4"}]},
]
with open("dataset.jsonl", "w") as f:
for item in dataset:
f.write(json.dumps(item) + "\n")
Reading a .jsonl file:
with open("dataset.jsonl", "r") as f:
for line in f:
item = json.loads(line.strip())
print(item["messages"][0]["content"])
10. JSON in AI APIs
This is the payoff โ every LLM API call is built from exactly what you just learned:
import json
# What you SEND to an LLM API is built as a Python dict, then becomes JSON
request_payload = {
"model": "gpt-4o-mini",
"temperature": 0.7,
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is retrieval-augmented generation?"}
]
}
request_json = json.dumps(request_payload)
print(request_json[:80], "...")
# What you RECEIVE back is JSON text, parsed into a Python dict
response_json = '''
{
"id": "msg_01",
"model": "gpt-4o-mini",
"content": [{"type": "text", "text": "RAG combines search with generation."}],
"usage": {"input_tokens": 20, "output_tokens": 8}
}
'''
response = json.loads(response_json)
answer = response["content"][0]["text"]
print(answer)
Expected Output:
{"model": "gpt-4o-mini", "temperature": 0.7, "messages": [{"role" ...
RAG combines search with generation.
๐ค This is what happens, almost line for line, inside every AI SDK you will ever call: build a dict โ convert to JSON โ send over HTTP โ receive JSON back โ parse into a dict โ pull out the fields you need.
11. Processing Structured Data
Combining files + JSON โ a realistic small pipeline:
import json
documents = [
{"text": "Python is used heavily in AI development.", "source": "notes.txt"},
{"text": "RAG improves LLM answers with retrieved context.", "source": "notes.txt"},
]
# Save processed documents as a JSON dataset, ready for embedding later
with open("processed_docs.json", "w") as f:
json.dump(documents, f, indent=2)
# Load them back for the next pipeline stage
with open("processed_docs.json", "r") as f:
loaded_docs = json.load(f)
for doc in loaded_docs:
print(f"[{doc['source']}] {doc['text']}")
Expected Output:
[notes.txt] Python is used heavily in AI development.
[notes.txt] RAG improves LLM answers with retrieved context.
๐ค Saving intermediate results as JSON between pipeline stages (ingestion โ cleaning โ chunking โ embedding) is standard practice โ it lets you inspect, debug, or resume a pipeline without redoing expensive earlier steps.
Text Encoding: How Characters Become Bytes
A text file ultimately stores numbers called bytes. An encoding is the rule that maps those bytes to characters. UTF-8 can represent English, Hindi, emoji, and many other writing systems, so state it explicitly when practical:
from pathlib import Path
path = Path("notes.txt")
path.write_text("Hello เคจเคฎเคธเฅเคคเฅ ๐", encoding="utf-8")
text = path.read_text(encoding="utf-8")
Using the wrong encoding can produce strange characters or an error. For a very large file, process one line at a time instead of loading the entire file into memory.
Safe Writes and Data Formats
If a program crashes halfway through overwriting an important file, the file may be incomplete. Production systems commonly write the complete new content to a temporary file and then replace the destination in one final operation.
Use JSON for one structured object or a manageable array. Use JSONL when each line is an independent record; a training pipeline can then stream one example at a time and can often recover more easily from one malformed line.
Module Summary
You can now read and write text files safely with with open(...),
understand file modes (r/w/a), build reliable paths with pathlib,
read and write CSV tabular data, and โ most importantly โ convert between
JSON text and Python dicts/lists in both directions.
AI Connection
JSON is the shared language between your Python code and every AI API.
Every request you send and every response you receive is JSON underneath,
translated to and from Python dicts using exactly json.dumps/json.loads
you just practiced. Files are how your pipeline remembers documents,
results, and intermediate data between runs.
Mini Practice
- Write a documentโs text to a file, then read it back and print its word count.
- Create a Python dict representing an LLM API request (model, messages),
convert it to a JSON string with
json.dumps, and print it. - Parse a JSON string representing an API response and extract just the answer text and token usage.
- Write a list of 3 dictionaries (each with
textandscore) to a JSON file, then load it back and print only the ones withscore >= 0.7. - Explain, in one or two sentences, why nearly every AI API โspeaks JSON,โ and how that connects to what you learned about dictionaries in Module 2.
Next: Module 8 โ Modules, Packages and Environments โ organizing code and securely managing API keys.
- Author
- TechByteByByte Editorial Team
- Reviewed by
- TechByteByByte Admin
- Published
- Last reviewed