Flask Installasjon og Routes

Skip to content

Info

Det aller meste av oppsettet er hentet fra her: Flask Quickstart

GitHub?

Legg gjerne koden på GitHub!

Sjekk teams for info om GitHub classroom, der skal dere finne en lenke til et repository som dere kan klone som et start-prosjekt.

Litt Teori 💤😴

Fun Fact: Hvorfor heter det Flask? 🤔

Originalt var Flask bare en Aprilsnarr spøk (it’s just a prank bro). Det var ment som en vits basert på et allerede eksisterende rammeverk som heter “Bottle”, men så ble det så populært at det ble gjort om til et skikkelig rammeverk! (Kilde: Wikipedia)

Først og fremst, hva er Flask? Flask er et lightweight rammeverk for å lage web-applikasjoner. Selv om det er lightweight, betyr ikke det at det er dårlig! Tvert i mot, det er faktisk det nest mest brukte rammeverket for Python innen web-rammeverk. Første plass går til Django.

Kort forklart: Flask gir deg muligheten til å lage en web-server!

Når dere jobbet med HTML/CSS/JavaScript i fjor “kjørte” dere bare HTML sidene direkte i nettleseren. Tilsvarende, når dere lagde Python programmer kjørte dere bare filene i VS Code.

Men nå skal vi lage en web-server, altså en “back-end” (store fagord, i know 🤓). Denne bruker Python til å “levere” HTML nettsider til en bruker.

Web-server? Levere nettsider? Hæ? 😭

Har du noen gang lurt på hva som egentlig skjer når du går inn på for eksempel https://youtube.com? Nei?

Se for deg at du skriver lenken til en nettside i nettleseren, hvordan får du all informasjonen om innholdet, hvordan nettsiden ser ut også videre?

Svaret: en web-server! 🖥️

Brukeren (altså deg), spør om å få se youtube.com. Dermed sender du en “request” til en web-server og spør:

  • 📞 “Hallo du, jeg vil gjerne se YouTube nettsiden, har du den til meg?”
  • 🖥️ “Jaha, YouTube? Den skal jeg sende til deg!” (cue sending a crapload of information)
  • 📞 “Tusen takk, jeg ser nettsiden!”

Warning

Dette er ikke en nøyaktig vitenskaplig forklaring.

Altså, ett eller annet har jobben å sende en nettside tilbake til brukeren. Det er der web-serveren, altså Flask-applikasjonen kommer inn i bildet.

Del 1 - Installasjon

PyCharm? Null problem!

Dersom du jobber i PyCharm kan du bare finne prosjekttypen “Flask” og opprette et prosjekt. Dermed kan du hoppe direkte til Del 2. I andre kode-editorer er det nok sannsynlig at du må installere Flask manuelt. Det kan likevel være nyttig å lese det som står her!

Åpne terminalen. Sjekk at kommandolinjen peker til rett mappe.

Skriv inn i terminalen: pip install flask.
Dette installerer flask på din maskin, pip install brukes når vi skal installere eksterne “pakker” eller “biblioteker”.

Lag en ny fil som heter app.py. Deretter plasser følgende kode i denne filen:

# imports
from flask import Flask

# opprett en flask server
app = Flask(__name__)

# vi lager en "rute" for hovedsiden som er "/"
@app.route("/")
def hello():
    return "Hello World!"

# for øyeblikket bruker vi bare dette for å starte programmet
if __name__ == "__main__":
    app.run(debug=True)

Hva gjør denne koden!?

Først så må vi importere Flask. Hvis dette ikke går for deg kan det hende at du gjorde steg 2 feil.

Etterpå må vi lage en app, altså det er en “web-server” som vi kan sende “requests” til. Her er det mange fag-ord, men det viktigste å vite er at det er et program som kan sende og ta i mot data.

Info

Vennligst kall variablen for appen “app”. Du kan teknisk sett kalle den hva som helst, men da er det ikke min feil hvis noe blir forvirrende senere! ☝️🤓

Deretter har vi en funksjon med en “route”. Dette kommer vi tilbake til. Men en route er bare noe som tar inn litt informasjon og sender tilbake noe annet.

Til slutt kjører vi appen med app.run(). debug=True forteller bare Flask at den skal skrive ut ekstra logging for ting som skjer, inkluderer ting som går galt. Når du skal publisere en flask app, husk å endre til debug=False.

Kjør programmet. I terminalen bør dere se at det står en lenke: http://127.0.0.1:5000. Følg denne, enten ved å trykke på den eller skrive den inn i nettleseren, hva kommer opp?

Ingenting skjer!
  • Har du gjort steg 2?
  • Har du installert Python?

Del 2 - Enkle Routes

Nå som vi har en basic app skal vi se på det første Flask-konseptet: “Routes”!

“Route”, hva er det?

En “route”, eller en “retning” er et sted du kan gå på en nettside. For eksempel så kan du ha nettside.no/hjelp, da er “/hjelp” en route.

Easy Oppgave 1 - Basic routes

La oss legge til en basic route. Vi skal lage en route som vil gi deg en vits dersom du skriver /joke i nettside-lenken.

