Skip to content

Flask

Introductie

Stel – je bezoekt een webwinkel. Je voert het adres in van de website die je wilt bezoeken en drukt op enter. Binnen enkele seconden reageert je browser, die in rap tempo een webpagina toont. Je wordt begroet met je gebruikersnaam, en wanneer je daarop klikt laadt direct jouw persoonlijke omgeving. Hier wijzig je je adresgegevens en drukt op opslaan. Volgende keer wanneer je een bestelling plaatst wordt het pakketje naar het correcte adres gestuurd. Maar… Wat gebeurt hier nou achter de schermen?

De sleutelrol in dit alles wordt gespeeld door een zogeheten web framework. Dit web framework is een basisprogramma waarin alle essentiële functies van een website (of andere webapplicatie) al zijn voorgeprogrammeerd. Dit scheelt een hoop werk, omdat een ontwikkelaar dan alleen die code en bestanden hoeft toe te voegen die voor die website anders zijn dan anders. Daarom dat het merendeel van de websites, van zowel kleine als grote organisaties, gebruik maakt van een web framework.

Elk framework heeft tenminste drie functionaliteiten: het ontvangen van HTTP-requests van bezoekers, het routeren naar de juiste pagina, en het terugsturen van een HTTP-response met daarin de relevante bestanden. Daarnaast zijn er veel extra opties die een framework kan aanbieden, die het leven van bezoekers en ontwikkelaars makkelijker maken: onder andere cookies, extra beveiliging, caching, en logging worden vaak aangeboden.[^1]

Een gemiddelde ‘flow’ van een HTTP-verzoek aan een webserver ziet er als volgt uit. De gebruiker opent een browser en voert een URL in. De browser gebruikt deze URL als basis voor een HTTP-request, die naar de server wordt gestuurd waarop de website gehost wordt. Zodra de webserver dit verzoek ontvangt gaat het framework aan de slag. Eerst wordt er gecontroleerd of het verzoek wel mag – bestaat het webadres wel, en mag de bezoeker überhaupt dat deel van de website zien? Zo niet, dan stuurt het framework een foutmelding terug naar de browser van de gebruiker. Zo ja, dan gaat het framework aan de slag met het verzoek. Het framework zoekt op welke code moet worden gebruikt om de opgevraagde pagina op te bouwen. Deze code kan veel, van aangeven dat sommige velden in een formulier niet goed zijn ingevuld tot het weergeven van het weer in een specifieke locatie. Als alles klaar staat voor de gebruiker stuurt het framework een HTTP-response terug. De browser ontvangt dit en laat de pagina zien aan de gebruiker. Zodra een gebruiker iets doet op de pagina, zoals op een link klikken, begint het weer opnieuw.

Flask

Een goed voorbeeld van een web framework is Flask. Flask gebruikt Python om websites te draaien, en is een zogeheten microframework: het bevat alleen de basics. Hierdoor krijgen ontwikkelaars meer flexibiliteit om hun eigen website te bouwen, maar ze moeten zelf aanvullende functionaliteiten zoals user accounts, input validation, of database verbindingen programmeren. Deze flexibiliteit maakt het een ideaal framework voor zowel beginners als grote organisaties – Netflix gebruikt het bijvoorbeeld om aanbevelingen te geven over series en films!

Er is niet veel nodig om een website werkend te krijgen in Flask. Het minimum bestaat uit een Python-bestand met een paar regels code om aan te geven wat de website moet doen, een HTML-bestand waarin de layout van de webpagina zelf staat beschreven, en een CSS-bestand om de website mooi te maken.

Belangrijk is wel dat al deze bestanden op de juiste plek staan. Flask is ervoor gemaakt om standaard taken uit handen te nemen, zoals het afhandelen van HTTP-requests. Dat betekent dat er achter de schermen is aangegeven waar alles staat om die standaardtaken uit te voeren, zoals de stylesheets of HTML-bestanden. Als je hiervan wilt afwijken ‘weet’ Flask ineens niet meer waar het de bestanden moet vinden, en geeft het foutmeldingen.

Dit betekent dat elk basic Flask-programma de volgende structuur moet aanhouden[^1]:

website_folder/
  __init__.py       # required file

  static/           # required folder
    stylesheet.css  # example file
    header.bmp      # example file

  templates/        # required folder
    base.html       # example file
    home.html       # example file

