De standaardclient en statusklassen · oefening
Headers van het antwoord lezen
De statusklasse vertelt een client wie er aan zet is. Sommige zetten hebben meer nodig. Hoe lang moet de client na een 429 wachten? Is deze body wel get_json teruggeeft: Content-Type en Retry-After.
Twee manieren om een header te lezen
Je record bevat al elke header in de getheaders() bouwde: namen in kleine letters, elk met een
response.getheader("Retry-After")
getheader(name) vindt de naam in elke schrijfwijze, dus "retry-after", "Retry-After" en "RETRY-AFTER" vinden allemaal een regel die de server schreef als Retry-After: 1. Het geeft de waarde terug als None als de header ontbreekt; een tweede getheader("Retry-After", "0"), vervangt die None. Komt de naam meer dan eens voor, dan voegt getheader de waarden samen tot één string met ", " ertussen.
Beide manieren zijn niet hoofdlettergevoelig, en elk past bij een andere taak. Voor een header met één waarde, zoals Content-Type of Retry-After, geeft getheader je die waarde direct. Voor een header die herhaald kan worden, waarbij je elke waarde apart nodig hebt, houdt de dict ze uit elkaar: X-Trace: a en X-Trace: b blijven daar ["a", "b"], terwijl getheader("X-Trace") "a, b" teruggeeft. Samenvoegen is alleen veilig als er geen komma in een waarde kan staan, en dat geldt niet voor elke header; hoofdstuk 7 komt er een tegen waarvoor het niet geldt.
Wat je niet moet doen, is de naam opzoeken in een dict die gebouwd is met de schrijfwijze van de server zelf. Een server kan retry-after of RETRY-AFTER schrijven, en {"Retry-After": "1"}.get("Retry-After") werkt alleen met een server die de naam op jouw manier schreef.
Retry-After is tekst
Retry-After vertelt de client wanneer hij opnieuw mag vragen. Het bevat ofwel een aantal seconden, zoals Retry-After: 120, ofwel een datum, zoals Retry-After: Fri, 31 Dec 1999 23:59:59 GMT. Omdat het een datum kan zijn, is de waarde niet altijd een getal, en houdt get_json hem als de tekst die aankwam. Er een wachttijd van maken, en beslissen of er überhaupt opnieuw geprobeerd wordt, is de taak van wie get_json aanroept.
De regel uit Python in Practice voor 429 geldt hier nog steeds: het is een signaal om te stoppen. get_json meldt wat de server zei en keert terug; het wacht niet en verstuurt het verzoek niet opnieuw.
De kop van een antwoord bevat de regel Retry-After: 1. Wat geeft response.getheader("retry-after") terug?
Content-Type heeft parameters
Content-Type noemt het formaat van de body. practice-api stuurt Content-Type: application/json; charset=utf-8. Het deel vóór de ; is het mediatype, application/json; wat volgt is een application/json zonder parameter, of application/json;charset=UTF-8 zonder spatie. Les 4 gebruikt het mediatype om te beslissen of een body als JSON gedecodeerd wordt. Houd voorlopig de hele waarde zoals hij aankwam.
Bekijk een 429
Het rate-limitscenario antwoordt op basis van het pogingnummer dat je meestuurt: pogingen 1 en 2 krijgen een 200, en pogingen 3 tot en met 10 krijgen een 429. Het onthoudt niets tussen verzoeken, dus poging 3 is altijd een 429. Onder de
Content-Type: application/json; charset=utf-8
Retry-After: 1
X-RateLimit-Limit: 2
X-RateLimit-Remaining: 0
Je opdracht
Voeg in
wire.pytwee sleutels toe aan het record datget_jsonteruggeeft:"content_type", uitresponse.getheader("Content-Type"), en"retry_after", uitresponse.getheader("Retry-After"). Lees beide binnen hetwith-blok, houd elk als de tekst die aankwam, en laatNonestaan als de header ontbreekt. Houd alles wat les 1 schreef.Bekijk een live 429:
python -c "import wire; r = wire.get_json('/v1/scenarios/rate-limit?attempt=3'); print(r['status'], r['content_type'], r['retry_after'])"
Het zou 429 application/json; charset=utf-8 1 moeten afdrukken. Probeer ook attempt=2: de 200 die terugkomt, heeft geen Retry-After, dus zijn retry_after is None.
Druk daarna op Check my work. Je client leest nu de status en de headers die een beslissing nodig heeft, maar behandelt nog steeds elke body op dezelfde manier. De volgende les deelt elk scenario in op klasse en houdt de foutbodies.
Opdracht
Voeg de headers die een beslissing nodig heeft toe aan het record dat get_json teruggeeft.
"content_type": devan response.getheader("Content-Type"), zoals hij aankwam, inclusief. "retry_after": de waarde vanresponse.getheader("Retry-After"), bewaard als tekst, niet omgezet in een getal.Beide zijn
Noneals het antwoord zo’n header niet heeft.Houd alles uit les 1: één verbinding met de time-out, één
GETmet de oefenheader, de status, reason, headerdict en body, en de verbinding gesloten op elk pad.get_jsonwacht niet en verstuurt het verzoek niet opnieuw na een 429; het geeft het record terug.
Voer python -c "import wire; r = wire.get_json('/v1/scenarios/rate-limit?attempt=3'); print(r['status'], r['content_type'], r['retry_after'])" uit in de
Druk daarna op Check my work. Die roept get_json aan met een vervanger voor make_connection waarvan de gescripte antwoorden headernamen in ongebruikelijke schrijfwijzen bevatten, zoals rEtRy-AfTeR: 3: een 429, een 503 met Retry-After, en antwoorden zonder een van beide headers. Ze controleert de twee nieuwe sleutels, dat het record en het sluiten uit les 1 nog kloppen, en dat get_json niet wacht en geen tweede verzoek verstuurt. Niets uit je terminal wordt beoordeeld.