├── README.md
├── lab_02_Blueprints
├── run.py
├── __init__.py
├── config.py
├── templates
│ └── app
│ │ ├── save.html
│ │ ├── register.html
│ │ ├── add.html
│ │ ├── edit.html
│ │ └── students.html
├── app
│ ├── serialize.py
│ ├── models.py
│ └── views.py
└── utils
│ └── serialize.py
├── lab_04_RESTful_Client
├── get_requests.py
├── delete_requests.py
├── post_requests.py
├── show_students.html
└── receive.html
├── lab_01_Helloworld
└── main.py
├── lab_02_Building_Web_Applications_with_Flask
├── templates
│ ├── save.html
│ ├── register.html
│ ├── add.html
│ ├── edit.html
│ └── students.html
├── serialize.py
├── models.py
└── views.py
├── .gitignore
├── lab_08_ORM
├── database.py
├── dbtest.py
└── models.py
├── lab_03_RESTful_via_Flask
├── print_request_headers.py
└── main.py
├── lab_06_Authentication
├── auth.py
└── main.py
├── lab_05_Visualization_via_D3
├── main.py
└── index.html
└── lab_07_MongoDB
├── dbtest.py
└── models.py
/README.md:
--------------------------------------------------------------------------------
1 | # comp9321
2 | COMP9321, UNSW Sydney
3 | Data Services Engineering Lab
4 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/run.py:
--------------------------------------------------------------------------------
1 | from lab_02_Blueprints import app
2 |
3 | app.config.from_object('config')
4 | app.run()
5 |
--------------------------------------------------------------------------------
/lab_04_RESTful_Client/get_requests.py:
--------------------------------------------------------------------------------
1 | import requests
2 | response = requests.get("http://localhost:5000/statistics", params=None)
3 | print("statistics:", response.json())
4 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/__init__.py:
--------------------------------------------------------------------------------
1 | from lab_02_Blueprints.app.views import bp as controllers
2 | from flask import Flask
3 | app = Flask(__name__)
4 | app.register_blueprint(controllers)
5 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | DEBUG = True
4 | BASE_DIR = os.path.abspath(os.path.dirname(__file__))
5 | SECRET_KEY = "SPECIFY_YOUR_OWN_SECRET_KEY2"
6 | SESSION_TYPE = "filesystem"
7 |
--------------------------------------------------------------------------------
/lab_01_Helloworld/main.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 |
3 | app = Flask(__name__)
4 |
5 |
6 | @app.route("/")
7 | def hello():
8 | return "Hello World!"
9 |
10 |
11 | if __name__ == "__main__":
12 | app.run()
13 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/templates/app/save.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Saved
6 |
7 |
8 | Return to the students page
9 |
10 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/templates/save.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Saved
6 |
7 |
8 |
9 | Return to the students page
10 |
11 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/app/serialize.py:
--------------------------------------------------------------------------------
1 | import codecs
2 | import pickle
3 |
4 |
5 | def serialize(object):
6 | return codecs.encode(pickle.dumps(object, pickle.HIGHEST_PROTOCOL), "base64").decode()
7 |
8 |
9 | def deserialize(object_string):
10 | return pickle.loads(codecs.decode(object_string.encode(), "base64"))
11 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/utils/serialize.py:
--------------------------------------------------------------------------------
1 | import codecs
2 | import pickle
3 |
4 |
5 | def serialize(object):
6 | return codecs.encode(pickle.dumps(object, pickle.HIGHEST_PROTOCOL), "base64").decode()
7 |
8 |
9 | def deserialize(object_string):
10 | return pickle.loads(codecs.decode(object_string.encode(), "base64"))
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | .gitignore
3 | .idea/
4 | lab_02_Building_Web_Applications_with_Flask/__pycache__/
5 | lab_02_Blueprints/__pycache__/
6 | lab_02_Blueprints/app/__pycache__/
7 | lab_02_Blueprints/utils/__pycache__/
8 | lab_07_orm/__pycache__/
9 | lab_08_authentication/__pycache__/
10 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/serialize.py:
--------------------------------------------------------------------------------
1 | import codecs
2 | import pickle
3 |
4 |
5 | def serialize(object):
6 | return codecs.encode(pickle.dumps(object, pickle.HIGHEST_PROTOCOL), "base64").decode()
7 |
8 |
9 | def deserialize(object_string):
10 | return pickle.loads(codecs.decode(object_string.encode(), "base64"))
11 |
--------------------------------------------------------------------------------
/lab_04_RESTful_Client/delete_requests.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | john = {
4 | "name": "John",
5 | "grade": 95
6 | }
7 | URL = 'http://localhost:5000/students/' + john["name"]
8 | result = requests.delete(URL, headers={"Content-Type": "application/json"})
9 | if not result.ok:
10 | print("status code", result.status_code)
11 | print(result.text)
12 | quit()
13 | else:
14 | print(result.text)
15 |
--------------------------------------------------------------------------------
/lab_08_ORM/database.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import create_engine
2 | from sqlalchemy.ext.declarative import declarative_base
3 | from sqlalchemy.orm import scoped_session, sessionmaker
4 |
5 | Base = declarative_base()
6 | engine = create_engine('sqlite:///:memory:', echo=True)
7 | db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
8 | Base.query = db_session.query_property()
9 |
10 |
11 | def init_db():
12 | # create tables
13 | Base.metadata.create_all(bind=engine)
14 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/models.py:
--------------------------------------------------------------------------------
1 | class Teacher:
2 | def __init__(self, name, course, students={}):
3 | super().__init__()
4 | self.name = name
5 | self.course = course
6 | self.students = students
7 |
8 |
9 | class Student:
10 | def __init__(self, id, first_name, last_name, gender='MALE'):
11 | super().__init__()
12 | self.id = id
13 | self.first_name = first_name
14 | self.last_name = last_name
15 | self.gender = gender
16 |
17 |
--------------------------------------------------------------------------------
/lab_08_ORM/dbtest.py:
--------------------------------------------------------------------------------
1 | from lab_08_ORM.database import db_session, init_db
2 | from lab_08_ORM.models import Teacher, Student
3 |
4 | init_db()
5 |
6 | t1 = Teacher('Helen', 'Paik', {1: Student(1, "Ali", "Hasan")})
7 | t2 = Teacher('John', 'Hard')
8 |
9 | # add teachers to the database
10 | db_session.add(t1)
11 | db_session.add(t2)
12 |
13 | # commit the changes
14 | db_session.commit()
15 |
16 | # query the database
17 | for t in Teacher.query.all():
18 | print("Teacher:", t.name, " Number of Students:", len(t.students))
19 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/templates/app/register.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Register
6 |
7 |
8 |
21 |
22 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/app/models.py:
--------------------------------------------------------------------------------
1 | class Teacher:
2 |
3 | def __init__(self, name, course, students={}, username=None, password=None):
4 | super().__init__()
5 | self.password = password
6 | self.username = username
7 | self.name = name
8 | self.course = course
9 | self.students = students
10 |
11 |
12 | class Student:
13 | def __init__(self, id, first_name, last_name, gender='MALE'):
14 | super().__init__()
15 | self.id = id
16 | self.first_name = first_name
17 | self.last_name = last_name
18 | self.gender = gender
19 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/templates/register.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Register
6 |
7 |
8 |
21 |
22 |
--------------------------------------------------------------------------------
/lab_04_RESTful_Client/post_requests.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | john = {
4 | "name": "John",
5 | "grade": 95
6 | }
7 |
8 | result = requests.post("http://localhost:5000/students", json=john, headers={"Content-Type": "application/json"})
9 | if not result.ok:
10 | print("status code", result.status_code)
11 | print(result.text)
12 | quit()
13 | else:
14 | print(result.text)
15 |
16 | susan = {
17 | "name": "Susan",
18 | "grade": 100
19 | }
20 |
21 | result = requests.post("http://localhost:5000/students", json=susan)
22 | if not result.ok:
23 | print("status code", result.status_code)
24 | print(result.text)
25 | quit()
26 | else:
27 | print(result.text)
28 |
29 | result = requests.get("http://localhost:5000/statistics", params=None)
30 | print("statistics : ", result.json())
31 |
--------------------------------------------------------------------------------
/lab_08_ORM/models.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import Column, Integer, String
2 | from sqlalchemy import PickleType
3 |
4 | from lab_08_ORM.database import Base
5 |
6 |
7 | class Teacher(Base):
8 | __tablename__ = 'teachers'
9 |
10 | id = Column(Integer, primary_key=True, autoincrement=True)
11 | name = Column(String)
12 | course = Column(String)
13 | students = Column(PickleType)
14 |
15 | def __init__(self, name, course, students={}):
16 | super().__init__()
17 | self.name = name
18 | self.course = course
19 | self.students = students
20 |
21 |
22 | class Student:
23 | def __init__(self, id, first_name, last_name, gender='MALE'):
24 | super().__init__()
25 | self.id = id
26 | self.first_name = first_name
27 | self.last_name = last_name
28 | self.gender = gender
29 |
--------------------------------------------------------------------------------
/lab_03_RESTful_via_Flask/print_request_headers.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify
2 | import dicttoxml
3 |
4 | app = Flask(__name__)
5 |
6 |
7 | @app.route("/")
8 | def print_headers():
9 | # Print the KEY-VALUES in the request header
10 | print(request.headers)
11 |
12 | # Find & return the header key-values
13 | headers = {}
14 | for h in request.headers.environ:
15 | header_key = h.replace("HTTP_", "")
16 | header_value = request.headers.get(header_key)
17 | if header_value is not None:
18 | headers[header_key] = header_value
19 |
20 | client_accepted_response_format = headers.get('ACCEPT')
21 | if client_accepted_response_format == "text/xml":
22 | return dicttoxml.dicttoxml(headers), 200, {"Content-Type": "text/xml"}
23 |
24 | return jsonify(headers)
25 |
26 |
27 | if __name__ == '__main__':
28 | app.run(debug=True)
29 |
--------------------------------------------------------------------------------
/lab_06_Authentication/auth.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 | from flask import request, jsonify
4 | from flask_restful import abort
5 | from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer)
6 |
7 | SECRET_KEY = "A RANDOM KEY"
8 |
9 |
10 | def authenticate_by_token(token):
11 | if token is None:
12 | return False
13 | s = Serializer(SECRET_KEY)
14 | try:
15 | username = s.loads(token.encode())
16 | if username == 'admin':
17 | return True
18 | except:
19 | return False
20 |
21 | return False
22 |
23 |
24 | def login_required(f, message="You are not authorized"):
25 | @wraps(f)
26 | def decorated_function(*args, **kwargs):
27 |
28 | token = request.headers.get("AUTH_TOKEN")
29 | if authenticate_by_token(token):
30 | return f(*args, **kwargs)
31 |
32 | return jsonify(message=message), 401
33 | # abort(401, message=message)
34 |
35 | return decorated_function
36 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/templates/app/add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
34 |
35 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/templates/add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
34 |
35 |
--------------------------------------------------------------------------------
/lab_05_Visualization_via_D3/main.py:
--------------------------------------------------------------------------------
1 | from collections import deque
2 | from flask import Flask
3 | import datetime
4 | import threading
5 | import time
6 | import psutil as psutil
7 | from jsonpickle import json
8 |
9 | app = Flask(__name__)
10 | mem_history = deque(maxlen=60)
11 |
12 |
13 | def record_mem():
14 | while True:
15 | if len(mem_history) == 60:
16 | mem_history.pop()
17 | date = datetime.datetime.now()
18 | date = int(date.timestamp())
19 | mem_history.append({'date': date, 'memory_usage': psutil.virtual_memory().percent})
20 | time.sleep(10)
21 |
22 |
23 | t = threading.Thread(target=record_mem)
24 | t.daemon = True
25 | t.start()
26 |
27 |
28 | @app.route("/mem", methods=['GET'])
29 | def get_memory_history():
30 | history = list(mem_history)
31 | # to allow external access to the endpoint you need to add 'Access-Control-Allow-Origin': '*' to the headers
32 | return json.dumps(history), 200, {'Access-Control-Allow-Origin': '*'}
33 |
34 |
35 | if __name__ == '__main__':
36 | app.run(debug=True)
37 |
--------------------------------------------------------------------------------
/lab_04_RESTful_Client/show_students.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Show Students
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lab_07_MongoDB/dbtest.py:
--------------------------------------------------------------------------------
1 | from mongoengine import connect
2 |
3 | from lab_07_MongoDB.models import Teacher, Student
4 |
5 | from mongoengine import connect
6 | from lab_07_MongoDB.models import Teacher, Student
7 |
8 |
9 | def save_information():
10 | t1 = Teacher(1, 'Helen', 'Paik', [Student(1, "Tom", " Ainsley")])
11 | t2 = Teacher(2, 'John', 'Hardy')
12 | connect('teacher') # add teachers to the database
13 | t1.save()
14 | t2.save()
15 |
16 |
17 | def get_all_teachers():
18 | connect('teacher')
19 | for t in Teacher.objects:
20 | print(t.id, t.name)
21 |
22 |
23 | def get_one_teacher():
24 | connect('teacher')
25 | for t in Teacher.objects(id=1):
26 | print(t.id, t.name)
27 |
28 |
29 | def update_teacher_info():
30 | connect('teacher')
31 | Teacher.objects(id=2).update(name='George')
32 |
33 |
34 | def delete_teacher_info():
35 | connect('teacher')
36 | Teacher.objects(id=2).Delete()
37 |
38 |
39 | if __name__ == '__main__':
40 | save_information()
41 | get_all_teachers()
42 | delete_teacher_info()
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/templates/app/edit.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
34 |
35 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/templates/edit.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
34 |
35 |
--------------------------------------------------------------------------------
/lab_07_MongoDB/models.py:
--------------------------------------------------------------------------------
1 | from mongoengine import StringField, IntField, Document, EmbeddedDocument, ListField, EmbeddedDocumentField
2 |
3 |
4 | class Student(EmbeddedDocument):
5 | id = IntField(required=True, primary_key=True)
6 | first_name = StringField(required=True, max_length=50)
7 | last_name = StringField(required=True, max_length=50)
8 | gender = StringField(required=True, max_length=50)
9 |
10 | def __init__(self, id, first_name, last_name, gender='MALE', *args, **kwargs):
11 | super().__init__(*args, **kwargs)
12 | self.id = id
13 | self.first_name = first_name
14 | self.last_name = last_name
15 | self.gender = gender
16 |
17 |
18 | class Teacher(Document):
19 | id = IntField(required=True, primary_key=True)
20 | name = StringField(required=True, max_length=50)
21 | course = StringField(required=True, max_length=50)
22 | students = ListField(EmbeddedDocumentField(Student))
23 |
24 | def __init__(self, id, name, course, students=[], *args, **values):
25 | super().__init__(*args, **values)
26 | self.id = id
27 | self.name = name
28 | self.course = course
29 | self.students = students
30 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/templates/app/students.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Students List
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Student List
14 |
15 |
16 |
17 |
18 | |
19 | |
20 | ID |
21 | Gender |
22 | First Name |
23 | Last Name |
24 |
25 |
26 | {% for s in students: %}
27 |
28 | |
29 | |
30 | {{s.id}} |
31 |
32 | | {{s.first_name}} |
33 | {{s.last_name}} |
34 |
35 |
36 | {% endfor %}
37 |
38 |
39 |
40 |
41 | New
42 | Save
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/templates/students.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Students List
6 |
7 |
8 |
9 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Student List
23 |
24 |
25 |
26 |
27 | |
28 | |
29 | ID |
30 | Gender |
31 | First Name |
32 | Last Name |
33 |
34 |
35 | {% for s in students: %}
36 |
37 | |
38 | |
39 | {{s.id}} |
40 |
41 | | {{s.first_name}} |
42 | {{s.last_name}} |
43 |
44 |
45 | {% endfor %}
46 |
47 |
48 |
49 |
50 | New
51 | Save
52 |
53 |
54 |
--------------------------------------------------------------------------------
/lab_05_Visualization_via_D3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
104 |
--------------------------------------------------------------------------------
/lab_03_RESTful_via_Flask/main.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 | from flask import jsonify
3 | from flask_restful import reqparse
4 |
5 | app = Flask(__name__)
6 | database = []
7 |
8 |
9 | class Student:
10 | def __init__(self, name, grade):
11 | self.name = name
12 | self.grade = grade
13 |
14 |
15 | class Statistics:
16 | min = None
17 | max = None
18 | average = 0
19 | num_of_students = 0
20 |
21 |
22 | def statistics():
23 | """
24 | This function gets through the all student objects in the database
25 | and calculates min, max, average, and total number of students.
26 | :return: Statistics
27 | """
28 | stats = Statistics()
29 | stats.num_of_students = len(database)
30 |
31 | if stats.num_of_students == 0:
32 | return stats
33 |
34 | stats.max = database[0].grade
35 | stats.min = database[0].grade
36 | sum = 0
37 | for student in database:
38 | sum += student.grade
39 | if student.grade < stats.min:
40 | stats.min = student.grade
41 | if student.grade > stats.max:
42 | stats.max = student.grade
43 |
44 | stats.average = sum / stats.num_of_students
45 | return stats
46 |
47 |
48 | @app.route("/students", methods=['POST'])
49 | def add_student():
50 | parser = reqparse.RequestParser()
51 | parser.add_argument('name', type=str)
52 | parser.add_argument('grade', type=int)
53 | args = parser.parse_args()
54 |
55 | name = args.get("name")
56 | grade = args.get("grade")
57 |
58 | database.append(Student(name, grade))
59 | return jsonify(studentName= name),200
60 |
61 |
62 | @app.route("/students", methods=['GET'])
63 | def get_students():
64 | response = jsonify([st.__dict__ for st in database])
65 | response.headers._list.append(('Access-Control-Allow-Origin', '*'))
66 | return response
67 |
68 |
69 | @app.route("/students/", methods=['GET'])
70 | def get_student(name):
71 | for st in database:
72 | if st.name == name:
73 | return jsonify(st.__dict__)
74 |
75 | return jsonify(name=False), 404
76 |
77 |
78 | @app.route("/students/", methods=['DELETE'])
79 | def delete_student(name):
80 | for st in database:
81 | if st.name == name:
82 | database.remove(st)
83 | return jsonify(studentName=name), 200
84 | return jsonify(studentName=False), 200
85 |
86 |
87 | @app.route("/students/", methods=['POST'])
88 | def update_student(name):
89 | parser = reqparse.RequestParser()
90 | parser.add_argument('grade', type=int)
91 | args = parser.parse_args()
92 | grade = args.get("grade")
93 |
94 | for st in database:
95 | if st.name == name:
96 | database.remove(st)
97 | database.append(Student(name, grade))
98 | return jsonify(studentName=name, studentGrade=grade), 201
99 |
100 | return jsonify(studentName=False), 404
101 |
102 |
103 | @app.route("/statistics", methods=['GET'])
104 | def get_statistics():
105 | return jsonify(statistics().__dict__)
106 |
107 |
108 | if __name__ == "__main__":
109 | app.run()
110 |
--------------------------------------------------------------------------------
/lab_02_Blueprints/app/views.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | from flask import Blueprint
4 | from flask import request, render_template, redirect, url_for, make_response, session, Flask
5 |
6 | from lab_02_Blueprints.app.models import Teacher, Student
7 | from lab_02_Blueprints.utils.serialize import deserialize, serialize
8 |
9 | bp = Blueprint('app', __name__, url_prefix='')
10 |
11 |
12 | @bp.route('/', methods=['GET'])
13 | def index():
14 | teacher = retrieve_teacher()
15 | if teacher is None:
16 | return redirect(url_for(".register"))
17 |
18 | return redirect(url_for(".show_students"))
19 |
20 |
21 | @bp.route('/register', methods=["POST", "GET"])
22 | def register():
23 | if request.method == 'GET':
24 | return render_template("app/register.html")
25 | else:
26 | name = request.form.get("name")
27 | course = request.form.get("course")
28 | teacher = Teacher(name, course)
29 |
30 | session["_teacher"] = serialize(teacher)
31 | return redirect(url_for(".index"))
32 |
33 |
34 | @bp.route('/students', methods=["GET"])
35 | def show_students():
36 | teacher = retrieve_teacher()
37 | if teacher is None:
38 | return redirect("register")
39 | else:
40 | return render_template("app/students.html", students=teacher.students.values())
41 |
42 |
43 | @bp.route('/add', methods=["POST", "GET"])
44 | def add():
45 | if request.method == 'GET':
46 | return render_template("app/add.html")
47 | else:
48 | id = request.form.get("id")
49 | firstname = request.form.get("firstname")
50 | lastname = request.form.get("lastname")
51 | gender = request.form.get("gender")
52 |
53 | teacher = retrieve_teacher()
54 | teacher.students[id] = Student(id, firstname, lastname, gender)
55 | session['_teacher'] = serialize(teacher)
56 |
57 | return redirect(url_for(".show_students"))
58 |
59 |
60 | @bp.route('/delete/', methods=["GET", "POST", "DELETE"])
61 | def delete(id):
62 | teacher = retrieve_teacher()
63 | teacher.students.pop(id)
64 | session['_teacher'] = serialize(teacher)
65 |
66 | return redirect(url_for(".show_students"))
67 |
68 |
69 | @bp.route('/edit/', methods=["POST", "GET"])
70 | def edit(id):
71 | teacher = retrieve_teacher()
72 | student = teacher.students.pop(id)
73 |
74 | if request.method == 'GET':
75 | return render_template("app/edit.html", student=student)
76 | else:
77 | student.first_name = request.form.get("firstname")
78 | student.last_name = request.form.get("lastname")
79 | student.gender = request.form.get("gender")
80 |
81 | teacher.students[id] = student
82 | session['_teacher'] = serialize(teacher)
83 | return redirect(url_for(".show_students"))
84 |
85 |
86 | @bp.route('/save')
87 | def save():
88 | serialized_teacher = session.get("_teacher")
89 | resp = make_response(render_template("app/save.html"))
90 | if serialized_teacher is not None:
91 | expire_date = datetime.datetime.now() + datetime.timedelta(days=90)
92 | resp.set_cookie("_teacher", serialized_teacher, expires=expire_date)
93 |
94 | return resp
95 |
96 |
97 | def retrieve_teacher():
98 | serialized_teacher = session.get("_teacher")
99 | if serialized_teacher is None:
100 | serialized_teacher = request.cookies.get('_teacher')
101 |
102 | if serialized_teacher is not None:
103 | return deserialize(serialized_teacher)
104 |
105 | return None
106 |
--------------------------------------------------------------------------------
/lab_02_Building_Web_Applications_with_Flask/views.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | from flask import request, render_template, Flask, redirect, url_for, make_response, session
4 | from lab_02_Building_Web_Applications_with_Flask.models import Teacher, Student
5 | from lab_02_Building_Web_Applications_with_Flask.serialize import deserialize, serialize
6 |
7 | app = Flask(__name__)
8 |
9 |
10 | @app.route('/', methods=['GET'])
11 | def index():
12 | teacher = retrieve_teacher()
13 | if teacher is None:
14 | return redirect(url_for("register"))
15 |
16 | return redirect(url_for("show_students"))
17 |
18 |
19 | @app.route('/register', methods=["POST", "GET"])
20 | def register():
21 | if request.method == 'GET':
22 | return render_template("register.html")
23 | else:
24 | name = request.form.get("name")
25 | course = request.form.get("course")
26 | teacher = Teacher(name, course)
27 |
28 | session["_teacher"] = serialize(teacher)
29 | return redirect(url_for("index"))
30 |
31 |
32 | @app.route('/students', methods=["GET"])
33 | def show_students():
34 | teacher = retrieve_teacher()
35 | if teacher is None:
36 | return redirect("register")
37 | else:
38 | return render_template("students.html", students=teacher.students.values())
39 |
40 |
41 | @app.route('/add', methods=["POST", "GET"])
42 | def add():
43 | if request.method == 'GET':
44 | return render_template("add.html")
45 | else:
46 | id = request.form.get("id")
47 | firstname = request.form.get("firstname")
48 | lastname = request.form.get("lastname")
49 | gender = request.form.get("gender")
50 |
51 | teacher = retrieve_teacher()
52 | teacher.students[id] = Student(id, firstname, lastname, gender)
53 | session['_teacher'] = serialize(teacher)
54 |
55 | return redirect(url_for("show_students"))
56 |
57 |
58 | @app.route('/delete/', methods=["GET", "POST", "DELETE"])
59 | def delete(id):
60 | teacher = retrieve_teacher()
61 | teacher.students.pop(id)
62 | session['_teacher'] = serialize(teacher)
63 |
64 | return redirect(url_for("show_students"))
65 |
66 |
67 | @app.route('/edit/', methods=["POST", "GET"])
68 | def edit(id):
69 | teacher = retrieve_teacher()
70 | student = teacher.students.pop(id)
71 |
72 | if request.method == 'GET':
73 | return render_template("edit.html", student=student)
74 | else:
75 | student.first_name = request.form.get("firstname")
76 | student.last_name = request.form.get("lastname")
77 | student.gender = request.form.get("gender")
78 |
79 | teacher.students[id] = student
80 | session['_teacher'] = serialize(teacher)
81 | return redirect(url_for("show_students"))
82 |
83 |
84 | @app.route('/save')
85 | def save():
86 | serialized_teacher = session.get("_teacher")
87 | resp = make_response(render_template("save.html"))
88 | if serialized_teacher is not None:
89 | expire_date = datetime.datetime.now() + datetime.timedelta(days=90)
90 | resp.set_cookie("_teacher", serialized_teacher, expires=expire_date)
91 |
92 | return resp
93 |
94 |
95 | def retrieve_teacher():
96 | serialized_teacher = session.get("_teacher")
97 | if serialized_teacher is None:
98 | serialized_teacher = request.cookies.get('_teacher')
99 |
100 | if serialized_teacher is not None:
101 | return deserialize(serialized_teacher)
102 |
103 | return None
104 |
105 |
106 | if __name__ == "__main__":
107 | app.secret_key = 'SPECIFY_YOUR_OWN_SECRET_KEY'
108 | app.config['SESSION_TYPE'] = 'filesystem'
109 | app.run()
--------------------------------------------------------------------------------
/lab_06_Authentication/main.py:
--------------------------------------------------------------------------------
1 | from lab_06_Authentication.auth import login_required
2 | from lab_06_Authentication.auth import SECRET_KEY
3 | from flask import Flask
4 | from flask import jsonify
5 | from flask_restful import reqparse
6 | from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer)
7 |
8 |
9 | app = Flask(__name__)
10 | database = []
11 |
12 |
13 | class Student:
14 | def __init__(self, name, grade):
15 | self.name = name
16 | self.grade = grade
17 |
18 |
19 | class Statistics:
20 | min = None
21 | max = None
22 | average = 0
23 | num_of_students = 0
24 |
25 |
26 | def statistics():
27 | """
28 | This function gets through the all student objects in the database
29 | and calculates min, max, average, and total number of students.
30 | :return: Statistics
31 | """
32 | stats = Statistics()
33 | stats.num_of_students = len(database)
34 |
35 | if stats.num_of_students == 0:
36 | return stats
37 |
38 | stats.max = database[0].grade
39 | stats.min = database[0].grade
40 | sum = 0
41 | for student in database:
42 | sum += student.grade
43 | if student.grade < stats.min:
44 | stats.min = student.grade
45 | if student.grade > stats.max:
46 | stats.max = student.grade
47 |
48 | stats.average = sum / stats.num_of_students
49 | return stats
50 |
51 |
52 | @app.route("/students", methods=['POST'])
53 | @login_required
54 | def add_student():
55 | parser = reqparse.RequestParser()
56 | parser.add_argument('name', type=str)
57 | parser.add_argument('grade', type=int)
58 | args = parser.parse_args()
59 |
60 | name = args.get("name")
61 | grade = args.get("grade")
62 |
63 | database.append(Student(name, grade))
64 | return jsonify(studentName=name), 200
65 |
66 |
67 | @app.route("/students", methods=['GET'])
68 | @login_required
69 | def get_students():
70 | response = jsonify([st.__dict__ for st in database])
71 | # response.headers._list.append(('Access-Control-Allow-Origin', '*'))
72 | return response
73 |
74 |
75 | @app.route("/students/", methods=['GET'])
76 | @login_required
77 | def get_student(name):
78 | for st in database:
79 | if st.name == name:
80 | return jsonify(st.__dict__)
81 |
82 | return jsonify(name=False), 404
83 |
84 |
85 | @app.route("/students/", methods=['DELETE'])
86 | @login_required
87 | def delete_student(name):
88 | for st in database:
89 | if st.name == name:
90 | database.remove(st)
91 | return jsonify(studentName=name), 200
92 | return jsonify(studentName=False), 200
93 |
94 |
95 | @app.route("/students/", methods=['POST'])
96 | @login_required
97 | def update_student(name):
98 | parser = reqparse.RequestParser()
99 | parser.add_argument('grade', type=int)
100 | args = parser.parse_args()
101 | grade = args.get("grade")
102 |
103 | for st in database:
104 | if st.name == name:
105 | database.remove(st)
106 | database.append(Student(name, grade))
107 | return jsonify(studentName=name, studentGrade=grade), 201
108 |
109 | return jsonify(studentName=False), 404
110 |
111 |
112 | @app.route("/statistics", methods=['GET'])
113 | @login_required
114 | def get_statistics():
115 | return jsonify(statistics().__dict__)
116 |
117 |
118 | @app.route("/auth", methods=['GET'])
119 | def generate_token():
120 | parser = reqparse.RequestParser()
121 | parser.add_argument('username', type=str)
122 | parser.add_argument('password', type=str)
123 | args = parser.parse_args()
124 |
125 | username = args.get("username")
126 | password = args.get("password")
127 |
128 | s = Serializer(SECRET_KEY, expires_in=600)
129 | token = s.dumps(username)
130 |
131 | if username == 'admin' and password == 'admin':
132 | return token.decode()
133 |
134 | return 404
135 |
136 |
137 | if __name__ == "__main__":
138 | app.run()
139 |
--------------------------------------------------------------------------------
/lab_04_RESTful_Client/receive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
87 |
88 |
Add a New Student:
89 |
95 |
96 |
Update Student Info
97 |
102 |
103 |
Delete Student
104 |
108 |
109 |
List all students:
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------