Alle bestanden voor je website staan in de folder website. In de hoofdfolder staan je Python-bestanden. Dit zijn de bestanden waarmee je de website aanstuurt, bijvoorbeeld wat er moet gebeuren als iemand naar een bepaalde URL gaat. Er is een bestand verplicht in deze folder: __init__.py. Zodra Flask wordt gestart gaat het op zoek naar dit bestand. Daarom zetten we daar meestal de hoofdinstellingen van de website in. In de folder templates zet je jouw HTML-bestanden. Als laatste is er de static-folder. In de static-folder zet je alle statische bestanden, zoals CSS-stylesheets, plaatjes, of video’s.

Flask code

In __init__.py ga je de code schrijven waarmee je Flask-framework draait. Er zijn stukken code waarmee je het framework opzet, de basis-stukken code waarmee je de instellingen meegeeft voor je applicatie, en stukken code waarmee je het framework invult. De basis-code zal er meestal als volgt uitzien:

from flask import Flask, render_template, request

create_app():
    app = Flask(__name__)
    app.config.from_mapping(#settings here)
    ...
    ...
    ...

    return app

Met de eerste regel importeer je de belangrijkste Flask-componenten in je Python-bestand. Hiermee kan je deze in-built functionaliteiten in jouw eigen code gebruiken. Er zijn er 3 die toelichting verdienen:

  • Flask: Flask is het object waarin alle standaard-functies van het webframework zijn vormgegeven. Hiermee ‘start’ je als het ware het web framework zodat je website kan draaien.
  • request: Request is het HTTP-request, inclusief alle headers en beschrijvende informatie, die wordt opgestuurd door de bezoeker als deze een pagina wilt laden. Hierin staat bijvoorbeeld naar welk IP-adres Flask een reactie moet sturen, informatie uit formulieren die zijn ingevuld, en de HTTP-methode die is gebruikt om de pagina op te vragen.
  • render_template: hiermee geef je aan dat er een HTML-bestand moet worden samengesteld op basis van een HTML-template uit de folder templates. Zodra je een template rendert stuurt Flask een HTTP-response aan de bezoeker.

Vervolgens ga je routes definieren. De route geeft aan welke code uitgevoerd moet worden als een gebruiker een pagina opvraagt. Je definieert de route tussen het initialiseren van de app met app = Flask(__name__) en de regel return app. Een route kan er bijvoorbeeld als volgt uitzien:

@app.route("/about", methods=["GET, POST"])
def about():
    if request.method = "GET":
        return render_template("about.html")
    if request.method = "POST":
        error = "Je hoort geen POST-methode te gebruiken hier!"
        return render_template("about.html", error_on_html_page = error)

Je registreert een route met @app.route(). Als eerste argument geef je mee over welke URL deze route gaat. In dit geval vraagt iemand de pagina http://hostname/about op. Er zijn daarnaast twee HTTP-methoden toegestaan: GET en POST. Daarna ga je een functie definieren: een blokje herbruikbare code. Dit heeft wat unieke karakteristieken waar je later meer over gaat leren. Neem voor nu aan dat dit de standaard volgorde is.

In de functie staan 5 regels code. In dit geval zijn er twee if-statements: als de methode GET gebruikt wordt, wordt het eerste blokje code uitgevoerd, en als de methode POST gebruikt wordt draait het tweede blokje code. Zoals eerder beschreven leest Flask de HTTP-methode uit via request.

Bij de eerste if, voor de methode GET, staat de code return render_template("about.html"). Met return geef je aan dat de functie nu op z’n einde is, en dat de functie iets teruggeeft aan het hoofdprogramma. In dit geval geeft het een gerenderde pagina about.html terug, om op te sturen naar de bezoeker. Bij de tweede if staat er een regeltje extra. Er wordt een error-bericht opgeslagen in een variabele, omdat het eigenlijk niet de bedoeling is om deze pagina met een POST-methode te bezoeken. Omdat je dit bericht ook op de HTML-pagina wilt tonen geef je bij deze render-statement een extra argument. De code return render_template("about.html", error_on_html_page = error) geeft aan dat je about.html wilt renderen, en dat er een variabele meegaat. In het HTML-template zal er een optioneel stukje HTML-code staan met de aanduiding error_on_html_page. Je geeft met deze code aan dat er op die plek de tekst "Je hoort geen POST-methode te gebruiken hier!" moet komen te staan.

Met deze blokjes kan je de meeste basis Flask-applicaties bouwen! Voor meer over hoe je Flask kan gebruiken, en hoe je het combineert met Jinja, kan je kijken op de Digital Ocean tutorial How To Use Templates in a Flask Application.

[^1]: je mag hiervan afwijken zodra je bekender bent met Flask, maar vooralsnog is het belangrijk om dit aan te houden.