Programming for the Web

Connecting Requests to JSON Storage


Learning Objectives

  • You can distinguish request-local values, running state, and saved records.
  • You can read the current records, append a record, and save the result.
  • You can explain why a GET request leaves the file unchanged.

The guided application called a supplied addition operation. To understand how that operation preserves records, first distinguish the values belonging to one request, the running Python program, and a saved file.

Requests and a Running Program

A new request calls a route again within the running Python program. Different browser tabs reach that same program and its current data. Each call has its own arguments and context, while a module-level list can remain available between calls. Filtering produces a selected view; it leaves that source list unchanged.

The next question uses a memory-only application. Follow the list across requests and a restart.

Two Browser Visits

0 / 5 points

On startup, this application runs:

task_titles = ["Read the article", "Practise loops"]
def matching_titles(q=""):
selected = []
for title in task_titles:
if q.lower() in title.lower():
selected.append(title)
return selected

An accepted POST appends its title to task_titles. GET /tasks passes its query parameter q to matching_titles and displays the returned titles; when q is omitted, it uses "". No operation saves the list to a file.

  1. Tab A successfully adds "Read notes".
  2. Tab B makes a new GET request for /tasks?q=read while the same Python process is running.
  3. Python is stopped and started again, executing the initialization above.
  4. Tab A makes a new GET request for /tasks?q=read.

How many titles appear on Tab B’s page in step 2 and Tab A’s page in step 4?

The local Study Tasks project instead preserves additions in JSON. After restarting, it reads that file to construct new Python records. Examine the existing add_task in the support.py listing; no new files are needed here.

The supplied read_records(path) loads the file’s JSON into Python records. write_records(path, records) saves the complete collection as JSON.

Read, Prepare, Save

The supplied prepare_task(title, category) builds a record with trimmed text and a generated identifier. The addition function appends that record to the list it just read, then saves the list:

def add_task(path, title, category):
records = read_records(path)
task = prepare_task(title, category)
records.append(task)
write_records(path, records)
return task

The diagram below follows an addition into the JSON file and shows how a later run reads the saved collection.

Saving the complete list preserves its records for a later application run.

Save a collection containing both the old records and the new record. Saving only the new record would lose earlier tasks.

Read the Current File on Each Operation

A GET route calls read_records(DATA_FILE) to display the current records. It does not call the writer. Starting the server also leaves the file’s contents unchanged.

Add a record through the browser and inspect tasks.json. Stop and restart the server, then refresh: the saved record should return.

The next exercise supplies a GET route that calls read_records(DATA_FILE) to display the current records. Complete the addition function so it saves a new task together with the existing records. This exercise is worth 40 points.

Save a New Task

0 / 40 points

Complete add_task(path, title, category) in main.py.

Read the current records with read_records(path), append the task returned by prepare_task(title, category), save the complete list with write_records, and return the new task. The helpers and routes are supplied.

Keep every earlier task. Saved tasks remain after restarting, and GET requests leave the file unchanged.

For the next trace, compare a Python record’s current title with the title saved in JSON.

Changes to Task Data

0 / 5 points

The supplied write_records(path, records) saves the given records as JSON.

A program executes:

records = [
{"id": "T01", "title": "Make a plan", "category": "writing"}
]
write_records("tasks.json", records)
records[0]["title"] = "Review notes"

Immediately afterward, what is the title in records[0] and the title of the task stored in tasks.json?

Next, apply these steps to a Reading Journal.

Check Your Understanding

  1. Two tasks are added one after another. If the second addition saves a list containing only its new task, what happens to the first task, and why?
  2. A search matches one task out of three. What could happen if the GET route saved that selected list back to tasks.json? Why should displaying the selection leave the file unchanged?
  3. An addition is saved to new-tasks.json, while the GET route reads tasks.json. Why can saving succeed without the new task appearing, and which path values would you compare?