Ga naar hoofdinhoud

HTML tonen

Hier bouw je op verder: Intro tot HTML en Tekst opmaken met CSS

Weet je dit niet meer zeker? Lees het terug voordat je verdergaat.

Tot nu toe gaven je endpoints JSON terug. Nu geef je een HTML-pagina terug.

HTMLResponse importeren​

Zet HTMLResponse bij de imports. Je endpoints blijven staan. De bovenkant van je main.py ziet er dan zo uit:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

HTMLResponse komt niet uit fastapi zelf, maar uit fastapi.responses, en krijgt daarom een eigen regel.

Waar komt een naam vandaan?

Elke plek heeft een eigen regel bovenaan: from fastapi import …, from fastapi.responses import …, enzovoort. Een nieuwe naam van een plek die er al staat, zet je in die regel, met een komma ertussen. Komt hij van een nieuwe plek, dan krijgt hij een eigen regel. Welke naam waar hoort, staat op de cheatsheet.

Vergeet je een naam, dan staat er in de terminal NameError: name '…' is not defined. Staat de naam in een @app-regel of tussen de haakjes van een functie, dan start de server niet. Staat hij in de functie zelf, dan gaat het pas mis bij het eerste verzoek, met een 500. VS Code ziet het eerder: zet je cursor op de kronkel onder de naam en druk op Ctrl+., dan stelt hij vaak de import-regel voor.

Een HTML pagina tonen​

Zet dit endpoint onder je andere endpoints:

@app.get("/pagina", response_class=HTMLResponse)
async def pagina():
return """
<!DOCTYPE html>
<html>
<head>
<title>Mijn Pagina</title>
</head>
<body>
<h1>Hallo!</h1>
<p>Dit is mijn eerste HTML pagina.</p>
</body>
</html>
"""
  1. Regel 1:

    response_class=HTMLResponse vertelt FastAPI dat je HTML terugstuurt en geen JSON. Wat er zonder gebeurt, probeer je uit in opdracht 3.

  2. Regel 3-14:

    De functie geeft één lange string terug. De drie aanhalingstekens """ openen een string die over meerdere regels doorloopt, zodat je de HTML kunt schrijven zoals hij is.

Testen​

Ga naar http://127.0.0.1:8000/pagina. Je ziet nu een echte webpagina.

CSS toevoegen​

In de web-cursus zette je CSS in een eigen bestand en koppelde je het met <link>. Dat kan hier ook, maar daarvoor moet je server dat bestand kunnen sturen; dat leer je in CSS in een eigen bestand. Tot die tijd zet je de CSS in een <style>-tag in de <head>. Zet dit endpoint er ook bij:

@app.get("/styled", response_class=HTMLResponse)
async def styled():
return """
<!DOCTYPE html>
<html>
<head>
<title>Met CSS</title>
<style>
h1 { color: blue; }
p { color: gray; }
</style>
</head>
<body>
<h1>Gestylede pagina</h1>
<p>Deze tekst is grijs.</p>
</body>
</html>
"""
Gaat er iets mis?

Zie je geen pagina maar platte tekst? Kijk of response_class=HTMLResponse in je decorator staat. Meer oplossingen staan op Er gaat iets mis.

Zo ziet je main.py er nu uit

Dit is je hele main.py na deze les, zonder wat je in de opdrachten maakte.

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/")
async def root():
return {"bericht": "Hallo wereld!"}

@app.get("/info")
async def info():
return {"naam": "Jouw Naam", "leeftijd": 16}

@app.get("/pagina", response_class=HTMLResponse)
async def pagina():
return """
<!DOCTYPE html>
<html>
<head>
<title>Mijn Pagina</title>
</head>
<body>
<h1>Hallo!</h1>
<p>Dit is mijn eerste HTML pagina.</p>
</body>
</html>
"""

@app.get("/styled", response_class=HTMLResponse)
async def styled():
return """
<!DOCTYPE html>
<html>
<head>
<title>Met CSS</title>
<style>
h1 { color: blue; }
p { color: gray; }
</style>
</head>
<body>
<h1>Gestylede pagina</h1>
<p>Deze tekst is grijs.</p>
</body>
</html>
"""
Controlevraag
In de string van /pagina sluit je de kop per ongeluk af met een h2-tag in plaats van een h1-tag. Je slaat op en herlaadt /pagina. Wat gebeurt er?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Opdrachten​

Opdracht 1: Predict - JSON of HTML?​

@app.get("/titel")
async def titel():
return {"titel": "<h1>Hallo</h1>"}
Voorspel
Wat zie je op /titel?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Opdracht 2: Run​

Ga naar /pagina en /styled. Is de kop op /styled blauw en de tekst grijs? En werkt /info uit de vorige les nog?

Opdracht 3: Investigate - Zonder HTMLResponse​

Wat gebeurt er als je response_class=HTMLResponse weghaalt bij het /styled endpoint? Probeer het uit.

Antwoord

Zonder response_class=HTMLResponse maakt FastAPI JSON van je string. Je ziet geen pagina, maar één lange regel tussen aanhalingstekens, ongeveer zo:

"\n <!DOCTYPE html>\n <html>\n <head>\n <title>Met CSS</title>\n ..."

Elke \n is een plek waar jij een nieuwe regel begon.

Opdracht 4: Make - Eigen pagina​

Maak een endpoint /profiel dat een HTML pagina toont met:

  • Jouw naam als heading
  • Een paragraaf over jezelf
  • Een gekleurde heading via CSS
Tip

Gebruik response_class=HTMLResponse en een string over meerdere regels met """. Zet je CSS in een <style> tag in de <head>.

Antwoord
@app.get("/profiel", response_class=HTMLResponse)
async def profiel():
return """
<!DOCTYPE html>
<html>
<head>
<title>Profiel</title>
<style>
h1 { color: purple; }
</style>
</head>
<body>
<h1>Jan</h1>
<p>Ik ben 16 en hou van programmeren.</p>
</body>
</html>
"""

Opdracht 5: Make - Een lijstje​

Maak een endpoint /hobbylijst dat een pagina toont met een kop en een lijst van drie hobby's.

Tip

Een lijst maak je in HTML met <ul> en voor elk item een <li>. Vergeet response_class=HTMLResponse niet.

Antwoord
@app.get("/hobbylijst", response_class=HTMLResponse)
async def hobbylijst():
return """
<!DOCTYPE html>
<html>
<body>
<h1>Mijn hobby's</h1>
<ul>
<li>Gamen</li>
<li>Voetbal</li>
<li>Tekenen</li>
</ul>
</body>
</html>
"""