Ga naar hoofdinhoud

Invoer controleren: een 422 lezen

In les 3 printte je alleen de melding. Het antwoord van een 422 zegt meer: welk veld het was, wat voor fout, en wat er binnenkwam. Met die gegevens kan een script zeggen wat er mis is.

Twee fouten tegelijk​

Maak een script fouten.py dat een te lange naam en een leeg bericht stuurt:

import httpx

adres = "http://127.0.0.1:8000/bericht"

antwoord = httpx.post(adres, data={"naam": "a" * 31, "bericht": ""})
print(antwoord.status_code)
for fout in antwoord.json()["detail"]:
print(fout["loc"][1], fout["type"], fout["msg"])
  1. Regel 7:

    detail is een lijst, met één dictionary per fout. Een for-loop loopt ze langs.

  2. Regel 8:

    Uit elke fout drie stukken: het veld, het soort fout, en de melding.

Draai het, met de server uit les 3.

Wat er in één fout staat​

Elke fout is een dictionary. Voor de te lange naam ziet hij er zo uit:

{'type': 'string_too_long', 'loc': ['body', 'naam'], 'msg': 'String should have at most 30 characters', 'input': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'ctx': {'max_length': 30}}
SleutelBetekent
typehet soort fout, als vast woord
locwaar: body is het formulier, daarna het veld
msgde melding in het Engels
inputwat er binnenkwam
ctxde grens die gold, als die er is

Daarom pak je in het script fout["loc"][1]: het tweede stuk van loc is de naam van het veld.

Een leeg veld is al een fout​

Het lege bericht gaf missing, en dat zonder dat je er iets voor schreef. Form(...) maakt een veld verplicht, en voor FastAPI telt een leeg veld als niet ingevuld. Een min_length=1 erbij is dus niet nodig.

Controlevraag
Je stuurt met fouten.py een naam van 40 tekens en een bericht van 300 tekens. Hoeveel regels print het onder de 422?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Er gaat iets mis​

KeyError: 'detail'​

Je verandert in fouten.py de naam in Sara en het bericht in hoi, en het script stopt met:

KeyError: 'detail'

Oorzaak: de server keurde alles goed, en antwoordde met een 200 en {'lengte': 3}. In dat antwoord staat geen detail, dus antwoord.json()["detail"] bestaat niet.

Oplossing: lees detail alleen als de server een 422 stuurde:

import httpx

adres = "http://127.0.0.1:8000/bericht"

antwoord = httpx.post(adres, data={"naam": "Sara", "bericht": "hoi"})
print(antwoord.status_code)
if antwoord.status_code == 422:
for fout in antwoord.json()["detail"]:
print(fout["loc"][1], fout["type"], fout["msg"])

Opdrachten​

Opdracht 1: Predict - Alleen een leeg bericht​

Je stuurt de naam Sara en een leeg bericht.

Vraag: wat print fouten.py, na de regel met 422?

Antwoord
bericht missing Field required

Eén fout: de naam is goed, het bericht ontbreekt.

Opdracht 2: Investigate - Waarom niet input printen?​

Waarom print fouten.py wel type en msg, maar niet input?

Tip

Denk aan groot.py uit les 2 en 3.

Antwoord

Omdat input alles bevat wat er binnenkwam. Bij een bericht van een miljoen tekens print je dan een miljoen letters. type en msg zijn altijd kort.

Door naar les 5: de inhoud controleren.