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"])
- Regel 7:
detailis een lijst, met één dictionary per fout. Een for-loop loopt ze langs. - 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}}
| Sleutel | Betekent |
|---|---|
type | het soort fout, als vast woord |
loc | waar: body is het formulier, daarna het veld |
msg | de melding in het Engels |
input | wat er binnenkwam |
ctx | de 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.
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.