From 89947866aa931862f2a4b8e267468ca7ac4e994a Mon Sep 17 00:00:00 2001 From: Eric Asante Date: Fri, 8 Nov 2024 01:47:31 -0500 Subject: [PATCH 1/7] Complete API/TEST --- Backend/Dockerfile | 30 ---- Backend/{main.py => app.py} | 78 ++++++++-- .../databasefunctions.cpython-310.pyc | Bin 0 -> 5268 bytes .../{ => database_files}/databasefunctions.py | 73 ++++++---- .../initdatabase.py} | 42 ++---- Backend/docker_files/Dockerfile | 18 +++ Backend/docker_files/requirements.txt | 4 + Backend/requirements.txt | 8 -- Backend/testData.db | Bin 20480 -> 0 bytes Backend/test_app.py | 133 ++++++++++++++++++ 10 files changed, 280 insertions(+), 106 deletions(-) delete mode 100644 Backend/Dockerfile rename Backend/{main.py => app.py} (59%) create mode 100644 Backend/database_files/__pycache__/databasefunctions.cpython-310.pyc rename Backend/{ => database_files}/databasefunctions.py (79%) rename Backend/{databaseinit.py => database_files/initdatabase.py} (52%) create mode 100644 Backend/docker_files/Dockerfile create mode 100644 Backend/docker_files/requirements.txt delete mode 100644 Backend/requirements.txt delete mode 100644 Backend/testData.db create mode 100644 Backend/test_app.py diff --git a/Backend/Dockerfile b/Backend/Dockerfile deleted file mode 100644 index d085169..0000000 --- a/Backend/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -# Use Python as the base image -FROM python:3.8-slim-buster - -# Install pip and Python dependencies -RUN apt-get update && apt-get install -y python3 python3-pip - -# Keeps Python from generating .pyc files in the container -ENV PYTHONDONTWRITEBYTECODE=1 - -# Turns off buffering for easier container logging -ENV PYTHONUNBUFFERED=1 - - -# Set the working directory in the container -WORKDIR /app - - -# Install pip requirements -COPY /requirements.txt . -RUN python3 -m pip install -r requirements.txt - -# Copy main application file -COPY generateData.py . - -# Set the port for the application -ENV PORT=5000 -EXPOSE 5000 - -# Command to run the application -CMD ["python3", "generateData.py"] \ No newline at end of file diff --git a/Backend/main.py b/Backend/app.py similarity index 59% rename from Backend/main.py rename to Backend/app.py index 913cd46..a24b08b 100644 --- a/Backend/main.py +++ b/Backend/app.py @@ -2,11 +2,8 @@ This module provides functions for HTTP communication and route functions """ -import sqlite3 -import databasefunctions from flask import Flask, request, jsonify -from petfuc import get_random_pet -from userfuc import add_user_faviorte, remove_user_faviorte, replace_user_location +from database_files import databasefunctions app = Flask(__name__) # ----------------------------------------------------------------------------------------- @@ -17,9 +14,11 @@ def add_newuser(): Adds new user to database """ data = request.get_json() - newuser_id = databasefunctions.insert_user(data.get("name"), data.get("age"), data.get("location")) + newuser_id = databasefunctions.insert_user(data.get("username"),data.get("password"), + data.get("name"), data.get("age"), + data.get("location")) - return jsonify({'user_id': newuser_id}), 200 + return jsonify({'user_id': newuser_id}), 200 @app.route("/add_newpet", methods=["POST"]) def add_newpet(): @@ -28,21 +27,29 @@ def add_newpet(): """ data = request.get_json() newpet_id = databasefunctions.insert_pet(data.get("name"), data.get("age"), - data.get("gender"), data.get("breed"), data.get("type"), + data.get("gender"), data.get("breed"), data.get("type"), data.get("location"), data.get("photo_path")) - return jsonify({'pet_id': newpet_id}), 200 + return jsonify({'pet_id': newpet_id}), 200 @app.route("/add_newfavorite", methods=["POST"]) def add_newfavorite(): """ Adds new user favorite to database + INSERT INTO pets (name, age, gender, breed, type, location, photo_path) + VALUES + ('Bella', 3, 'female', 'Golden Retriever', 'dog', 'New York', 'images/Chuck.jpg'), + ('Max', 5, 'male', 'Maine Coon', 'cat', 'Boston', 'images/gunner.jpg'), + ('Luna', 2, 'female', 'Siamese', 'cat', 'Chicago', 'images/luna.jpg'), + ('Charlie', 4, 'male', 'Beagle', 'dog', 'Los Angeles', 'images/lizzie_izzie.jpg'), + ('Daisy', 1, 'female', 'Labrador Retriever', 'dog', 'Miami', 'images/monster.jpg'); + """ data = request.get_json() newfavorite_id = databasefunctions.insert_favorite(data.get("user_id"), data.get("pet_id")) - return jsonify({'faviorte_id': newfavorite_id}), 200 + return jsonify({'faviorte_id': newfavorite_id}), 200 @@ -66,7 +73,7 @@ def removepet(): Remove pet from database """ data = request.get_json() - petid = data.get("petid") + petid = data.get("pet_id") roweffected = databasefunctions.remove_pet(petid) return (f"{roweffected}, row was deleted in pet table"), 200 @@ -85,6 +92,25 @@ def removefavorite(): # --------------------------------------------------------------------- + +@app.route("/fetch_userid", methods=["POST"]) +def fetch_userid(): + """ + fetch userid associated with username and password + """ + data = request.get_json() + username = data.get("username") + password = data.get("password") + + + userid = databasefunctions.fetch_userid_from_username_and_password(username, password) + + return jsonify(userid), 200 + + + + + @app.route("/fetch_pet", methods=["POST"]) def fetch_pet(): """ @@ -94,7 +120,7 @@ def fetch_pet(): petid = data.get("pet_id") users_row = databasefunctions.fetch_pet_by_id(petid) - return jsonify(users_row), 200 + return jsonify(users_row), 200 @app.route("/fetch_user", methods=["POST"]) @@ -106,7 +132,7 @@ def fetch_user(): userid = data.get("user_id") users_row = databasefunctions.fetch_user_by_id(userid) - return jsonify(users_row), 200 + return jsonify(users_row), 200 @app.route("/fetch_favorited_pets", methods=["POST"]) @@ -118,11 +144,35 @@ def fetch_favorite_pet(): userid = data.get("user_id") favorited_pets = databasefunctions.fetch_favorites_by_user(userid) - return jsonify(favorited_pets), 200 + return jsonify(favorited_pets), 200 # --------------------------------------------------------------- +@app.route("/fetch_allusers", methods=["POST"]) +def fetch_allusers(): + """ + fetches all users in database + """ + + allusers = databasefunctions.fetch_all_users() + return jsonify(allusers), 200 + + +@app.route("/fetch_allpets", methods=["POST"]) +def fetch_allpets(): + """ + fetches all pets in database + """ + + allpets = databasefunctions.fetch_all_pets() + return jsonify(allpets), 200 + + + + + + if __name__ == "__main__": - app.run(host="0.0.0.0", port=5000, debug=True) + app.run(host="0.0.0.0", debug=True) diff --git a/Backend/database_files/__pycache__/databasefunctions.cpython-310.pyc b/Backend/database_files/__pycache__/databasefunctions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1bdb583e90dc8a6c4b9061c724abdc57204df75 GIT binary patch literal 5268 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 CXMutM literal 0 HcmV?d00001 diff --git a/Backend/databasefunctions.py b/Backend/database_files/databasefunctions.py similarity index 79% rename from Backend/databasefunctions.py rename to Backend/database_files/databasefunctions.py index f0cecf4..4aa835e 100644 --- a/Backend/databasefunctions.py +++ b/Backend/database_files/databasefunctions.py @@ -1,20 +1,21 @@ +'''DATABASE FUNCTIONS''' from contextlib import closing import sqlite3 def connect_db(): """Establish a connection to the SQLite database.""" - return sqlite3.connect('Projectdatabase.db') #this might change + return sqlite3.connect('projectdatabase.db') #this might change -# ---------------------------------------------------------------------------------------------- insert functions +# --------------------- insert functions -def insert_user(name, age, location): +def insert_user(username, password, name, age, location): """Insert a new user into the accounts table.""" with closing(connect_db()) as conn, conn: cursor = conn.cursor() cursor.execute( - '''INSERT INTO accounts (name, age, location) - VALUES (?, ?, ?)''', - (name, age, location) + '''INSERT INTO accounts (username, password, name, age, location) + VALUES (?, ?, ?, ?, ?)''', + (username, password, name, age, location) ) conn.commit() return cursor.lastrowid @@ -45,7 +46,7 @@ def insert_favorite(user_id, pet_id): conn.commit() return cursor.lastrowid -# ------------------------------------------------------------------------------------- remove functions +# ---------------------------remove functions def remove_user(user_id): """Remove a pet from the accounts table.""" @@ -77,79 +78,99 @@ def remove_favorite(user_id, pet_id): """Remove a favorite row from the favorites table based on user_id and pet_id.""" with closing(connect_db()) as conn: cursor = conn.cursor() - - # Execute DELETE query to remove the row matching user_id and pet_id + + # Execute DELETE query to remove the row matching user_id and pet_id cursor.execute(""" DELETE FROM favorites WHERE user_id = ? AND pet_id = ? """, (user_id, pet_id)) - + conn.commit() return cursor.rowcount # Returns the number of rows affected (should be 1 if successful) -# ----------------------------------------------------------------------------------------------------------- change fucntions +# ------------------------------------------- change fucntions def change_user_attributes(user_id, attribute, change): """Update a user's attribute in the accounts table.""" - + # List of valid column names to avoid SQL injection - valid_columns = ['name', 'age', 'location'] # Add your valid column names here - + valid_columns = ['name', 'age', 'location', 'password'] # Add your valid column names here + if attribute not in valid_columns: raise ValueError("Invalid attribute name.") - + with closing(connect_db()) as conn: cursor = conn.cursor() - + # Use the attribute directly, now it's safe since we validated it cursor.execute(f""" UPDATE accounts SET {attribute} = ? WHERE user_id = ? """, (change, user_id)) - + conn.commit() return fetch_user_by_id(user_id) def change_pet_attributes(pet_id, attribute, change): """Update a user's attribute in the accounts table.""" - + # List of valid column names to avoid SQL injection - valid_columns = ['name', 'age', 'location', 'breed', 'gender', 'type', 'photo_path'] # Add your valid column names here - + valid_columns = ['name', 'age', 'location', 'breed', + 'gender', 'type', 'photo_path'] # Add your valid column names here + if attribute not in valid_columns: raise ValueError("Invalid attribute name.") - + with closing(connect_db()) as conn: cursor = conn.cursor() - + # Use the attribute directly, now it's safe since we validated it cursor.execute(f""" UPDATE pets SET {attribute} = ? WHERE pet_id = ? """, (change, pet_id)) - + conn.commit() return fetch_pet_by_id(pet_id) -# ----------------------------------------------------------------------------------------------------------- fetch functions +# ------------------------------------- fetch functions + + +def fetch_userid_from_username_and_password(username,password): + """Get a users ID from there username and password""" + + with closing(connect_db()) as conn: + cursor = conn.cursor() + + # Execute DELETE query to remove the row matching user_id and pet_id + cursor.execute(""" + SELECT user_id FROM accounts + WHERE username = ? AND password = ? + """, (username, password)) + + result = cursor.fetchone() + if result: + return result[0] + else: + return None def fetch_favorites_by_user(user_id): """Fetch all favorite pets for a given user_id.""" with closing(connect_db()) as conn: cursor = conn.cursor() - + cursor.execute(""" SELECT pets.* FROM pets INNER JOIN favorites ON pets.pet_id = favorites.pet_id WHERE favorites.user_id = ? """, (user_id,)) - + return cursor.fetchall() diff --git a/Backend/databaseinit.py b/Backend/database_files/initdatabase.py similarity index 52% rename from Backend/databaseinit.py rename to Backend/database_files/initdatabase.py index 861c9a8..e90b8d4 100644 --- a/Backend/databaseinit.py +++ b/Backend/database_files/initdatabase.py @@ -1,20 +1,20 @@ -'''ONLY USE THIS IF THE DATABASE IS EMPTY. IT'S THE INIT CODE''' +'''INIT TABLES IN DATABASE''' import sqlite3 -from contextlib import closing -import os -def populate_test_data(db_path): +def create_database_tabels(db_path): '''THE ACTUAL FUNCITON''' conn = sqlite3.connect(db_path) cursor = conn.cursor() - conn.execute("PRAGMA foreign_keys = ON") + conn.execute("PRAGMA foreign_keys = ON") # Create tables cursor.executescript(''' CREATE TABLE IF NOT EXISTS accounts ( user_id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL, + password TEXT NOT NULL, name TEXT NOT NULL, age INTEGER, location TEXT, @@ -41,35 +41,21 @@ def populate_test_data(db_path): created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); - ''') - # Insert sample users - cursor.executescript(''' - INSERT INTO accounts (name, age) VALUES - ('Ben Ten', 28), - ('Spongebob Smith', 35), - ('Dipper Pines', 25), - ('Emilia Kirej', 20); - ''') + INSERT INTO pets (name, age, gender, breed, type, location, photo_path) + VALUES + ('Bella', 3, 'female', 'Golden Retriever', 'dog', 'New York', 'images/Chuck.jpg'), + ('Max', 5, 'male', 'Maine Coon', 'cat', 'Boston', 'images/gunner.jpg'), + ('Luna', 2, 'female', 'Siamese', 'cat', 'Chicago', 'images/luna.jpg'), + ('Charlie', 4, 'male', 'Beagle', 'dog', 'Los Angeles', 'images/lizzie_izzie.jpg'), + ('Daisy', 1, 'female', 'Labrador Retriever', 'dog', 'Miami', 'images/monster.jpg'); - # Insert sample pets - cursor.executescript(''' - INSERT INTO pets (name, age, gender, breed, type, location, photo_path) VALUES - ('Gunner', 9, 'male', 'Golden Retriever', 'dog', 'Myrtle Beach, SC', 'images/gunner.jpg'), - ('Lizzie Izzie', 5, 'female', 'Donskoy', 'cat', 'Milford, CT', 'images/lizzie_izzie.jpg'), - ('Chuck', 1, 'male', 'Corgi', 'dog', 'Orlando, FL', 'images/chuck.jpg'), - ('Monster', 5, 'female', 'Maine Coon', 'cat', 'Houston, TX', 'images/monster.jpg'); - ''') - # Insert sample favorites - cursor.executescript(''' - INSERT INTO favorites (user_id, pet_id) VALUES - (2, 4), - (1, 2); ''') + conn.commit() conn.close() if __name__ == "__main__": - populate_test_data('Projectdatabase.db') + create_database_tabels('projectdatabase.db') diff --git a/Backend/docker_files/Dockerfile b/Backend/docker_files/Dockerfile new file mode 100644 index 0000000..305c2f8 --- /dev/null +++ b/Backend/docker_files/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.9-slim +WORKDIR /Docker1 + + +COPY /database_files/databasefunctions.py /Docker1/database_files/databasefunctions.py +COPY app.py app.py +COPY /database_files/initdatabase.py /Docker1/database_files/initdatabase.py + + +# Copy requirements.txt from docker_files directory into the container +COPY docker_files/requirements.txt /Docker1/requirements.txt + +# Install Python dependencies inside Docker +RUN pip3 install -r /Docker1/requirements.txt + +EXPOSE 5000 + +CMD python3 /Docker1/database_files/initdatabase.py && python3 app.py diff --git a/Backend/docker_files/requirements.txt b/Backend/docker_files/requirements.txt new file mode 100644 index 0000000..2e64847 --- /dev/null +++ b/Backend/docker_files/requirements.txt @@ -0,0 +1,4 @@ +Flask==3.0.3 +requests==2.26.0 +pytest==7.2.1 +flask_cors==3.0.10 diff --git a/Backend/requirements.txt b/Backend/requirements.txt deleted file mode 100644 index 5eeda4f..0000000 --- a/Backend/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -Flask==2.0.3 -requests==2.26.0 -pandas==1.3.4 -pytest==7.2.1 -flask_cors==3.0.10 -#Werkzeug==2.1.3 -#pip freeze - diff --git a/Backend/testData.db b/Backend/testData.db deleted file mode 100644 index 14a1ced4137ca6c85a0d126ff4511ef69154595c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 zcmeI(Z*SU090zb4NLkPtCNX41*@KIsDIlN?B~sV!$%x~mEd0rg(HdzIa_|K%F}7P?l zL-|ZmRplE(6h&D{e&SE2wAf~neEg>__P!|1eELLL`*ZEr`&E%af&c^{ z009U<00Izz00cfRfuDj*R@>ZE-&DAL>e5+6!y%^;kLI}*-87n(L9FIp+aUAfq?98` zifas+Lt0(SI5bRhY_>X0^Mo83C!{&BdabUA(J{JK^}33TGp{l)crg>fnC}tGc)oDH z?L|M*aOvPd&oo+xUD-}4iC8A4abTE6S2y~yx6yTpY`pyXWjd=Bi|WrkIpl!yDE?(` z3^P8mFhH^Up5ycEDV4n?-JV6dgLZp9M0-r%QOysIspljEB>FQ$KPn|hT3u4wp4u+m zu9EFDDs$!Xyy9s{sj~#bFN37@t59-Z26Fsy9A{+n?ZqIjFOK|EJ(&319|ks`EHy9+ zsm-Y~6i=I0t7G)7X6Kmf8wbrn+amhF6#mxmy5tJ}ICW2}RMZp69=&kI6YDUd;(B`{ zy0n|VaWR$(OR;TL)GWWgr)D)xQ{P-%-@Wq2jZ!!2$9Kl!)m*yw{>|pmkR$2t$a4mKUVU;<$uYaiwqJ3AOHafKmY;|fB*y_009U< z00Qp>>Y1$arMgjQ7*pmln;fx_o_{VL-9ttl@uuX_&ZFI0yh4I$|{w(m44uRV|wbJlKzzO$yQQJym`5$Rz=M!8|r$Y zu}8(bFzS5~F>mbB+j|v1|EKc5EBQaf1_=TXfB*y_009U<00Izz00bZafsb9_lT^B> z$`4jn)wHI{ZyPdl{(tSQl7E}uU;9gBkRSj72tWV=5P$##AOHafKmYKzI{CqQaNBfzE1grc z)uL9|sx|b&|7!T}t+-J(^TWUr*W?%Sv}dkDvd=qJJa^KmY;|fB*y_009U< O00Izz00jQW0)GR|xWAMD diff --git a/Backend/test_app.py b/Backend/test_app.py new file mode 100644 index 0000000..da5e088 --- /dev/null +++ b/Backend/test_app.py @@ -0,0 +1,133 @@ +""" +Pytest for fake API +""" +import requests + +UNIQUE_USER_ID = None +UNIQUE_PET_ID = None + + +def test_insert_user(): + """ + Test for http://localhost:5000/add_newuser, adding user to database + """ + global UNIQUE_USER_ID + url = "http://localhost:5000" + + UNIQUE_USER_ID = requests.post((url + "/add_newuser"), + json={"username":"sam2213", + "password":"catlover20","name": "sam", + "age": 17, "location": "jamaica"},timeout=10) + + response1 = requests.post((url + "/fetch_user"),json=UNIQUE_USER_ID.json(), timeout=10) + response2 = requests.post((url + "/fetch_allusers"), timeout=10) + + assert (response1.json() in response2.json()) is True + + +def test_insert_pet(): + """ + Test for http://localhost:5000/add_newpet, adding new pet to database to database + """ + global UNIQUE_PET_ID + url = "http://localhost:5000" + UNIQUE_PET_ID = requests.post((url + "/add_newpet"), + json={"name": "sam", "age": 17, + "gender":"female","breed":"pug", + "type":"cat","location": "jamaica", + "photo_path":"images/sam.jpg"},timeout=10) + + response1 = requests.post((url + "/fetch_pet"),json=UNIQUE_PET_ID.json(), timeout=10) + response2 = requests.post((url + "/fetch_allpets"), timeout=10) + + assert (response1.json() in response2.json()) is True + +def test_insert_favorite_relation(): + """ + Test for http://localhost:5000/add_newfavorite, adding users favorited pet into the database + """ + global UNIQUE_USER_ID + global UNIQUE_PET_ID + + url = "http://localhost:5000" + + + requests.post((url + "/add_newfavorite"), + json={"user_id": UNIQUE_USER_ID.json().get("user_id"), + "pet_id": UNIQUE_PET_ID.json().get("pet_id")},timeout=10) + + response1 = requests.post((url + "/fetch_pet"),json=UNIQUE_PET_ID.json(), timeout=10) + response2 = requests.post((url + "/fetch_favorited_pets"),json=UNIQUE_USER_ID.json(),timeout=10) + + assert (response1.json() in response2.json()) is True + + +# ----------------------------------------------------------------------------- + +def test_fetch_userid(): + """ + Test for http://localhost:5000/fetch_userid, + retrieve userid accosiated with username and password + """ + + global UNIQUE_USER_ID + global UNIQUE_PET_ID + + url = "http://localhost:5000" + userid = requests.post((url + "/fetch_userid"), + json={"username": "sam2213", + "password": "catlover20"}, timeout=10) + + assert userid.json() == UNIQUE_USER_ID.json().get("user_id") + +# ---------------------------------------------------------------------------------- + +def test_remove_favorite_relation(): + """ + Test for http://localhost:5000/remove_favorite, remove users favorited pet from the database + """ + + global UNIQUE_USER_ID + global UNIQUE_PET_ID + + url = "http://localhost:5000" + + requests.delete((url + "/remove_favorite"), + json={"user_id": UNIQUE_USER_ID.json().get("user_id"), + "pet_id": UNIQUE_PET_ID.json().get("pet_id")},timeout=10) + + + response = requests.post((url + "/fetch_favorited_pets"),json=UNIQUE_USER_ID.json(),timeout=10) + + assert (response.json()) == [] + + +def test_remove_user(): + """ + Test for http://localhost:5000/remove_user + """ + + global UNIQUE_USER_ID + global UNIQUE_PET_ID + + url = "http://localhost:5000" + + requests.delete((url + "/remove_user"), json=UNIQUE_USER_ID.json(), timeout=10) + + response = requests.post((url + "/fetch_user"),json=UNIQUE_USER_ID.json(), timeout=10) + + assert response.json() is None + + +def test_remove_pet(): + """ + Test for http://localhost:5000/remove_pet + """ + + url = "http://localhost:5000" + + requests.delete((url + "/remove_pet"), json=UNIQUE_PET_ID.json(), timeout=10) + + response = requests.post((url + "/fetch_pet"),json=UNIQUE_PET_ID.json(), timeout=10) + + assert response.json() is None From 78b0bc89ee2ff07cb7ce86eceb0381f2ebf7e75c Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 01:49:17 -0500 Subject: [PATCH 2/7] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a7c605..0bbcdf6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # cse2102-fall24-Team51 -Eric Asante eoa21004 +Eric Asante eoa21004\n Kyle Kirejczyk kek20009 Ishayu Ray isr21011 Kunal bagga kub21001 Link to Trello: https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board -Link to Figma Prototype: https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray \ No newline at end of file +Link to Figma Prototype: https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray From 5a79ff9d69a5c451eec27ae32e54e91ded8a0d67 Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 01:50:10 -0500 Subject: [PATCH 3/7] Update README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0bbcdf6..c89e0ec 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# cse2102-fall24-Team51 -Eric Asante eoa21004\n -Kyle Kirejczyk kek20009 -Ishayu Ray isr21011 -Kunal bagga kub21001 -Link to Trello: https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board -Link to Figma Prototype: https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray +# CSE2102-fall24-Team51 + +Eric Asante eoa21004
+Kyle Kirejczyk kek20009
+Ishayu Ray isr21011
+Kunal Bagga kub21001
+ +Link to Trello: [https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board](https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board)
+Link to Figma Prototype: [https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray](https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray) From 6451947245532ea53b2679b1ffaf5f80de567cb5 Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 01:52:49 -0500 Subject: [PATCH 4/7] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c89e0ec..e4b6f52 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,10 @@ Ishayu Ray isr21011
Kunal Bagga kub21001
Link to Trello: [https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board](https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board)
-Link to Figma Prototype: [https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray](https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray) +Link to Figma Prototype: [https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray](https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray)
+ +Terminal commands to run DOCKERIZED API:
+# Make sure you cd into Backend folder.
+1. docker build -f docker_files/Dockerfile -t team51-backend .
+2. docker run -d -p 5000:5000 team51-backend
+3. pytest From a38d9766be7249fe77c329ce6d49f0ff430e3974 Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 01:53:07 -0500 Subject: [PATCH 5/7] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4b6f52..112d09b 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ Kunal Bagga kub21001
Link to Trello: [https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board](https://trello.com/b/j8t0Ulvk/group-51-jira-kaban-board)
Link to Figma Prototype: [https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray](https://www.figma.com/design/mKMWW1sIOVpuQKOlapBINQ/ishayu.ray)
-Terminal commands to run DOCKERIZED API:
-# Make sure you cd into Backend folder.
+# Terminal commands to run DOCKERIZED API:
+Make sure you cd into Backend folder.
1. docker build -f docker_files/Dockerfile -t team51-backend .
2. docker run -d -p 5000:5000 team51-backend
3. pytest From 0bc4c1ca469bf94e1a04563b5f392fcb0a706985 Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 02:01:28 -0500 Subject: [PATCH 6/7] Update ms5yml --- .github/workflows/ms5yml | 90 ++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 54 deletions(-) diff --git a/.github/workflows/ms5yml b/.github/workflows/ms5yml index d352c7f..6dcea33 100644 --- a/.github/workflows/ms5yml +++ b/.github/workflows/ms5yml @@ -1,59 +1,41 @@ -name: ms5API Testing +name: API CI/CD -on: - push: #we want only the milstone5 - branches: [Milestone-5_feature_branch] - pull_request: - branches: [Milestone-5_feature_branch] +on: + push: + branches: + - Milestone6-ericfeaturebranch jobs: - api-testing: - runs-on: ubuntu-latest + tests: + runs-on: self-hosted + strategy: + matrix: + #python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8"] steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Python 3 - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install flask flask_cors flasgger pylint pytest - - # Run pylint - - name: Run pylint - run: | - pylint ./backend/*.py - continue-on-error: false # Set to true to see warnings - - #docker image build - - name: Build API Docker Image - run: | - docker build -t api-image -f Dockerfile . - - #run docker container - - name: Start API Container - run: | - docker run -d -p 5000:5000 --name api-container api-image - - #running main.py - - name: Start API Service - run: | - docker exec api-container python main.py - - #test_main.py - - name: Run test_main.py - run: | - docker exec api-container pytest test_main.py --maxfail=1 --disable-warnings - - #cut the docker - - name: Stop and Remove API Container - run: | - docker stop api-container - docker rm api-container - - + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install pylint + run: | + python -m pip install --upgrade pip + pip install pylint + + - name: Install pytest + run: | + python -m pip install --upgrade pip + pip install pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Run Api + run: | + python3 Backend/app.py & + + - name: pytest + run: | + pytest + From 2b2ba22a69f126798b567ead198b748e07df2ae7 Mon Sep 17 00:00:00 2001 From: Eric O Asante Date: Fri, 8 Nov 2024 02:02:49 -0500 Subject: [PATCH 7/7] Update ms5yml