From e022c2d6a18fc66e836c8aa7d8bba83c841564df Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 10:20:52 +0800 Subject: [PATCH 01/14] added get profile ID feature --- ProfilesAPI.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ProfilesAPI.py diff --git a/ProfilesAPI.py b/ProfilesAPI.py new file mode 100644 index 0000000..a2956a3 --- /dev/null +++ b/ProfilesAPI.py @@ -0,0 +1,70 @@ +from flask import Flask +from flask import request +from flask import Blueprint +from flask import render_template +from db import datab + +app = Flask(__name__) +# profile = Blueprint('profile',__name__,url_prefix='/profiles') + + +# @profile.route('/profiles/GET//', methods=['GET']) +@app.route('/profiles/GET//', methods=['GET']) +def get_profile(name): + GET_profile = {} + for obj in datab: + if obj["name"] == str(name): + GET_profile = {"name" : name , "scores" : obj.get("scores")} + if GET_profile == {}: + return "name does not exist" + else: + return GET_profile + +# @profile.route('/profiles/POST//', methods=["POST"]) +@app.route('/profiles/POST/', methods=["POST", "GET"]) +def create_profile(name): + user_dict ={"name" : name} + datab.append(user_dict) + return f"user {name} has been created" + + + + +# @profile.route('/profiles/DELETE/', methods=["DELETE"]) +@app.route('/profiles/DELETE/', methods=["DELETE","GET"]) +def delete_profile(name): + wanted_profile_list = list(filter(lambda a: a["name"] != name, datab)) + if len(datab) != len(wanted_profile_list): + return f"{name} successfully removed" + else: + return "name not in database" + + + + # for obj in datab: + # if obj["name"] == name: + # datab.remove(obj) + # return "success" + + + +# @profile.route('/scores/GET//', methods=['GET' , 'POST']) +@app.route('/scores/GET//', methods=['GET' , 'POST']) +def get_above_minscore(name): + minscore = request.args.get('minScore',type=int,default=0) + score_list = [] + for obj in datab: + if obj["name"] == str(name): + score_list = list(filter(lambda a : a > minscore, obj["scores"])) + score_dict = {"name":name, "scores": score_list} + return score_dict + if score_list == []: + return "candidate not found" + +@app.route('/test/',methods=['POST','GET']) +def haha(): + return render_template("test.html") + + +if __name__ == "__main__": + app.run(debug = True) \ No newline at end of file From d3ad505f67c24f5fbb58a4dfed6a508b5bb1a2fe Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 10:37:20 +0800 Subject: [PATCH 02/14] added create profile feature --- ProfilesAPI.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index a2956a3..458a21c 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -1,7 +1,6 @@ from flask import Flask from flask import request from flask import Blueprint -from flask import render_template from db import datab app = Flask(__name__) @@ -29,42 +28,5 @@ def create_profile(name): - -# @profile.route('/profiles/DELETE/', methods=["DELETE"]) -@app.route('/profiles/DELETE/', methods=["DELETE","GET"]) -def delete_profile(name): - wanted_profile_list = list(filter(lambda a: a["name"] != name, datab)) - if len(datab) != len(wanted_profile_list): - return f"{name} successfully removed" - else: - return "name not in database" - - - - # for obj in datab: - # if obj["name"] == name: - # datab.remove(obj) - # return "success" - - - -# @profile.route('/scores/GET//', methods=['GET' , 'POST']) -@app.route('/scores/GET//', methods=['GET' , 'POST']) -def get_above_minscore(name): - minscore = request.args.get('minScore',type=int,default=0) - score_list = [] - for obj in datab: - if obj["name"] == str(name): - score_list = list(filter(lambda a : a > minscore, obj["scores"])) - score_dict = {"name":name, "scores": score_list} - return score_dict - if score_list == []: - return "candidate not found" - -@app.route('/test/',methods=['POST','GET']) -def haha(): - return render_template("test.html") - - if __name__ == "__main__": app.run(debug = True) \ No newline at end of file From 5cb21570c01a560b8ff8eadc3ff18f139f6adb21 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 11:20:09 +0800 Subject: [PATCH 03/14] added delete profile feature --- ProfilesAPI.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index 458a21c..4020fe3 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -15,7 +15,7 @@ def get_profile(name): if obj["name"] == str(name): GET_profile = {"name" : name , "scores" : obj.get("scores")} if GET_profile == {}: - return "name does not exist" + return "profile does not exist" else: return GET_profile @@ -26,6 +26,17 @@ def create_profile(name): datab.append(user_dict) return f"user {name} has been created" +# @profile.route('/profiles/DELETE/', methods=["DELETE","GET"]) +@app.route('/profiles/DELETE/', methods=["DELETE","GET"]) +def delete_profile(name): + unwanted_profile_list = list(filter(lambda a: a["name"] == name, datab)) + if unwanted_profile_list !=[]: + datab.remove(unwanted_profile_list[0]) + return f"{name} removed from database" + else: + return "name does not exist" + + if __name__ == "__main__": From 91a9f7e218a75bf0f2616f05b69f937b597eed43 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 11:24:51 +0800 Subject: [PATCH 04/14] added 'get profile with minScore argument' feature --- ProfilesAPI.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index 4020fe3..6b4cb18 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -37,6 +37,18 @@ def delete_profile(name): return "name does not exist" +# @profile.route('/scores/GET//', methods=['GET' , 'POST']) +@app.route('/scores/GET//', methods=['GET' , 'POST']) +def get_above_minscore(name): + minscore = request.args.get('minScore',type=int,default=0) + score_list = [] + for obj in datab: + if obj["name"] == str(name): + score_list = list(filter(lambda a : a > minscore, obj["scores"])) + score_dict = {"name":name, "scores": score_list} + return score_dict + if score_list == []: + return "candidate not found" if __name__ == "__main__": From b601e0cb3321add6c430c9bfe766dd3ebbe23933 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 12:01:39 +0800 Subject: [PATCH 05/14] added blueprint function --- ProfilesAPI.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index 6b4cb18..7e1ce0f 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -3,12 +3,10 @@ from flask import Blueprint from db import datab -app = Flask(__name__) -# profile = Blueprint('profile',__name__,url_prefix='/profiles') +profile = Blueprint('profile',__name__,url_prefix='/profiles') -# @profile.route('/profiles/GET//', methods=['GET']) -@app.route('/profiles/GET//', methods=['GET']) +@profile.route('/GET//', methods=['GET']) def get_profile(name): GET_profile = {} for obj in datab: @@ -19,15 +17,13 @@ def get_profile(name): else: return GET_profile -# @profile.route('/profiles/POST//', methods=["POST"]) -@app.route('/profiles/POST/', methods=["POST", "GET"]) +@profile.route('/POST//', methods=["POST","GET"]) def create_profile(name): - user_dict ={"name" : name} + user_dict ={"name" : name,"scores": []} datab.append(user_dict) return f"user {name} has been created" -# @profile.route('/profiles/DELETE/', methods=["DELETE","GET"]) -@app.route('/profiles/DELETE/', methods=["DELETE","GET"]) +@profile.route('/DELETE/', methods=["DELETE","GET"]) def delete_profile(name): unwanted_profile_list = list(filter(lambda a: a["name"] == name, datab)) if unwanted_profile_list !=[]: @@ -37,8 +33,7 @@ def delete_profile(name): return "name does not exist" -# @profile.route('/scores/GET//', methods=['GET' , 'POST']) -@app.route('/scores/GET//', methods=['GET' , 'POST']) +@profile.route('/scores/GET//', methods=['GET' , 'POST']) def get_above_minscore(name): minscore = request.args.get('minScore',type=int,default=0) score_list = [] @@ -49,7 +44,3 @@ def get_above_minscore(name): return score_dict if score_list == []: return "candidate not found" - - -if __name__ == "__main__": - app.run(debug = True) \ No newline at end of file From fdb886585ec8f0e6d77095ce14edf08c9edf8732 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 17:38:56 +0800 Subject: [PATCH 06/14] added register user feature --- AuthAPI.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 AuthAPI.py diff --git a/AuthAPI.py b/AuthAPI.py new file mode 100644 index 0000000..fc01744 --- /dev/null +++ b/AuthAPI.py @@ -0,0 +1,31 @@ +import json +import jwt +from flask import Flask, Blueprint, request,jsonify +from db import datab +from db import profile_auth + + +auth_api = Blueprint('auth_api',__name__,url_prefix='/auth') + + +@auth_api.route('/register/POST///', methods=['POST','GET']) +def register_user(username,password): + passwordhash = hash(password) + user_dict = {"username":username, "hashedPassword": passwordhash} + if user_dict["hashedPassword"] == -9223363242168321331: + return jsonify({"message":"failure", "status":"400"}) + else: + profile_auth.append(user_dict) + return jsonify({"message":"success", "status":"200"}) + + + + + + + + + +# if __name__ == "__main__": +# app.run(debug=True) + From a57d327ec5d4b4620f8ce7ec8c8b6edd238753ba Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 17:42:25 +0800 Subject: [PATCH 07/14] added login feature --- AuthAPI.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/AuthAPI.py b/AuthAPI.py index fc01744..1c659d2 100644 --- a/AuthAPI.py +++ b/AuthAPI.py @@ -20,12 +20,14 @@ def register_user(username,password): - - - - - - -# if __name__ == "__main__": -# app.run(debug=True) - +@auth_api.route('/login/POST///', methods=['POST','GET']) +def user_login(username,password): + passwordhash = hash(password) + user_dict = {"username":username, "hashedPassword": passwordhash} + match = list(filter(lambda a:a["username"] == username and a["hashedPassword"] ==passwordhash, profile_auth)) + try: + if match[0] == user_dict: + token = jwt.encode({"username":username, "hashedPassword": passwordhash}, "secret", algorithm="HS256") + return jsonify({"token":token, "message":"success", "status":"200"}) + except: + return jsonify({"message":"failure", "status":"401"}) \ No newline at end of file From fa53f97c56789c2937a933cbcc6d02347f62fdba Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 17:54:45 +0800 Subject: [PATCH 08/14] added appropriate jsonify status response --- ProfilesAPI.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index 7e1ce0f..049b0bd 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -1,8 +1,7 @@ -from flask import Flask -from flask import request -from flask import Blueprint +from flask import Flask,request,Blueprint,jsonify from db import datab + profile = Blueprint('profile',__name__,url_prefix='/profiles') @@ -13,24 +12,24 @@ def get_profile(name): if obj["name"] == str(name): GET_profile = {"name" : name , "scores" : obj.get("scores")} if GET_profile == {}: - return "profile does not exist" + return jsonify({"message":"failure", "status":"400"}) else: - return GET_profile + return jsonify(GET_profile) @profile.route('/POST//', methods=["POST","GET"]) def create_profile(name): user_dict ={"name" : name,"scores": []} datab.append(user_dict) - return f"user {name} has been created" + return jsonify({"message":"success", "status":"200"}) -@profile.route('/DELETE/', methods=["DELETE","GET"]) +@profile.route('/DELETE//', methods=["DELETE","GET"]) def delete_profile(name): unwanted_profile_list = list(filter(lambda a: a["name"] == name, datab)) if unwanted_profile_list !=[]: datab.remove(unwanted_profile_list[0]) - return f"{name} removed from database" + return jsonify({"message":"success", "status":"200"}) else: - return "name does not exist" + return jsonify({"message":"failure", "status":"400"}) @profile.route('/scores/GET//', methods=['GET' , 'POST']) @@ -41,6 +40,7 @@ def get_above_minscore(name): if obj["name"] == str(name): score_list = list(filter(lambda a : a > minscore, obj["scores"])) score_dict = {"name":name, "scores": score_list} - return score_dict + return jsonify(score_dict) if score_list == []: - return "candidate not found" + return jsonify({"message":"failure", "status":"400"}) + From 3664c3a5c4d391f9a0d5817cff76702b0d5c3724 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 Oct 2021 17:57:11 +0800 Subject: [PATCH 09/14] added welcome message --- main.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..6b803cd --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +from flask import Flask +from db import datab +from ProfilesAPI import profile +from AuthAPI import auth_api + +app = Flask(__name__) +app.register_blueprint(profile, url_prefix="/profiles") +app.register_blueprint(auth_api, url_prefix="/auth") + + +@app.route('/GET/', methods=['GET']) +def welcome(): + return 'welcome!' + +if __name__ == "__main__": + app.run(debug=True) From 349b0c8926744653bdb387c8a64dd8365944943b Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 21 Oct 2021 01:23:25 +0800 Subject: [PATCH 10/14] created a documentation --- documentation.md | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 documentation.md diff --git a/documentation.md b/documentation.md new file mode 100644 index 0000000..747cf15 --- /dev/null +++ b/documentation.md @@ -0,0 +1,129 @@ +1)/GET/ + +description:returns welcome message + +function used: def welcome() + +Source: main.py + +Parameters: None + +Response: returns welcome message + +eg: Welcome! + + + + +2)/profiles/GET// + +returns the dictionary of the name and score that matches the name provided in the url + +function: get_profile(name) + +source: ProfilesAPI.py + +Parameters: none + +Response: returns dictionary of name and score + +eg: returns when is replaced with Richard +{ + "name": "Richard", + "scores": [5,4,3,2,1] +} + + + + +3)/profiles/POST// + +creates a dictionary of name and empty list of score and stores it in db.py + +function: create_profile(name) + +source: ProfilesAPI.py + +Parameters: None + +Response: after adding the dictionary to the database, return success message + +eg: {"message":"success", "status":"200"} + + + + +4)/profiles/DELETE/ +delete the dictionary that contains the name specified by user + +function:delete_profile(name) + +source:ProfilesAPI.py + +Parameters:None + +Response: status message that shows whether the operation is successful. + +eg: if there are no dictionaries deleted, {"message":"failure", "status":"400"} is returned + if there are dictionaries deleted, {"message":"success", "status":"200"} is returned + + + +5)/profiles/scores/GET// + +return the specified name and scores above the specified minimum score + +function: get_above_minscore(name) + +source: ProfilesAPI.py + +Parameters: minScore + +Response: if the data requested exists in the database, it will be presented in json. otherwise there will be error message + +eg: successful response failed response +{ {"message":"failure", "status":"400"} + "name": "Richard", + "scores": [4,5] +} + + + +6)/auth/register/POST/// +adds a user name and hashed password to database + +function: register_user(username,password) + +source: AuthAPI.py + +Parameter: None + +Response: if there is a password entered, it returns a success message; otherwise it returns failure message + +eg: successful response failed response +{"message":"success", "status":"200"} {"message":"failure", "status":"400"} + +7)/login/POST/// +match the username and password to a pre-existing username and password in the database, if there is a match, return a token and a success message. Otherwise return a failed message. + +function: user_login(username,password) + +source: AuthAPI.py + +Parameter: None + +Response: success message + token +{ + "message": "success", + "status": "200", + "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InNoYXduIiwiaGFzaGVkUGFzc3dvcmQiOjUyMDE4ODg3Njk4ODY0NjI5MjF9.mQZZnZ27x08CvwCP_KBZHPYlxaqWWeba3EJUi49Y2wQ" +} + or + failure message + { + "message": "failure", + "status": "401" +} + + + From 21a783220e54c23ca1c1a49f5007b42ad4b70158 Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 21 Oct 2021 15:42:58 +0800 Subject: [PATCH 11/14] added / to the end of DELETE URL --- ProfilesAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProfilesAPI.py b/ProfilesAPI.py index 049b0bd..f772eb8 100644 --- a/ProfilesAPI.py +++ b/ProfilesAPI.py @@ -12,7 +12,7 @@ def get_profile(name): if obj["name"] == str(name): GET_profile = {"name" : name , "scores" : obj.get("scores")} if GET_profile == {}: - return jsonify({"message":"failure", "status":"400"}) + return jsonify({"message":"failure", "status":"401"}) else: return jsonify(GET_profile) From 925d3f35999201bb89511d66bf6415211df33c54 Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 21 Oct 2021 15:46:48 +0800 Subject: [PATCH 12/14] created welcome homepage --- main_app.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 main_app.py diff --git a/main_app.py b/main_app.py new file mode 100644 index 0000000..ad9d375 --- /dev/null +++ b/main_app.py @@ -0,0 +1,16 @@ +from flask import Flask +from db import datab +from ProfilesAPI import profile +from AuthAPI import auth_api + +app = Flask(__name__) +app.register_blueprint(profile, url_prefix="/profiles") +app.register_blueprint(auth_api, url_prefix="/auth") + + +@app.route('/GET/', methods=['GET']) +def welcome(): + return 'welcome!' + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file From 9e31823375c9b6ed4e05c6705a4739192503cc69 Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 21 Oct 2021 17:19:06 +0800 Subject: [PATCH 13/14] created database --- db.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 db.py diff --git a/db.py b/db.py new file mode 100644 index 0000000..e3fc608 --- /dev/null +++ b/db.py @@ -0,0 +1,12 @@ +datab = [{ + "name": "Nobel", + "scores": [1, 2, 3, 4, 5] +}, { + "name": "Richard", + "scores": [5, 4, 3, 2, 1] +}, { + "name": "Hui Hui", + "scores": [9, 29, 34] +}] + +profile_auth = [] \ No newline at end of file From 9e350bde280a1a21182a1d9396dee7995e7cfba8 Mon Sep 17 00:00:00 2001 From: leonghuenweng <88919450+leonghuenweng@users.noreply.github.com> Date: Thu, 21 Oct 2021 20:08:39 +0800 Subject: [PATCH 14/14] extra copy of main.py deleted --- main.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 main.py diff --git a/main.py b/main.py deleted file mode 100644 index 6b803cd..0000000 --- a/main.py +++ /dev/null @@ -1,16 +0,0 @@ -from flask import Flask -from db import datab -from ProfilesAPI import profile -from AuthAPI import auth_api - -app = Flask(__name__) -app.register_blueprint(profile, url_prefix="/profiles") -app.register_blueprint(auth_api, url_prefix="/auth") - - -@app.route('/GET/', methods=['GET']) -def welcome(): - return 'welcome!' - -if __name__ == "__main__": - app.run(debug=True)