0%

Talking to an API · capstone

Capstone project: Project: Fetch One Safe Page

Finish one command that fetches, validates, and writes exactly one page.

The site’s disposable .venv is excluded when moving between lessons. Rebuild it from the saved requirement before running this command:

python -m venv .venv
.venv/bin/python -m pip install -r requirements.txt

On your own machine, reuse your existing project environment if it already has the recorded dependency installed. The command’s interface is deliberately small:

.venv/bin/python api_catalog.py requested-page.json --page 1 --page-size 2

The positional output path is required. Page defaults to 1. Page size defaults to 2. --page must be at least 1 and --page-size must be 1 through 3. Reject invalid values in argparse with status 2 and stderr before any HTTP call. There is no base-URL, host, token, secret, or retry option.

write_page(document, output_path) writes visible UTF-8 JSON using two-space indentation, allow_nan=False, and exactly one trailing newline, then returns the same document.

run_api_catalog(output_path, page, page_size, *, timeout=DEFAULT_TIMEOUT, session=None) first calls fetch_items_page. Only after fetch and validation succeed may it call write_page. Success prints exactly Wrote N items to OUTPUT_PATH., prints no stderr, and returns 0.

At this command boundary, catch only these expected failures, in this meaning:

  • requests.Timeout: Practice API request timed out.

  • requests.ConnectionError: Could not connect to the practice API.

  • requests.HTTPError: Practice API returned HTTP STATUS. For 429 only, append Retry after N second(s). from the response header.

  • requests.exceptions.JSONDecodeError: Practice API returned invalid JSON.

  • response-validation : Practice API returned invalid data: MESSAGE

  • output OSError: Could not write OUTPUT_PATH: MESSAGE

Every failure message goes to stderr and returns 1. Unexpected RuntimeError, TypeError, assertions, invalid-URL defects, and unrelated programming errors must propagate with their . A pre-existing output sentinel remains unchanged for every failure before writing begins. This project promises no rollback after the writer starts.

Keep main(argv=None) import-safe: parse first, then pass the three values to run_api_catalog. On success, inspect the requested JSON artifact and leave api_catalog.py, requirements.txt, API_CONTRACT.md, and that artifact in the workspace. .venv, caches, and bytecode are derived and excluded.

One idea ties this whole project together, and it is worth stating plainly before you build it. Every one of those failure messages is short, specific, and tells the person running the command something they can act on. None of them is a traceback, and none of them is the word “error” on its own. That is the difference between a program that failed and a program that failed usefully.

The unexpected failures stay ugly on purpose. A TypeError from a defect in your own code should look alarming, because it means something you believed about your program is not true.

When may the command first open the requested output for writing?

Task

Complete the exact parser, write_page, run_api_catalog, and import-safe main(argv=None) contract. Fetch and validate before writing; preserve output on every pre-write failure; emit the specified stdout/stderr and statuses; catch only the documented expected . Leave the durable source, exact requirements pin, contract note, and your requested JSON artifact, while making no public-host, retry, secret, live-evidence, or deployment claim.