promptdojo_
chapter 04

read the pipeline

every real script reads a file or calls an api — usually both. learn the with-block, the status-code families, and the retry rules: the seatbelts ai forgets to put on.

3 live lessons · 24 live steps · 83 XP

Every real script is a pipeline

Read a file. Call an API. Check what came back. Write the result somewhere. Strip away the framework and that's what almost every AI-generated script does — data comes in from disk, goes out over the wire, and comes back as JSON you have to dig through.

This chapter is the minimum file and HTTP literacy you need before the LLM-API track. Not an I/O curriculum — the handful of shapes that show up in nearly every script you'll read or ship this year, plus the seatbelts AI forgets to put on: the with block that guarantees a file closes, the status check before .json(), the retry that backs off instead of hammering.

The mental model

Two halves, one pipeline:

Files. Every file operation is open, do something, close:

with open("data.csv", "r") as f:
    contents = f.read()
# file is closed here, automatically

Modern Python often skips the boilerplate entirely with pathlib:

from pathlib import Path
contents = (Path("data") / "users.csv").read_text()

HTTP. Every API call is a request you send and a response you receive, and AI writes the same four lines on autopilot:

import httpx

response = httpx.get("https://api.example.com/users/7")
response.raise_for_status()  # crash on 4xx/5xx
data = response.json()
print(data["name"])

The status code — 200, 404, 429, 500 — is the most diagnostic field in the response. The first digit tells you who broke (you or the server) and whether retrying can help.

What this chapter covers in three lessons

Lesson 1: Files without fear. with open(...) as f, the mode strings ("r", "w", "a"), pathlib.Path with the / operator and read_text/write_text — and the manifest: a small sha256-and-rows receipt that catches a dataset being silently swapped under you.

Lesson 2: Talking to APIs. The shape of a call, the status-code families (2xx success, 4xx your fault, 5xx their fault), and pulling a value out of the nested JSON that comes back.

Lesson 3: When the pipeline breaks. raise_for_status, reading error bodies, and the retry decision: never retry 4xx (except 429 Too Many Requests, which means wait, then retry — honor the Retry-After header), retry 5xx with backoff, always bounded.

What AI specifically gets wrong here

  • Opening with "w" when the file should grow. Every save wipes the previous contents. Check the mode any time AI writes a log.
  • Calling .json() without checking the status. A 401 error body parses fine, then your code crashes six lines later on a missing key — the traceback points at the wrong line.
  • Retrying everything. A loop that re-sends the same broken request to a 401-returning API five times. Retries belong on 5xx and 429, nowhere else.

Why this chapter sits here

The LLM-API chapter — and everything after it — assumes you can read these shapes cold: an API call is exactly this pattern with the URL pointed at a model provider and a messages list in the body, and the 429/backoff dance is daily reality once you're paying per token. Get this solid and the rest installs cleanly on top.

Press Start chapter below.