Flask Webserver

  • Flask-App app.py in Hauptordner
  • HTML-Seite index.html in Unterordner templates
  • CSS- & JavaScript-Files style.css & script.js in Unterordner static
app.py
from flask import Flask, render_template, request, jsonify # import the Flask object from the flask package
import datetime
import random
 
app = Flask(__name__) # create Flask application instance with name 'app' (name of python file)
#app.debug = True
 
# HTTP REQUESTS AND RESPONSES
# return root resource index.html for first get request "GET /"
@app.route('/') # '/' means that this fcn responds to request for URL /, which is main URL
def index():
    return render_template('index.html') # can also pass dictionary with data as argument: ...('index.html', data=data_dict)
 
@app.route('/interactWithServer', methods = ['POST'])
def do_something(): # is executed whenever client sends request with "let response = await fetch('/interactWithServer', {...."
    data = request.json['data'] # save data sent by JS in variable
    # do something with data
    # e.g. create dictionary with response data
    data_response = {"name":"Johanna", "age":42}
    return data_response
 
if __name__ == '__main__':
    app.run()
 
"""
typical shape
@app.route(...) # this decorator turns a ...
def some_fcn(): # ... regular Python function into a Flask view function which ...
    ...
    return ...  # ... converts the function's return value into an HTTP response)
"""
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <link href="/static/style.css" type="text/css" rel="stylesheet">
    <script src="static/script.js" async></script>
</head>
 
<body>
    ...
</body>
</html>

Hier wollen wir anschauen, wie man eine HTTP-Anfrage (Request) an einen Server stellt, um z.B. gewisse Daten zu erhalten. Eine solche Anfrage über das Web dauert ihre Zeit. Damit die ganze Website nicht einfriert bis die Antwort vom Server eingetroffen ist, sollte man seinen Code asynchron programmieren. D.h. die Website kann auch anderweitig weiterverwendet werden, während sie noch auf eine Antwort wartet. Dies realisiert man mit async und await.

Einen einfachen HTTP-Request sendet man dann wie folgt:

async function sendRequest() {
    const url = 'https://www.wiewarm.ch/api/v1/bad.json/16'; // state url
 
    let fetched = fetch(url);
    // The fetch(url) function initiates a fetch request to the specified URL.
    // It returns a PROMISE that resolves to the response to that request.
 
    let response = await fetched;
    // The await keyword pauses the execution of the function until the Promise
    // returned by fetch(url) is resolved. In this case, it's waiting for the
    // HTTP request to complete and the response to be available.
 
    console.log(response.status) // print response status, e.g. "ok"
 
    let json_data = await response.json();
    // Once the response is available, await response.json() is used to parse the
    // response as JSON. Again, we use await to pause until the JSON parsing is complete.
 
    console.log(json_data);
    // do something with data
}

In fetch wird die URL angegeben, von der etwas gefetched werden soll. Dies kann eine fremde Website sein wie let url = https://www.wiewarm.ch/api/v1/bad.json/16'; oder ein Endpoint für den eigenen Server, z.B. const url = '/dothis';

Oft möchte man einem HTTP-Request auch Daten anhängen, die dann vom Server verarbeitet werden sollen. Dazu modifiziert man den fetch-Befehl wie folgt:

fetch(url, {
    method: 'POST', // because want to send data to server s.t. it can process it
    headers: { // tells server that request body contains json data
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({data: dataSend}) // data sent to server
})

Es gibt auch noch eine alternative Variante für das Senden eines HTTP-Requests, die obige Variante mit asynv & await ist aber zu bevorzugen.

Alternativer Syntax für HTTP-Request

Sendet man einen HTTP-Request an seinen Flask-Server, kann man diesen wie folgt bearbeiten:

@app.route('/dothis', methods = ['POST'])
def do_this():
    ...
    return {"data": return_data} # data returned to website

Flask Tutorial (Version 2)

Create the following files and folders:

  • app.py
  • templates / index.html
  • static / style.css
  • static / script.js
  • Install Flask with pip
  • Just run app.py, then click on the link and the website should open.
snippet.python
from flask import Flask, render_template, request, jsonify # import the Flask object from the flask package
import datetime
import random
 
app = Flask(__name__) # create Flask application instance with name 'app' (name of python file)
#app.debug = True
 
# HTTP REQUESTS AND RESPONSES
# return root resource index.html for first get request "GET /"
@app.route('/') # '/' means that this fcn responds to request for URL /, which is main URL
def index():
    return render_template('index.html') # can also pass dictionary with data as argument: ...('index.html', data=data_dict)
 
@app.route('/interactWithServer', methods = ['POST'])
def do_something():
    data = request.json['data'] # save data sent by JS in variable
    # do something with data
    # e.g. create dictionary with response data
    data_response = {"name":"Johanna", "age":42}
    return data_response
 
if __name__ == '__main__':
    app.run()
 
 
"""
typical shape
@app.route(...) # this decorator turns a ...
def some_fcn(): # ... regular Python function into a Flask view function which ...
    ...
    return ...  # ... converts the function's return value into an HTTP response)
"""
snippet.html
<!-- I'm sure you know how a html file looks like ;) -->
 
<!-- can access dictionary with data that is passed as argument (see app.py above) -->
<p>My data: {{ data.name_of_key }}</p>
snippet.js
// access html elements from withing JS
let htmlElement = document.getElementById("idOfMyHtmlElement");
 
// function that interacts with flask server app
async function somethingHasHappened(word){
    // send post request to server
    let response = await fetch('/interactWithServer', {
        method: 'POST', // because want to send data to server s.t. it can process it
        headers: { // tells server that request body contains json data
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({"name":"John", "age":41}) // data sent to server
    });
 
    // write response status (hopefully not 404!) into console
    console.log(response.status); 
 
    // wait for server's response, then access data sent back
    let json_data = await response.json();
 
    // now do something with data
    htmlElement.innerHTML = json_data.nameOfKey;
}
 
// function that is executed on even
function somethingHasHappened(event){
    // call function that interacts with server
    interactWithServer(inpPlainText.value);
}
 
// add event listeners (clicking button, typing something into input box, ...)
htmlElement.addEventListener('input',somethingHasHappened)
  • talit/flask_webserver.1702912741.txt.gz
  • Zuletzt geändert: 2023-12-18 15:19
  • von sca