Her må vi ta i bruk et nytt Python-konsept dere ikke har sett før! En decorator. Det er en spesiell funksjon som modifiserer eller utvider funksjonaliteten til en allerede eksisterende funksjon, uten å endre på funksjonen.

Se på den følgende koden:

@app.route("/joke")
def joke():
    return "Why did the chicken cross the road? Buck if I know!"

Her kan du se at vi lagt til @app.route("/joke"). Denne decorator-en forteller til app-en vår at denne funksjonen skal være en route med verdien /joke.

Legg til denne koden etter @app.route("/"). Prøv å kjøre koden, hva skjer? For øyeblikket, ingenting! Men alt du trenger for å hente den fantastisk morsomme vitsen din er å skrive http://127.0.0.1:5000/joke. Da har du fortalt til web-serveren at du skal hente fra /joke.

Løsning: Hele koden så langt
# imports
from flask import Flask

# opprett en flask server
app = Flask(__name__)

# vi lager en "rute" for hovedsiden som er "/"
@app.route("/")
def hello():
    return "Hello World!"

# ny rute for å hente en vits
@app.route("/joke")
def joke():
    return "Why did the chicken cross the road? Buck if I know!"

# for øyeblikket bruker vi bare dette for å starte programmet
if __name__ == "__main__":
    app.run(debug=True)

Vi skal senere se på hvordan vi kan sende hele nettsider via disse i Level 2.

Easy Oppgave 2 - Routes med parametre

Ruter trenger ikke å være statiske. Vi kan faktisk sende inn noe vi kaller parametre til rutene.

Som et eksempel skal vi lage en rute på nettsiden som sier hallo til navnet som blir skrevet inn.

Se på den følgende koden:

@app.route("/hello/<name>")
def hello_name(name):
    return "Hello " + name

Her tar vi i bruk krokodille parenteser for å fortelle at dette skal være et parameter. <name> i dette tilfellet kan ta alle slags verdier.

Legg denne koden inn i app.py, kjør koden, gå til nettleseren og prøv følgende:

http://127.0.0.1:5000/hello/Bob.

Hva skjer? Prøv noen andre navn også!

Løsning: Hele koden så langt
# imports
from flask import Flask

# opprett en flask server
app = Flask(__name__)

# vi lager en "rute" for hovedsiden som er "/"
@app.route("/")
def hello():
    return "Hello World!"

# ny rute for å hente en vits
@app.route("/joke")
def joke():
    return "Why did the chicken cross the road? Buck if I know!"

# hei på deg!
@app.route("/hello/<name>")
def hello_name(name):
    return "Hello " + name

# for øyeblikket bruker vi bare dette for å starte programmet
if __name__ == "__main__":
    app.run(debug=True)
YouTube eksempel

Hvis vi tar YouTube eksemplet fra tidligere så klarer du kanskje å se for deg nhvordan web-serveren vet hvilken video du skal se på.

Litt forenklet så ser YouTube lenker slik ut:

https://www.youtube.com/watch?v=<video_id>

Her vil <video_id> være en parameter, som forteller web-serveren hvilken video den skal sende. Dermed tar web-serveren seg av alt som brukeren vil ha tilbake.

Medium Oppgave 3 - Parameter typer

For øyeblikket når du skriver en parameter med <parameter>, vil verdien alltid tolkes som en string type, altså tekst.

Typer? Hva er det?

Typer er ikke noe vi har snakket så mye om før, men det viktigste å vite er at ikke alle variabler fungerer på samme måten.

Se for deg at du blir spurt om å legge sammen to elefanter og ordet “appelsin”. Hva blir egentlig svaret? Svaret er at det ikke fungerer, siden det ikke gir noe mening fra starten av!

I Python kan vi se på det slik:

antall_elefanter = 2
frukt = "appelsin"

print(antall_elefanter + frukt) # DETTE GÅR IKKE!!

Hvorfor fungerer det ikke?!

Fordi, antall_elefanter og frukt er to helt forskjellige typer. Den ene er et tall (integer eller int på fagspråk), og den andre er tekst (string på fagspråk). Vi kan ikke legge en int og en string sammen!

Route parametre har flere egenskaper. Vi kan spesifisere “typen” til parameteren!

Se på den følgende koden:

@app.route("/calculate/<int:num>")
def calculate(num):
    return str(num * 2)

Denne koden tar inn et tall og ganger det med 2.

Legg denne koden inn i app.py, kjør koden, gå til nettleseren og prøv følgende:

http://127.0.0.1:5000/calculate/3.

Hva får du som svar? Prøv andre tall også å se hva som skjer!

Løsning: Hele koden så langt
# imports
from flask import Flask

# opprett en flask server
app = Flask(__name__)

# vi lager en "rute" for hovedsiden som er "/"
@app.route("/")
def hello():
    return "Hello World!"

# ny rute for å hente en vits
@app.route("/joke")
def joke():
    return "Why did the chicken cross the road? Buck if I know!"

