SD5913 / WEEK 09 / 5 NOVEMBER 2026
One scene.
Two views.
Connected interactions / messages, state and useful failure
SD5913 / WEEK 09 / 5 NOVEMBER 2026
Connected interactions / messages, state and useful failure
SD5913 / WEEK 09 / 5 NOVEMBER 2026
01 Locate the other process.
02 Validate an action before changing state.
03 Share one scene through two views.
04 Inspect failure before deciding to retry.
05 Choose a boundary for your project.
OPENING / DATED NEWS
FastAPI 0.162.0 / 23 October 2026
Omitted form fields now follow declared defaults or missing-field errors.
What should an omitted gallery control mean: false, unchanged or invalid?
REUSE / WEEK 4
A person chooses September.
The browser asks the Python service for records.
The response is data; the browser still draws the chart.
01
HOST, PORT, ROUTE AND PROTOCOL
ADDRESS
ONE JOURNEY / DIFFERENT JOBS
PREDICT / LOCATE THE FAILURE
Server running:
GET /statee
HTTP 404 / application answered.
Server stopped:
GET /state
Connection failure / no HTTP response.
Same host. Same port. Different failure boundary. Read the status and body. A response is not automatically success.
LIVE / FROM PFAD WEEK09
cd week09 uv run python server.py # Open twice: http://127.0.0.1:8009 # A snapshot in another terminal: curl http://127.0.0.1:8009/state
One process, loopback only. Ctrl+C stops it.
READ / ACTUAL DATA SHAPE
{"type": "state", "x": 50, "revision": 0}
# Send an action:
{"id": "a-1", "action": "set_x", "x": 25}
A read and a command have different jobs.
1 / SEND
PYTHON / VALIDATION BEFORE MUTATION
if type(message["x"]) is not int or not 0 <= message["x"] <= 100: raise ValueError("x must be a whole number from 0 to 100.") self.x = message["x"] self.revision += 1
Excerpt from Scene.apply; other field checks precede this.
2 / APPLY
COMPARE / ACCEPTED AND REJECTED
x=0 or 100 / accepted
x=101 / rejected
Valid JSON is not enough.
Inspect x and revision after rejection.
HTTP 422
{"type":"rejected",
"id":"a-2",
"error":"x must be ..."}
Same rule over WebSocket.
02
A COMPACT RAW TCP OBSERVATION /50-60MINUTES
LIVE / TCP ON 8010
# Terminal1, inside week09: uv run python echo_server.py # Terminal2: uv run python echo_client.py
TCP newline framing; this is not HTTP or WebSocket.
BYTES / MESSAGES
03
SNAPSHOTS, CONTINUING MESSAGES AND AWAITING WORK
3 / OBSERVE
4 / ACKNOWLEDGE
COMPARE / EXCHANGE SHAPE
HTTP GET /state
One snapshot for this request.
Polling repeats those reads.
HTTP POST /action
One command and response.
WebSocket /ws A continuing bidirectional channel. State arrives when server broadcasts. HTTP may reuse its TCP connection. Persistent transport is not saved data.
PYTHON / WAIT WITHOUT BLOCKING EVERYTHING
incoming = await client.receive() # Parse and validate this message. async with lock: ack = scene.apply(message) await broadcast() await client.send_json(ack)
Excerpt from updates(); one server process and event loop.
PREDICT / TWO CLIENTS
Inspect the server revisions.
The last accepted action determines x.
A local clock does not establish server order.
A new process starts its revision at0.
04
95-110 MINUTES / OBSERVED, REJECTED OR UNKNOWN
LIVE / DISCONNECT AND RECONNECT
Disconnect A.
Change the scene from B.
Reconnect A: inspect the current snapshot.
A does not automatically resend its old action.
LIVE / IGNORE REPLIES AFTER SENDING
ACTUAL BROWSER / 29 OCTOBER 2026
Connected again; the missing acknowledgement is still unknown.
DESIGN / RETRY POLICY
set_x=73 repeated: same position, another revision.
spend_coin repeated: potentially another cost.
Inspect state before deciding to retry.
This teaching server does not deduplicate IDs.
LIVE / STOP AND RESTART
Stop Python / disconnected UI.
Last-knownposition stays labeled.
Restart Python / x50, revision0.
Read HTTP snapshot without WS reconnect.
Knowledge of old state is not a current observation. RAM is not persistent storage. Week 10 will save related records.
TRANSFER / PROTOCOL CHOICES
EVENT
Reliable delivery plus application rules.
UPDATE
Frequent position snapshots;freshness matters.
READ
HTTP request/response is often enough.
CREATIVE BRIDGE / NO EXTRA SETUP
Week 8 fingertip x -> round(x*100) -> set_x.
No hand -> no action; clamp to the allowed range.
OSC /scene/x could carry one typed value.
An adapter would translate it to this JSON contract.
TEAM / CHOOSE ONE BOUNDARY
Local-only, request/response, or continuing messages?
Name one state, one command and one failure.
Explain what the screen can honestly confirm.
PFAD / SEPARATE 120-MINUTE TUTORIAL
Pinned Week 9 source and complete tutorial
uv run python server.py
Two views -> invalid 101 -> disconnect/restart.
Change the maximum from 100 to 80; check both transports.
Final 20 minutes: tutor review / project support.
Know what changed, what was observed, and what remains unknown.
SD5913.GITHUB.IO/TEACHING