Creating a Webapp with Flask
Have you ever wanted to build a website from scratch? We will go over how to set up your own web app, including the use of databases, forms and CSS to make it nice and pretty.
Introduction
To create a project, we will first need to have the flask
package installed and a folder housing all of the files we will create. The first thing we will need is a “templates” folder containing HTML files that will represent the three pages we will have. To give an idea of what these files look like, the main page’s HTML has been included below. Note that the tags in the format { % % } are from Jinja, a templating engine that makes creating these files a bit easier.
<!doctype html>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>{% block title %}Home{% endblock %} - Message Bank</title>
<nav>
<h1>Message Bank</h1>
<!-- <b>Navigation:</b> -->
<ul>
<li><a href="{{url_for('submit')}}">Submit a message</a></li>
<li><a href="{{url_for('view')}}">View messages</a></li>
</ul>
</nav>
<section class="content">
<header>
{% block header %}{% endblock %}
</header>
{% block content %}
<p>Hello! Click the first link to submit a message, or click the second link to see what others have said!</p>
{% endblock %}
</section>
After creating that file, you can (somewhat) view it if you open the file in Google Chrome or another browser. The Jinja tags won’t be processed, though, so they will just appear as regular text. This file sets up a very basic website titled “Home - Message Bank”, with two links to the “submit” and “view” pages that we will create later.
Starting Flask
Before we can view the full webpage, we need to create a file called “app.py” where we can use Flask. In it, we need to import all the appropriate packages and create an app.
from flask import Flask, render_template, g, request
import sqlite3
# Creates app with file name
app = Flask(__name__)
Next, we create a function that allows the user to view the main page. The following code essentially states that the main page will appear however the HTML in the file “base.html” appears.
# Creates a home page
@app.route("/")
def main():
return render_template("base.html")
With this, we can start up Flask! In the terminal or Anaconda Prompt, type export FLASK_ENV=development
then flask run
. Note that on a Windows system, you will need to replace the word export
with set
or else it won’t work properly. The terminal will then give a link for which you can view the page! We will omit the creation of the other two HTML files for the submission page and the page to view messages; the process to create them can be tedious and requires constant changing, so documenting it all at once (and in the beginning) would not be proper. However, they appear very similar to the HTML shown above.
Database Functions
For this project, we will be retrieving data from the user, storing it in a database, and posting some of that data.
The first function creates a connection to a database and stores it for the current session. What this does is create the connection in a “variable” called g
that will be remembered for as long as the session is running. It then returns a connection to that database.
def get_message_db():
# Connect to the db if it is not yet
if "message_db" not in g:
g.message_db = sqlite3.connect("messages_db.sqlite")
cursor = g.message_db.cursor()
# make the following table if it is not made yet
cmd = """
CREATE TABLE IF NOT EXISTS messages
(id int, message text, handle text)
"""
cursor.execute(cmd)
return g.message_db
The second function we will use will be for taking whatever the user inputted on the submission page and inputting it in the database. When we do request.form["message"]
, we are taking the data inputted into the text box with HTML attribute name="message"
and setting it to the Python variable message
. We then input it, along with their handle
, into the database and return the two items in a list.
def insert_message(request):
# Gets info from the form submitted once user submits message
message = request.form["message"]
handle = request.form["handle"]
cursor = get_message_db().cursor()
# Gives each entry a unique id
row_count = cursor.execute("SELECT COUNT(*)+1 FROM messages;").fetchone()
cmd = """
INSERT INTO messages (id, message, handle)
VALUES (?, ?, ?)
"""
cursor.execute(cmd, (row_count[0], message, handle))
# Make sure the action is committed and saved:
g.message_db.commit()
g.message_db.close()
return [message, handle]
The third and final function we will need will retrieve at most n
messages from our database and return them.
def random_message(n):
cursor = get_message_db().cursor()
# Get n random messages and handles from the table
cmd = """
SELECT message, handle FROM messages ORDER BY RANDOM() LIMIT ?;
"""
info = cursor.execute(cmd, (n,)).fetchall()
return info
Next, we move on to making our Python file recognize the other two HTML files.
Connecting New Pages
The way we make our code connect to the other HTML files is with the following code. The first one will link to “submit.html”, the page used to submit messages. The methods
argument states that we can both send and retrieve data. If we are sending data (ie the user clicked the submit button), we take their message and call the insert_message
function, then render that HTML file while also passing in the message and handle they submitted.
If we arrived to this page without submitting the form, then it will show the basic “submit.html” page without passing in the message and handle. In the HTML file, we use Jinja syntax like {{ message }} to retrieve the value of that variable and display it on the page.
# Creates page that lets users submit messages
@app.route("/submit", methods=["POST", "GET"])
def submit():
# If the page is loaded after submitting a message:
if request.method == "POST":
msg = insert_message(request)
return render_template("submit.html",
message = msg[0],
handle = msg[1])
# If we're just viewing the page and didn't submit a form
else: # request.method == "GET"
return render_template("submit.html")
Lastly, we need to create the connection with the page of message submissions. What the following code block does is make the webpage with extension “/view” viewable. It also retrieves 5 random messages and sends it to our “view.html” file. In that file, it will loop through msgs
and neatly write out those messages.
# Creates page that lets users view messages
@app.route("/view", methods=["GET"])
def view():
msgs = random_message(5)
return render_template("view.html", msgs=msgs)
Viewing the Webpage
We are finally able to view the page! Using the link given in the terminal after running Flask, we will be able to see the following page that allows users to submit a message and their name or handle.
Lastly, we can see what the few submissions are. We can also see that the header fonts are updated to Verdana and the rest of the body is Arial, and there is also a nice pink background as well.
With these simple tools, we were able to make a website that takes in user input and displays it! With more time spent on designing, you can make a sleek and modern page. But for now, this will do.
This project, along with all the associated files created to make the web app, can be found on GitHub at https://github.com/michaelvchid/Flask-message-bank.