Eindproject: de leeslijstservice en -client · eindproject
Eindproject: Laat ze samen draaien
Elke helft is apart bewezen, en de twee hebben nog nooit met elkaar gepraat. Deze les voert elf opdrachten van je client uit tegen je server, beginnend bij reading_server.sample_state() met de now-
| Stap | Opdracht | now | Wat er moet gebeuren | Exit |
|---|---|---|---|---|
| 1 | list | 0 | GET /books, twee boeken | 0 |
| 2 | add, token van de schrijver | 0 | POST /books, 201, de nieuwe | 0 |
| 3 | show 3 | 0 | GET /books/3, vers tot 60 | 0 |
| 4 | show 3 | 30 | niets verstuurd | 0 |
| 5 | show 3 | 60 | If-None-Match, 304, vers tot 120 | 0 |
| 6 | update 3 via /v0, token van de lezer | 60 | 308, dan PUT /books/3: 403 | 2 |
| 7 | update 3 via /v0, token van de schrijver | 60 | 308, dan 200 met de nieuwe titel | 0 |
| 8 | show 3 | 90 | niets verstuurd, de oude titel | 0 |
| 9 | show 3 | 120 | If-None-Match, 200, de nieuwe titel | 0 |
| 10 | delete 3 via /v0 | 120 | 308, dan 204 | 0 |
| 11 | show 3 | 200 | If-None-Match, 404 | 2 |
Elke rij van “Not built yet” zit erin. Stap 6, 7 en 10 gaan via het oude pad, stap 5 hervalideert, stap 2 drukt een location af, en de statussen van de server bepalen elke exitcode.
Een doorverwijzing die je kunt zien
In stap 6, 7 en 10 volgt requests de 308 voor je, zoals hoofdstuk 10 liet zien: het stuurt dezelfde response.history is een response.url is waar requests uitkwam. Voor stap 7 bevat history één 308 waarvan de url de /v0-URL is.
Het contract vraagt de client om dat te melden: één regel op standard error per gevolgde doorverwijzing, followed STATUS from URL, vóór elke andere regel. Standard output blijft voor resultaten, dus een script dat de boekenlijst leest, ziet de regel nooit. Schrijf report_redirects(response), een response.history die van elk item de status_code en url afdrukt met file=sys.stderr. Roep die dan in run aan voor elke opdracht die een antwoord kreeg: direct na call voor list, add, update en delete, en voor show als cached_show een antwoord teruggaf, op beide plekken vóór de foutcontrole.
update 3 via /v0 met het token van de schrijver slaagt. Hoeveel followed-regels verschijnen er, en waar?
Kijk hoe het draait
pl_http.py start je server op een main, de now-waarden hierboven en een cachebestand in een tijdelijke map. De URL’s luiden http://books.test, omdat dat requests naar je server stuurt zonder een naam op te zoeken.
python pl_http.py capstone
Voor elke opdracht drukt het de verzoeken af die je server ontving, dan de
--- requests and replies ---
--- your reading_client.py show 3 --base-url http://books.test (now 30) ---
exit status: 0
standard output: ['3: Piranesi by Susanna Clarke']
standard error: []
--- requests and replies ---
request 1 GET /books/3 (If-None-Match: "6a584f0c2da517c8750cdd3157f9d6f9cc07bbd19955c92a953fcc8cb494f8a9") -> 304 Not Modified (connection 1)
Het eerste blok heeft helemaal geen verzoek: het item dat bij stap 3 was opgeslagen, was vers. Stap 6 gaat via het oude pad met een token dat alleen mag lezen:
request 1 PUT /v0/books/3 -> 308 Permanent Redirect (connection 1)
request 2 PUT /books/3 -> 403 Forbidden (connection 1)
--- your reading_client.py update 3 --base-url http://books.test/v0 --token tok-ben-reads-K9pz --title "Piranesi (paperback)" --author "Susanna Clarke" (now 60) ---
exit status: 2
standard output: []
standard error: ['followed 308 from http://books.test/v0/books/3', '403 this token may read the list but not change it']
Twee verzoeken bereikten je server voor één opdracht. Het tweede kreeg een 403, geen 401, dus requests stuurde het token na de doorverwijzing opnieuw mee: het houdt authorization als de nieuwe URL op dezelfde host staat. De lijst voor standard error begint met je followed-regel en eindigt met de ene foutregel. Bij elk verzoek staat connection 1: requests hield één verbinding open over alle elf opdrachten, zoals hoofdstuk 9 je server leerde toestaan. Aan het eind opent pl_http twee lege verbindingen, zodat serve() zijn telling van drie bereikt en terugkeert.
Vers is niet hetzelfde als actueel
Stap 8 is degene die er verkeerd uitziet:
--- your reading_client.py show 3 --base-url http://books.test (now 90) ---
exit status: 0
standard output: ['3: Piranesi by Susanna Clarke']
Bij stap 7 werd de titel Piranesi (paperback), en je server weet dat. Je client drukte toch de oude titel af, en stuurde niets. Terecht. Bij stap 5 zei de 304 van de server max-age=60: je mag deze kopie 60 seconden hergebruiken zonder te vragen. Die belofte liep tot 120, en de wijziging bij stap 7 kan een kopie waar de client nooit naar vraagt niet bereiken. Stap 9, op 120, is het moment dat de belofte afloopt: de client stuurt de oude tag, de tag komt niet meer overeen, en de 200 brengt de nieuwe titel. max-age ruilt actualiteit in voor bespaarde verzoeken, en de server kiest die ruil.
Stap 8 drukt de oude titel af, hoewel stap 7 hem veranderde. Doet de client het fout?
Wat er bewezen wordt, en hoe
Check my work leest die run niet. Hij herhaalt elke controle van les 1 en 2 en voert dan elf opdrachten uit in het geheugen: een echte requests.Session waarvan de enige adapter de bytes van elk verzoek in hetzelfde proces aan de handlerklasse van je server geeft, zodat requests de 308’s volgt en de 304 leest zoals het over een netwerk zou doen. De boeken, titels, tokens en basis-URL zijn nieuw, MAX_AGE is 45, en elke exitstatus, uitvoerregel, followed-regel en elk aantal verzoeken moet kloppen, met TIMEOUT bij elke hop.
Je opdracht
Schrijf
report_redirects.Roep die in
runaan voor elke opdracht, vóór de foutcontrole.Voer
python -m pytest -qenpython pl_http.py capstoneuit.Klik op Check my work.
De twee helften zijn het nu eens over elke opdracht van het contract. De volgende les schrijft de tests die zouden merken als een van beide daarmee ophield.
Opdracht
Meld elke
report_redirects(response): druk voor elk item vanresponse.history, op volgorde,followed STATUS from URLaf op standard error, met destatus_codeenurlvan dat item. Niets bij een lege history.Roep die in
runaan voor elke opdracht die een antwoord kreeg (voorshowalscached_shower een teruggaf), vóór de foutcontrole, zodat defollowed-regels vóór elke andere regel op standard error komen.
Houd elke server- en clientrij uit les 1 en 2. Voer python -m pytest -q en python pl_http.py capstone uit in de
Klik daarna op Check my work. Die herhaalt elke controle van les 1 en 2, controleert dan report_redirects op een antwoord dat een 308 en een 301 volgde, en de eerste regel op standard error van list, show, add, update, delete en een geweigerde update, elk via een /v0-basis-http://shelf.test:8123, MAX_AGE op 45, en now 0, 0, 0, 30, 60, 60, 60, 90, 120, 120, 200. Elke exitstatus, regel op standard output, followed-regel, foutregel, elk aantal verzoeken, If-None-Match en de timeout bij elke hop moeten kloppen; daarna moet main zonder sessie er zelf een maken met make_session. Terwijl je client draait, kan reading_client.requests niets versturen. Hij leest je terminal en de pl_http.py-run niet.