Introduction to Web Applications: Code
app.py
from flask import Flask, render_template, request, redirect, url_for
import sqlite3
from pprint import pprint
# remember to $ pip install flask
connection = sqlite3.connect("pets.db", check_same_thread=False)
print("succeeded in making connection.")
app = Flask(__name__)
@app.route("/", methods=["GET"])
@app.route("/hello", methods=["GET"])
@app.route("/hello/<name>", methods=["GET"])
def get_hello(name="world"):
# return f"<html><h1>Hello, {name}!<html>"
return render_template("hello.html", name=name)
@app.route("/bye", methods=["GET"])
def get_bye():
return "Bye!"
@app.route("/pets", methods=["GET"])
def get_pets():
# list = ["alpha","beta","gamma"]
# return render_template("list.html", list=list)
cursor = connection.execute("select * from pet")
rows = cursor.fetchall()
pprint(rows)
return render_template("pets.html", pets=rows)
@app.route("/create", methods=["GET"])
def get_create():
return render_template("create.html")
@app.route("/create", methods=["POST"])
def post_create():
data = dict(request.form)
connection.execute("""insert into pet(name, kind, age, food) values (?,?,?,?)""",
(data["name"],data["kind"],data["age"],data["food"]))
connection.commit()
return redirect(url_for("get_pets"))
@app.route("/update", methods=["GET"])
@app.route("/update/<id>", methods=["GET"])
def get_update(id=None):
if id==None:
return render_template("error.html", error_message="No ID was provided.")
id = int(id)
cursor = connection.cursor()
cursor.execute("""select * from pet where id = ?""",(id,))
rows = cursor.fetchall()
try:
(id, name, kind, age, food) = rows[0]
data = {
"id":id,
"name":name,
"kind":kind,
"age":age,
"food":food
}
print([data])
except:
return render_template("error.html", error_message="Data not found.")
return render_template("update.html",data=data)
@app.route("/update", methods=["POST"])
@app.route("/update/<id>", methods=["POST"])
def post_update(id=None):
if id==None:
return render_template("error.html", error_message="No ID was provided.")
id = int(id)
data = dict(request.form)
try:
data["age"] = int(data["age"])
except:
data["age"] = 0
cursor = connection.cursor()
cursor.execute("""update pet set name=?, kind=?, age=?, food=? where id=?""",
(data["name"],data["kind"],data["age"],data["food"],id))
connection.commit()
return redirect(url_for("get_pets"))
@app.route("/delete/<id>", methods=["GET"])
def get_delete(id):
id = int(id)
cursor = connection.execute("""delete from pet where id==?""",(id,))
connection.commit()
return redirect(url_for("get_pets"))
example.txt
https:// <= protocol
https://mywebsite.com <== DNS address of the url
mywebsite.com --> 123.12.45.16 <== IP address
https://123.12.45.16 <== the "machine" that houses the web server
https://mywebsite.com:563 <== port number -- usually implied
https://mywebsite.com/mypage <-- route = "/mypage"
https://mywebsite.com/mypage/foo <-- route = "/mypage/foo"
https://mywebsite.com/catalog/blenders <-- route = "/catalog/blenders"
Tell the server to take the route apart and search for blenders
https://mywebsite.com/catalog?category="blenders" <-- using parameters
https://mywebsite.com/catalog?category="blenders"&brand="KitchenAid" <-- using multiple parameters
pets.db
This is a binary data file. It is available in the repository linked below.
templates/create.html
<html>
<head></head>
<body>
This is the create template.
<form action="/create" method="post">
<hr/>
<p>Pet Name:<input name="name"/></p>
<p>Kind:<input name="kind"/></p>
<p>Age:<input name="age"/></p>
<p>Food:<input name="food"/></p>
<hr/>
<button type="submit">Create</button>
<a href="/pets">Cancel</a>
<hr/>
</form>
</body>
</html>templates/error.html
<html>
<head>
<title>Pet List</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body><H1>ERROR</H1>
<hr/>
<em>{{error_message}}</em>
<hr>
<a href="/pets">OK</a>
</body>
</html>templates/hello.html
<html>
<body>Hello, {{ name }}! (from the template)</body>
</html>templates/list.html
<html>
<body><H1>The List</H1>
{{ list }}
<ul>{% for item in list %}
<li>{{item}}</li>
{% endfor %}
</ul>
</body>
</html>templates/pets.html
<html>
<head>
<title>Pet List</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined"/>
</head>
<body><H1>Pets</H1>
<hr/>
<table class="table table-striped">
<tr>
<th>ID</th>
<th>Name</th>
<th>Kind</th>
<th>Age</th>
<th>Food</th>
<th></th>
<th></th>
</tr>
{% for pet in pets %}
<tr>
{% for item in pet %}
<td>{{ item }}</td>
{% endfor %}
<td><a href="/update/{{pet[0]}}"><span class="material-symbols-outlined">edit</span></a></td>
<td><a href="/delete/{{pet[0]}}"><span class="material-symbols-outlined">delete</span></a></td>
</tr>
{% endfor %}
</table>
<hr/>
<a href="/create"><span class="material-symbols-outlined">add_circle</span></a>
</body>
</html>templates/update.html
<html>
<head></head>
<body>
This is the update template for ID={{data["id"]}}
<form action="/update/{{data['id']}}" method="post">
<hr/>
<p>Pet Name:<input name="name" value="{{data['name']}}"/></p>
<p>Kind:<input name="kind" value="{{data['kind']}}"/></p>
<p>Age:<input name="age" value="{{data['age']}}"/></p>
<p>Food:<input name="food" value="{{data['food']}}"/></p>
<hr/>
<button type="submit">Update</button>
<a href="/pets">Cancel</a>
<hr/>
</form>
</body>
</html>The files are available in the course repository.