If you haven't already, read Part 1 and Part 2 in our Flask series. This tutorial is going to pick up where Part 2 left off.
If you followed the instructions correctly, you should have a file called flask_web_app.py with the following code:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home_page():
return render_template('index.html')
And a file called index.html inside a folder called templates with the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodeConda Web App</title>
</head>
<body>
<h1>Welcome to the CodeConda Web App!</h1>
<p>This web app is still in progress.</p>
</body>
</html>
All this code does is serve index.html to http://127.0.0.1:5000 when you run:
flask --app flask_web_app run
That's pretty simple. Let's make things more interesting. We're going to modify index.html to accept input from the user and send it to flask_web_app.py for processing. And then we're going to update flask_web_app.py to accept and process that user input, and update index.html accordingly. Let's start with flask_web_app.py. As an example, we're going to create a simple app that tells the user whether or not a given number is a prime number. First thing, let's add a Python function called is_prime() to flask_web_app.py that returns True if a number is prime and False otherwise. This can go directly above home_page():
def is_prime(number):
if number == 1:
return False
elif number == 2:
return True
else:
for i in range(2, number):
if number % i == 0:
return False
return True
Awesome. Now, before we modify home_page(), we need an additional Python module called requests. Change the first line in the Python file to:
from flask import Flask, render_template, request
Next, update the home_page() function definition and route decorator to:
@app.route("/", methods=("GET", "POST"))
def home_page():
result = ""
if request.method == "POST":
number = int(request.form["number"])
if number < 1:
result = "Please enter a number greater than 0."
elif is_prime(number):
result = "{} is a prime number!".format(number)
else:
result = "{} is NOT a prime number.".format(number)
return render_template('index.html', result=result)
Okay, let's pause to explain exactly what I did here. The first line, which added "methods" to the route decorator, is telling Flask that this function will be completing both GET and POST methods. A GET method is used to send data to the server, which is what we were doing already (we were sending index.html to the server). Flask accepts GET as the default for a route decorator. Now, we're explicitly stating that we'll be doing GET as well as POST. POST is a message in the opposite direction (from the server back to the method). We'll need to do this to capture input from the user.
If you look inside the function, you'll see how the POST method comes into play. One of the first things we do is use the request module to check whether the current function call is for a POST method, and if it is, we use request.form["number"] to capture information from the number field in index.html (we'll add that later). Then we check whether number is prime, and send information back to index.html in the result variable. This is then passed into the render_template() function call as an argument.
Finally, we need to update index.html to accept input from the user:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodeConda Web App</title>
</head>
<body>
<h1>Welcome to the CodeConda Web App!</h1>
<p>Enter any number, and we'll tell you if it's a prime number.</p>
<form method="post">
<div class="form-group">
<input type="number" name="number" id="number" required>
<button type="submit"> Submit</button>
</div>
</form>
{% block content %}
<p>{{ result }}</p>
{% endblock %}
</body>
</html>
There are a few important changes here. First, we've added a form element with method explicitly set to "post". Inside the form element, we have an input element with id and name "number" (this ties back to the "number" field referenced in our Python file). And we also have a button element for submitting the information. Also, we have a weird-looking "block content / endblock" element near the end of the file. Inside the block, you'll see an element called "result" inside two sets of braces. This ties back to the "result" passed in from our home_page() function. Basically, this weird section of code fills in with the information provided by our Python file.
Okay, awesome. Now, all you need to do is save your files and execute the "flask run" command. You should have something like this in the end:
And there you have it! That's how to build a (simple) web app using Flask! Hopefully that was helpful. If you're somewhat lost, I would highly recommend signing up for some of the beginner Python lessons we have on CodeConda. There, an experienced software engineer will walk you through everything you need to know, step-by-step.