diff --git a/.github/workflows/ms5.yaml b/.github/workflows/ms5.yaml new file mode 100644 index 0000000..47c0c77 --- /dev/null +++ b/.github/workflows/ms5.yaml @@ -0,0 +1,60 @@ +name: API CI/CD +# This is a trigger for any push to the repo, and tells github when the actions have to be run +# Every time we do a push, the action will be executed +# The actions should be run only when there is a push from main and develop +on: + push: + branches: + - main + - develop + +#Tells github actions what to execute when trigger condition is met +jobs: + # Each job runs in parallel + tests: #This is the job name + + # runs-on indicates which GitHub "Runners" will run this CICD pipeline + # For all CSE-2102 repos, just use the following line as is + runs-on: self-hosted + # This next block allows you to run this ENTIRE job on different python versions + strategy: + matrix: + #python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8"] + + # Steps are run in sequence in this job. If one step fails, the entire job fails. + steps: + # Use this next line to pull your repo into the Docker container running the job + - uses: actions/checkout@v3 + # This block sets up the python version + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + # Pylint is a static code analysis tool. Use this block as is to install pylint + # in the Docker container running the job + - 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/main.py & + + + - name: Run Pytest + run: | + pytest + + - name: Run Pylint + run: | + find ./Backend -name "*.py" | xargs pylint + + diff --git a/Backend/Docker b/Backend/Docker new file mode 100644 index 0000000..1021b0d --- /dev/null +++ b/Backend/Docker @@ -0,0 +1,11 @@ +FROM python:3.9-slim +WORKDIR /Docker1 +COPY main.py main.py +COPY PetFuc.py PetFuc.py +COPY UserFuc.py UserFuc.py +COPY test_main.py test_main.py +COPY requirements.txt requirements.txt +RUN pip3 install -r requirements.txt +CMD [ "python3", "main.py" ] + + diff --git a/Backend/main.py b/Backend/main.py new file mode 100644 index 0000000..0728623 --- /dev/null +++ b/Backend/main.py @@ -0,0 +1,54 @@ +""" +This module provides functions for HTTP communication and +route functions +""" +from flask import Flask, request, jsonify +from petfuc import get_random_pet +from userfuc import add_user_faviorte, remove_user_faviorte, replace_user_location + +app = Flask(__name__) + +#Get Random Pet information - For homepage +@app.route("/Get_Random_pet", methods=["GET"]) +def random_pet(): + """ + Function to extract random pet information + """ + return get_random_pet(), 200 # Return dog information + +# Faviortes route. add user faviorte pet to database +@app.route("/Add_User_Faviorte", methods=["POST"]) +def adduserfaviorte(): + """ + Function to add user from database + """ + json_data = request.get_json() + + # Api accesses database and append post json in database + #Retrun database with succses code + return jsonify(add_user_faviorte(json_data)), 200 + +# Un Faviote Route. remove user faviorte pet from there database +@app.route("/Remove_User_Faviorte", methods=["DELETE"]) +def removeuserfaviorte(): + """ + Function to remove user from database + """ + json_data = request.get_json() + + # Api accesses database and append post json in database + #Retrun database with succses code + return jsonify(remove_user_faviorte(json_data)), 200 # return new user database + +# Change a Users account location +@app.route("/Change_User_Location", methods=["PUT"]) +def replace_user_information(): + """ + Function to change the location associated with + an account + """ + newlocation = request.get_json() # Get new location from post request + return jsonify(replace_user_location(newlocation)) # retrun user account info + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) diff --git a/Backend/petfuc.py b/Backend/petfuc.py new file mode 100644 index 0000000..5e60700 --- /dev/null +++ b/Backend/petfuc.py @@ -0,0 +1,22 @@ +""" +This module provides functions for HTTP communication and +route functions +""" +from flask import jsonify + + +def get_random_pet(): + """ + Function to generate random ID and return pet + asscoieted with that ID + """ + randomint = "9" # APi generates random interger that represents a PET ID + # Api accesses database and return information in data base + #Retrun information such as profile picture on the pet accosiated with the random ID + data = {"id": randomint, + "name":"sam", + "sex":"male", + "Age":"8", + "location":"Connecticwut", + "Breed": "Pug"} + return jsonify(data) # Return dog information diff --git a/Backend/requirements.txt b/Backend/requirements.txt new file mode 100644 index 0000000..8bbecc4 --- /dev/null +++ b/Backend/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.3 +requests==2.32.3 \ No newline at end of file diff --git a/Backend/test_main.py b/Backend/test_main.py new file mode 100644 index 0000000..6ff3eea --- /dev/null +++ b/Backend/test_main.py @@ -0,0 +1,157 @@ +""" +Pytest for fake API +""" + +import requests + +def test_get_random_pet(): + """ + Test for http://localhost:5000/Get_Random_pet + """ + + url = "http://localhost:5000" + + response = requests.get((url + "/Get_Random_pet"), timeout=10) + + expected_response = { + "id": "9", + "name": "sam", + "sex": "male", + "Age": "8", + "location": "Connecticwut", + "Breed": "Pug" + } + + assert response.json() == expected_response + +# ----------------------------------------------------------------------------- + +def test_add_user_faviorte(): + """ + Test for http://localhost:5000/Add_User_Faviorte + """ + + url = "http://localhost:5000" + + faviortepet1 = { + "id": "9", + "name": "sam", + "sex": "male", + "Age": "8", + "location": "Connecticut", + "Breed": "Pug" + } + + + response = requests.post((url + "/Add_User_Faviorte"), json=faviortepet1, timeout=10) + + assert response.json() == [{'Age': '8', + 'Breed': 'Pug', + 'id': '9', + 'location': + 'Connecticut', + 'name': 'sam', + 'sex': 'male'}] + + faviortepet2 = { + "id": "90", + "name": "ben", + "sex": "male", + "Age": "2", + "location": "New York", + "Breed": "Husky" + } + + response = requests.post((url + "/Add_User_Faviorte"), json=faviortepet2, timeout=10) + + assert response.json() == [{'Age': '8', + 'Breed': 'Pug', + 'id': '9', + 'location': 'Connecticut', + 'name': 'sam', + 'sex': 'male'}, + {'Age': '2', + 'Breed': 'Husky', + 'id': '90', + 'location': 'New York', + 'name': 'ben', + 'sex': 'male'}] + +# ---------------------------------------------------------------------------------- + +def test_remove_user_faviorte(): + """ + Test for http://localhost:5000/Remove_User_Faviorte + """ + + url = "http://localhost:5000" + + faviortepet1 = { + "id": "9", + "name": "sam", + "sex": "male", + "Age": "8", + "location": "Connecticut", + "Breed": "Pug" + } + + + response = requests.delete((url + "/Remove_User_Faviorte"), json=faviortepet1, timeout=10) + + assert response.json() == [{'Age': '2', + 'Breed': 'Husky', + 'id': '90', + 'location': 'New York', + 'name': 'ben', + 'sex': 'male'}] + + faviortepet2 = { + "id": "90", + "name": "ben", + "sex": "male", + "Age": "2", + "location": "New York", + "Breed": "Husky" + } + + response = requests.delete((url + "/Remove_User_Faviorte"), json=faviortepet2, timeout=10) + + assert response.json() == [] +# ---------------------------------------------------------------------------------- + + + +def test_change_user_location(): + """ + Test for http://localhost:5000/Change_User_Location + """ + + url = "http://localhost:5000" + + response = requests.put((url + "/Change_User_Location"), + json={"Location":"New York"}, + timeout=10) + + assert response.json() == {"Location": "New York", + "Name": "eric", + "Occupation": "Student", + "Password": "2020"} + + + response = requests.put((url + "/Change_User_Location"), + json={"Location":"Chicago"}, + timeout=10) + + assert response.json() == {"Location": "Chicago", + "Name": "eric", + "Occupation": "Student", + "Password": "2020"} + + response = requests.put((url + "/Change_User_Location"), + json={"Location":"Massachusetts"}, + timeout=10) + + assert response.json() == {"Location": "Massachusetts", + "Name": "eric", + "Occupation": "Student", + "Password": "2020"} diff --git a/Backend/userfuc.py b/Backend/userfuc.py new file mode 100644 index 0000000..ef15a7c --- /dev/null +++ b/Backend/userfuc.py @@ -0,0 +1,39 @@ +""" +This module provides functions for HTTP communication and +route functions +""" +UserFaviorteDataBase = [] # pretend this is a database + +UserAccInfo = {"Name":"eric", + "Password":"2020", + "Location":"connecticut", + "Occupation":"Student"} # example user information + +# add user faviorte pet to database +def add_user_faviorte(jsondata): + """ + add user to database and return database elements + """ + UserFaviorteDataBase.append(jsondata) + # accesses database and append post json in database + return UserFaviorteDataBase # return new user database + + +# Remove user faviorte pet to database +def remove_user_faviorte(jsondata): + """ + remove user from database and return database elements + """ + UserFaviorteDataBase.remove(jsondata) + # accesses database and append post json in database + return UserFaviorteDataBase # return new user database + + +# Change a Users account location +def replace_user_location(newlocation): + """ + Replace location associated with a user account + """ + newlocation = newlocation.get('Location') + UserAccInfo["Location"] = newlocation # Set location accosiated with user to new location + return UserAccInfo # retrun user account info diff --git a/Frontend/hi.txt b/Frontend/hi.txt new file mode 100644 index 0000000..53a199a --- /dev/null +++ b/Frontend/hi.txt @@ -0,0 +1 @@ +I'm just testing the ci/cd :) \ No newline at end of file diff --git a/Frontend/index.html b/Frontend/index.html new file mode 100644 index 0000000..e69de29