# hei på deg!
@app.route("/hello/<name>")
def hello_name(name):
    return "Hello " + name

# kalkulator!
@app.route("/calculate/<int:num>")
def calculate(num):
    return str(num * 2)

# for øyeblikket bruker vi bare dette for å starte programmet
if __name__ == "__main__":
    app.run(debug=True)

Om return og Flask

Du ser kanskje her at vi skriver return str(num * 2).

Flask forventer alltid å få en gyldig HTTP-respons. Et enkelt tall er ikke en gyldig respons. Flask forventer å få tilbake en string, altså tekst.

Ekstra om return og Flask

Du kan også returnere en status kode her, men det er ikke noe vi skal snakke om nå. Det kan du gjøre ved å skrive return "Hallo", 200. 200 betyr bare at alt gikk fint og som forventet. Hvis du lurer mer på hva status-koder betyr nå sjekk ut Wikipedia Status Codes.

int typen

Legg merke til at her står det <int:num> i parameteren.

Parametre kan bli skrevet på måten: <type:navn>. I denne koden er typen int, som er fagspråk for integer, altså et heltall.

Liste over typer i Flask

Type Hva er det? Eksempler
<string:name> (default) all tekst utenom / "heisann", "Bob", "Kåre"
<int:number> Positive hele tall. 2, 4, 47, 214
<float:decimal> Desimaltall (fagord: flyttall) 2.4, 3.7, 44.213
<path:value> Lik som string men aksepterer også / "heisann/hoppsann"
<uuid:user_id> Tar imot “UUID” strings 550e8400-e29b-41d4-a716-446655440000

Viktig å huske at navnet etter : kan være hva som helst.

Medium Oppgave 4 - Enkel kalkulator

La oss oppgradere calculate routen vår litt! Du kan ta inn flere parametre i en route også! Prøv å legge til to parametre i calculate routen, en som heter num1 og en som heter num2. Deretter, legg sammen tallene å returner dem til nettsiden.

Løsning
@app.route("/calculate/<int:num1>/<int:num2>")
def calculate(num1, num2):
    return str(num1 + num2)

Hard Oppgave 5 - Utvidet kalkulator

Til slutt, prøv å lage en kalkulator der du kan bruke +, -, *, /.

Du kan enten velge å bruke ord som add, subtract, eller tegn.

Prøv å løs det med bare en route! (Du kunne ha lagd def add(num1, num2), men her er vi ute etter at du gjør det med bare def calculate).

Ekstra: pass på at deling på null blir tull.

Løsning
@app.route("/calculate/<int:num1>/<string:op>/<int:num2>")
def calculate(num1, op, num2):
    if op == "add":
        return str(num1 + num2)
    elif op == "subtract":
        return str(num1 - num2)
    elif op == "multiply":
        return str(num1 * num2)
    elif op == "divide":
        # Ekstra, kult hvis du husket dette! 😎
        if num2 == 0:
            return "Can't divide by zero!!"
        return str(num1 / num2)
Løsning: Hele koden
# imports
from flask import Flask

# opprett en flask server
app = Flask(__name__)

# vi lager en "rute" for hovedsiden som er "/"
@app.route("/")
def hello():
    return "Hello World!"

# ny rute for å hente en vits
@app.route("/joke")
def joke():
    return "Why did the chicken cross the road? Buck if I know!"

# hei på deg!
@app.route("/hello/<name>")
def hello_name(name):
    return "Hello " + name

# kalkulator!
@app.route("/calculate/<int:num1>/<string:op>/<int:num2>")
def calculate(num1, op, num2):
    if op == "add":
        return str(num1 + num2)
    elif op == "subtract":
        return str(num1 - num2)
    elif op == "multiply":
        return str(num1 * num2)
    elif op == "divide":
        # Ekstra, kult hvis du husket dette! 😎
        if num2 == 0:
            return "Can't divide by zero!!"
        return str(num1 / num2)

# for øyeblikket bruker vi bare dette for å starte programmet
if __name__ == "__main__":
    app.run(debug=True)

Ekstra oppgaver

Medium Oppgave E1 - Hallo hallo hallo hallo

Gjør om på /hello routen til å gi en unik melding basert på hvem som sier hallo.

Hard Oppgave E2 - Random joke

Gjør om på /joke routen til å hente en tilfeldig vits fra en liste med vitser. (Du trenger ikke så mange, bare vise at det fungerer)

Hard Oppgave E3 - (Enda mer) Utvidet kalkulator

Legg til enda flere funksjoner i kalkulatoren din, som for eksempel, opphøyd i (power), sinus, cosinus, areal kalkulator, eller hva enn du kommer på.

Hard Oppgave E4 - Hva er vitsen?

Utvid /joke routen enda mer til å kunne ta inn en “kategori” av vitser hvor du kan skrive /joke/<category> så får du en vits av den typen. Dersom du skriver bare /joke får du en tilfeldig joke fra hvilken som helst kategori.

Hint

Ta i bruk enten, flere lister (en liste per kategori), eller, bruk et python “Dictionary”. Les om dictionaries her: Python Dictionaries