diff --git a/backend/application.py b/backend/application.py index 7a3792e..b9beb22 100644 --- a/backend/application.py +++ b/backend/application.py @@ -1,19 +1,20 @@ +""" Main server file """ import json +from datetime import datetime +from flask_cors import CORS from flask import Flask, session, Response from flask_session import Session -from flask_cors import CORS -from datetime import datetime from utils import get_connection, config_app + sauron = Flask(__name__) +PATH = "config.json" +sauron = config_app(sauron, path=PATH) CORS(sauron) -path = "config.json" - -sauron = config_app(sauron, path=path) conn = get_connection() Session(sauron) - +#pylint: disable=wrong-import-position from experience import experience_api from bio import bio_api from projects import projects_api @@ -29,11 +30,12 @@ @sauron.route("/sauron/health", methods = ["GET"]) def health(): - t = str(datetime.now()) + """ Server health """ + _t = str(datetime.now()) msg = { "name": "Sauron-Service", "health": "Excellent", - "at time": t + "at time": _t } session.clear() result = Response(json.dumps(msg), status=200, content_type="application/json") @@ -42,12 +44,15 @@ def health(): @sauron.route("/sauron/login", methods = ["POST"]) def login(): + """ Manage Login """ pass sauron.route("/sauron/logout", methods = ["GET"]) def logout(): + """ Manage Logout """ pass if __name__ == "__main__": - sauron.run('0.0.0.0', port = 5011, debug=True) \ No newline at end of file + sauron.run('0.0.0.0', port = 5011, debug=True) + \ No newline at end of file diff --git a/backend/bio.py b/backend/bio.py index 8d7fd1c..2c83853 100644 --- a/backend/bio.py +++ b/backend/bio.py @@ -1,85 +1,94 @@ +""" This file manages routes for bio """ import json +import uuid +from datetime import datetime from flask import Blueprint, Response, request import requests -from datetime import datetime from utils import get_connection from model import Bio -import uuid bio_api = Blueprint('bio_api', __name__) conn = get_connection() -table = "Bio" +TABLE = "Bio" URL = "http://localhost:5011/" -@bio_api.route("/health", methods = ["GET"]) +@bio_api.route("/health", methods=["GET"]) def test(): - t = str(datetime.now()) + """ Test """ + _t = str(datetime.now()) msg = { "name": "Sauron-Bio-Service", "health": "Excellent", - "at time": t + "at time": _t } - result = Response(json.dumps(msg), status=200, content_type="application/json") + result = Response(json.dumps(msg), status=200, + content_type="application/json") return result -@bio_api.route("/get", methods = ["GET"]) + +@bio_api.route("/get", methods=["GET"]) def get_bio(): + """ Get bio info """ cursor = conn.cursor() - cursor.execute("SELECT * FROM {}".format(table)) + cursor.execute("SELECT * FROM {}".format(TABLE)) query_result = cursor.fetchall() if len(query_result) == 0: return "No bio exists", 404 - + return {"data": Bio(*query_result[0].values()).__dict__} -@bio_api.route("/add", methods = ["POST"]) +@bio_api.route("/add", methods=["POST"]) def add_bio(): + """ Add bio """ data = request.json - msg = requests.get(URL + "/sauron/backend/bio/get") + msg = requests.get(URL + "/sauron/backend/bio/get", timeout=5) if msg.status_code == 200: return "Bio already exists", 400 - try: - id = str(uuid.uuid4()) - query = "INSERT INTO {} VALUES ('{}', '{}')".format(table, id, data['data']) + try: + id_ = str(uuid.uuid4()) + query = "INSERT INTO {} VALUES ('{}', '{}')".format( + TABLE, id_, data['data']) cursor = conn.cursor() cursor.execute(query) conn.commit() - except: + except Exception: conn.rollback() return "Failed to add bio", 500 return "Added bio", 200 -@bio_api.route("/update", methods = ["PUT"]) +@bio_api.route("/update", methods=["PUT"]) def update_bio(): + """ Update bio """ data = request.json - msg = requests.get(URL + "/sauron/backend/bio/get") + msg = requests.get(URL + "/sauron/backend/bio/get", timeout=5) if msg.status_code == 400: return "Bio does not exist", 400 - id = msg.json()['data']['id'] + id_ = msg.json()['data']['id'] try: - query = "UPDATE {} SET bio = '{}' where id = '{}'".format(table, data['data'], id) + query = "UPDATE {} SET bio = '{}' where id = '{}'".format( + TABLE, data['data'], id_) cursor = conn.cursor() cursor.execute(query) conn.commit() - except: + except Exception: conn.rollback() return "Failed to update bio", 500 return "Updated bio", 200 -@bio_api.route("/delete", methods = ["DELETE"]) +@bio_api.route("/delete", methods=["DELETE"]) def remove_bio(): + """ Remove bio """ cursor = conn.cursor() - cursor.execute("DELETE FROM {}".format(table)) + cursor.execute("DELETE FROM {}".format(TABLE)) query_result = cursor.fetchall() if len(query_result) == 0: return "Deleted", 200 - - return None + return None diff --git a/backend/experience.py b/backend/experience.py index 2b42da9..0a35857 100644 --- a/backend/experience.py +++ b/backend/experience.py @@ -1,7 +1,8 @@ +""" This file manages routes for experience """ import json -from flask import Blueprint, Response -import requests from datetime import datetime +import requests +from flask import Blueprint, Response from utils import get_connection from model import Experience @@ -9,80 +10,89 @@ experience_api = Blueprint('experience_api', __name__) conn = get_connection() URL = "http://localhost:5011" -table = "Experience" +TABLE = "Experience" -@experience_api.route("/health", methods = ["GET"]) +@experience_api.route("/health", methods=["GET"]) def test(): - t = str(datetime.now()) + """ Test """ + _t = str(datetime.now()) msg = { "name": "Sauron-Experience-Service", "health": "Excellent", - "at time": t + "at time": _t } - result = Response(json.dumps(msg), status=200, content_type="application/json") + result = Response(json.dumps(msg), status=200, + content_type="application/json") return result -@experience_api.route("/get/all", methods = ["GET"]) + +@experience_api.route("/get/all", methods=["GET"]) def get_all_experiences(): + """ Get all experiences """ cursor = conn.cursor() - cursor.execute("SELECT * FROM {}".format(table)) + cursor.execute("SELECT * FROM {}".format(TABLE)) query_result = cursor.fetchall() if query_result is None: return "No experience exists", 404 - data = [] for exp in query_result: data.append({"data": Experience(*exp.values()).__dict__}) return data -@experience_api.route("/get/", methods = ["GET"]) -def get_experience_by_id(id): + +@experience_api.route("/get/", methods=["GET"]) +def get_experience_by_id(id_): + """ Get experience by ID """ cursor = conn.cursor() - cursor.execute("SELECT * FROM {} where id='{}'".format(table, id)) + cursor.execute("SELECT * FROM {} where id='{}'".format(TABLE, id_)) query_result = cursor.fetchone() if query_result is None: return "Experience does not exist", 404 - return {"data": Experience(*query_result.values()).__dict__} - # TODO: ADD and UPDATE -@experience_api.route("/add/", methods = ["POST"]) -def add_experience(id): +@experience_api.route("/add", methods=["POST"]) +def add_experience(): + """ Add experience """ pass -@experience_api.route("/update/", methods = ["PUT"]) -def update_experience(id): +@experience_api.route("/update", methods=["PUT"]) +def update_experience(): + """ Update experience by ID """ pass -@experience_api.route("/delete/all", methods = ["DELETE"]) + +@experience_api.route("/delete/all", methods=["DELETE"]) def remove_all_experiences(): + """ Remove all experiences """ cursor = conn.cursor() - cursor.execute("DELETE FROM {}".format(table)) + cursor.execute("DELETE FROM {}".format(TABLE)) query_result = cursor.fetchall() if len(query_result) == 0: return "Deleted", 200 - + return None -@experience_api.route("/delete/", methods = ["DELETE"]) -def remove_experience_by_id(id): + +@experience_api.route("/delete/", methods=["DELETE"]) +def remove_experience_by_id(id_): + """ Remove experience by ID """ cursor = conn.cursor() - msg = requests.get(URL + "/sauron/backend/exp/get/{}".format(id)) - if msg.status_code == 404: + msg = requests.get( + "{}/sauron/backend/exp/get/{}".format(URL, id_), timeout=5) + if msg.status_code == 404: return msg.text, 404 - cursor.execute("DELETE FROM {} where id='{}'".format(table, id)) + cursor.execute("DELETE FROM {} where id='{}'".format(TABLE, id_)) query_result = cursor.fetchone() if query_result is None: - return id, 200 - - return None + return id_, 200 + return None diff --git a/backend/links.py b/backend/links.py index dc05d2f..cf30e4c 100644 --- a/backend/links.py +++ b/backend/links.py @@ -18,11 +18,11 @@ def test(): """ Test """ - t = str(datetime.now()) + _t = str(datetime.now()) msg = { "name": "Sauron-Link-Service", "health": "Excellent", - "at time": t + "at time": _t } result = Response(json.dumps(msg), status=200, content_type="application/json") diff --git a/backend/model.py b/backend/model.py index 27bb5c9..8610b33 100644 --- a/backend/model.py +++ b/backend/model.py @@ -1,39 +1,52 @@ class Experience: - def __init__(self, id, role, company, type, location, logo, start_date, end_date, desc, tech) -> None: - self.id = id + """ Model for Experience """ + + def __init__( + self, _id, role, company, _type, location, logo, start_date, end_date, desc, tech + ) -> None: + self._id = _id self.role = role self.company = company - self.type = type + self._type = _type self.location = location self.logo = logo self.start_date = start_date self.end_date = end_date self.desc = desc - self.tech = tech + self.tech = tech class Bio: - def __init__(self, id, bio) -> None: - self.id = id + """ Model for Bio """ + + def __init__(self, _id, bio) -> None: + self._id = _id self.bio = bio class Projects: - def __init__(self, id, title, desc, link) -> None: - self.id = id + """ Model for Projects """ + + def __init__(self, _id, title, desc, link) -> None: + self._id = _id self.title = title self.desc = desc self.link = link + class Photo: - def __init__(self, id, photo_name, photo_url) -> None: - self.id = id + """ Model for Photo """ + + def __init__(self, _id, photo_name, photo_url) -> None: + self._id = _id self.photo_name = photo_name self.photo_url = photo_url - + class Links: - def __init__(self, id, name, link) -> None: - self.id = id + """ Model for Links """ + + def __init__(self, _id, name, link) -> None: + self._id = _id self.name = name - self.link = link \ No newline at end of file + self.link = link diff --git a/backend/projects.py b/backend/projects.py index 2980011..ae5d019 100644 --- a/backend/projects.py +++ b/backend/projects.py @@ -1,87 +1,97 @@ +""" This file manages routes for projects """ import json +from datetime import datetime from flask import Blueprint, Response import requests -from datetime import datetime from utils import get_connection from model import Projects projects_api = Blueprint('projects_api', __name__) conn = get_connection() -table = "Projects" +TABLE = "Projects" URL = "http://localhost:5011" -@projects_api.route("/health", methods = ["GET"]) + +@projects_api.route("/health", methods=["GET"]) def test(): - t = str(datetime.now()) + """ Test """ + _t = str(datetime.now()) msg = { "name": "Sauron-Projects-Service", "health": "Excellent", - "at time": t + "at time": _t } - result = Response(json.dumps(msg), status=200, content_type="application/json") + result = Response(json.dumps(msg), status=200, + content_type="application/json") return result -@projects_api.route("/get/all", methods = ["GET"]) -def get_all_experiences(): +@projects_api.route("/get/all", methods=["GET"]) +def get_all_projects(): + """ Get all projects """ cursor = conn.cursor() - cursor.execute("SELECT * FROM {}".format(table)) + cursor.execute("SELECT * FROM {}".format(TABLE)) query_result = cursor.fetchall() if query_result is None: return "No project exists", 404 - data = [] for exp in query_result: data.append({"data": Projects(*exp.values()).__dict__}) return data -@projects_api.route("/get/", methods = ["GET"]) -def get_experience_by_id(id): + +@projects_api.route("/get/", methods=["GET"]) +def get_project_by_id(_id): + """ Get project by id """ cursor = conn.cursor() - cursor.execute("SELECT * FROM {} where id='{}'".format(table, id)) + cursor.execute("SELECT * FROM {} where id='{}'".format(TABLE, _id)) query_result = cursor.fetchone() if query_result is None: return "Project does not exist", 404 - - return {"data": Projects(*query_result.values()).__dict__} + return {"data": Projects(*query_result.values()).__dict__} # TODO: ADD and UPDATE -@projects_api.route("/add/", methods = ["POST"]) -def add_experience(id): +@projects_api.route("/add", methods=["POST"]) +def add_experience(): + """ Add project """ pass -@projects_api.route("/update/", methods = ["PUT"]) -def update_experience(id): +@projects_api.route("/update/", methods=["PUT"]) +def update_experience(_id): + """ Update project by id """ pass -@projects_api.route("/delete/all", methods = ["DELETE"]) + +@projects_api.route("/delete/all", methods=["DELETE"]) def remove_all_experiences(): + """ Remove all projects """ cursor = conn.cursor() - cursor.execute("DELETE FROM {}".format(table)) + cursor.execute("DELETE FROM {}".format(TABLE)) query_result = cursor.fetchall() if len(query_result) == 0: return "Deleted", 200 - return None -@projects_api.route("/delete/", methods = ["DELETE"]) -def remove_experience_by_id(id): + +@projects_api.route("/delete/", methods=["DELETE"]) +def remove_experience_by_id(_id): + """ Remove project by id """ cursor = conn.cursor() - msg = requests.get(URL + "/sauron/backend/proj/get/{}".format(id)) - if msg.status_code == 404: + msg = requests.get( + URL + "/sauron/backend/proj/get/{}".format(_id), timeout=5) + if msg.status_code == 404: return msg.text, 404 - cursor.execute("DELETE FROM {} where id='{}'".format(table, id)) + cursor.execute("DELETE FROM {} where id='{}'".format(TABLE, _id)) query_result = cursor.fetchone() if query_result is None: return id, 200 - - return None + return None diff --git a/backend/utils.py b/backend/utils.py index 6615be5..7a1b20e 100644 --- a/backend/utils.py +++ b/backend/utils.py @@ -1,7 +1,8 @@ -import pymysql -import os +""" This file manages utility functions """ from datetime import timedelta +import os import json +import pymysql from werkzeug.utils import secure_filename import boto3 @@ -13,44 +14,51 @@ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} - def config_app(app, path): + """ Populates environment variables """ try: - with open(path) as config_file: + with open(path, encoding='utf-8') as config_file: data = json.load(config_file) for keys in data.keys(): os.environ[keys] = data[keys] app.secret_key = os.environ.get("SECRET") or os.urandom(24) app.config["SESSION_TYPE"] = os.environ.get("SESSION_TYPE", None) - app.config["SESSION_PERMANENT"] = True if os.environ.get("SESSION_PERMANENT", None) == "True" else False - app.config["SESSION_USE_SIGNER"] = True if os.environ.get("SESSION_USE_SIGNER", None) == "True" else False - app.permanent_session_lifetime = timedelta(days = 10) - except: + app.config["SESSION_PERMANENT"] = True if os.environ.get( + "SESSION_PERMANENT", None) == "True" else False + app.config["SESSION_USE_SIGNER"] = True if os.environ.get( + "SESSION_USE_SIGNER", None) == "True" else False + app.permanent_session_lifetime = timedelta(days=10) + except FileNotFoundError: print("\nxx Config doesnt exist\n") exit(1) return app def get_connection(): + """ Establish a connection with DB """ usr = os.environ.get("DBUSER") - pw = os.environ.get("DBPW") - h = os.environ.get("DBHOST") - db = "sauron" + _pw = os.environ.get("DBPW") + _h = os.environ.get("DBHOST") + _db = "sauron" conn = pymysql.connect( user=usr, - password=pw, - host=h, - db=db, + password=_pw, + host=_h, + db=_db, cursorclass=pymysql.cursors.DictCursor, autocommit=True ) return conn + def allowed_file(filename): + """ Check for allowed file types """ return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + def upload_file_to_s3(file): + """ Utility function to upload files to s3 """ filename = secure_filename(file.filename) try: s3.upload_fileobj( @@ -59,18 +67,18 @@ def upload_file_to_s3(file): "photography/" + filename ) - except Exception as e: - print("Error uploading image/logo: ", e) - return e + except Exception as _e: + print("Error uploading image/logo: ", _e) + return _e return filename -#TODO: Implement image compressor +# TODO: Implement image compressor # def image_compressor(image_file, filename): - + # image = Image.open(image_file) # image.save(filename, -# "png", -# optimize = True, +# "png", +# optimize = True, # quality = 65) -# return \ No newline at end of file +# return