Ga naar hoofdinhoud

Eigen POST request

Hier bouw je op verder

In deze les maak je een formulier dat data verstuurt naar je server via POST.

Het formulier

Maak static/pages/naam_form.html:

<!DOCTYPE html>
<html>
<body>
<h1>Wat is je naam?</h1>
<form method="post" action="/verstuur">
<input type="text" name="naam" required>
<button type="submit">Verstuur</button>
</form>
</body>
</html>

Belangrijke onderdelen

  • method="post" — Stuurt data via POST
  • action="/verstuur" — Naar welk endpoint
  • name="naam" — Deze naam gebruiken we in Python

De endpoints

In main.py:

from fastapi import FastAPI, Form
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

@app.get("/naam")
async def toon_formulier():
return FileResponse("static/pages/naam_form.html")

@app.post("/verstuur")
async def ontvang_naam(naam: str = Form(...)):
print(f"Naam ontvangen: {naam}")
return {"bericht": f"Hallo {naam}!"}
  1. Regel 8-10:

    Een gewone GET die het formulier toont. Het formulier is een HTML-bestand, dus FileResponse.

  2. Regel 12:

    Het pad /verstuur is de action van het formulier, en @app.post de method. Die twee moeten kloppen met de HTML, anders komt het verzoek nergens aan.

  3. Regel 13:

    Form(...) haalt het veld naam uit het verstuurde formulier. De parameter heet naam omdat het veld in de HTML name="naam" heeft; die twee namen moeten gelijk zijn.

  4. Regel 14:

    De print komt in je terminal terecht, niet in de browser. Handig om te zien wat er binnenkomt.

Waarom moet de naam matchen?

Als je in HTML name="naam" schrijft, stuurt de browser de data als naam=Jan. FastAPI zoekt dan naar een Python parameter die ook naam heet. Als die namen niet overeenkomen, kan FastAPI de data niet vinden en krijg je een 422 error.

Testen

  1. Ga naar http://127.0.0.1:8000/naam
  2. Vul je naam in en klik Verstuur
  3. Je ziet: {"bericht": "Hallo Jan!"}
  4. In de terminal: Naam ontvangen: Jan
Gaat er iets mis?

Krijg je een 422 Unprocessable Entity? Check of de name in je HTML matcht met de parameter in Python. Bekijk de troubleshooting pagina voor meer oplossingen.

Opdrachten

Opdracht 1: Predict - Wat zie je?

<form method="post" action="/groet">
<input type="text" name="naam">
<button type="submit">Verstuur</button>
</form>
@app.post("/groet")
async def groet(naam: str = Form(...)):
return {"groet": f"Hallo {naam}!"}

Vraag: Je vult "Sarah" in. Wat zie je?

Tip

Kijk wat de Python functie returnt. De waarde van naam wordt "Sarah" — wat wordt de f-string dan?

Antwoord

{"groet": "Hallo Sarah!"}

Opdracht 2: Run

Maak het formulier en de endpoints uit het voorbeeld. Test of je een naam kunt invullen en het bericht terugkrijgt.

Opdracht 3: Investigate - Naam mismatch

Wat gebeurt er als je in HTML name="voornaam" schrijft, maar in Python naam: str = Form(...) houdt? Probeer het uit.

Antwoord

Je krijgt een 422 Unprocessable Entity error. FastAPI zoekt naar een veld genaamd naam, maar de browser stuurt voornaam. De namen moeten exact matchen.

Opdracht 4: Make - Eigen formulier

Maak een formulier voor je favoriete kleur met een GET endpoint (formulier tonen) en POST endpoint (data ontvangen). Print de kleur in de terminal.

Tip

Maak een HTML bestand met een <form method="post" action="/kleur"> en een <input name="kleur">. Maak twee endpoints: @app.get("/kleur") voor het formulier en @app.post("/kleur") voor het ontvangen.

Antwoord

static/pages/kleur_form.html:

<!DOCTYPE html>
<html>
<body>
<h1>Favoriete kleur</h1>
<form method="post" action="/kleur">
<input type="text" name="kleur" required>
<button type="submit">Verstuur</button>
</form>
</body>
</html>
@app.get("/kleur")
async def kleur_form():
return FileResponse("static/pages/kleur_form.html")

@app.post("/kleur")
async def kleur_ontvang(kleur: str = Form(...)):
print(f"Kleur ontvangen: {kleur}")
return {"kleur": kleur}

Opdracht 5: Make - Twee velden

Maak een formulier met naam en leeftijd:

<input type="text" name="naam" required>
<input type="number" name="leeftijd" required>
@app.post("/profiel")
async def profiel(naam: str = Form(...), leeftijd: int = Form(...)):
return {"naam": naam, "leeftijd": leeftijd}
Tip

Je hebt twee <input> velden nodig in je HTML en twee Form(...) parameters in Python. Let op: leeftijd is een int, niet een str.

Antwoord

static/pages/profiel_form.html:

<!DOCTYPE html>
<html>
<body>
<h1>Profiel</h1>
<form method="post" action="/profiel">
<input type="text" name="naam" required>
<input type="number" name="leeftijd" required>
<button type="submit">Verstuur</button>
</form>
</body>
</html>
@app.get("/profiel")
async def profiel_form():
return FileResponse("static/pages/profiel_form.html")

@app.post("/profiel")
async def profiel(naam: str = Form(...), leeftijd: int = Form(...)):
return {"naam": naam, "leeftijd": leeftijd}