diff --git a/connector/Include/analytics.py b/connector/Include/analytics.py new file mode 100644 index 00000000..56f0b3ce --- /dev/null +++ b/connector/Include/analytics.py @@ -0,0 +1,116 @@ +from flask import Flask, request, jsonify +from flask_caching import Cache +import psycopg2 +import pandas +import json +from configparser import ConfigParser +from datetime import datetime + + +app = Flask(__name__) +cache = Cache(config={'CACHE_TYPE': 'SimpleCache'}) +db_connector = None +conn = None + + +@app.route("/api/get_number_of_ratings", methods=["GET"]) +@cache.cached(timeout=500) +def get_number_of_ratings(): + cursor = conn.cursor() + cursor.execute("select count(*) as num_of_ratings from ratings") + res = cursor.fetchall() + + cursor.close() + + return jsonify(res[0]), 200 + + +@app.route("/api/get_movie_ratings/", methods=["GET"]) +@cache.cached(timeout=50) +def get_movie_ratings(movie_id): + cursor = conn.cursor() + ratings = {} + rating_values = [5, 4, 3, 2, 1] + + for rating in rating_values: + cursor.execute(""" + SELECT COUNT(*) as count + FROM ratings + WHERE rating = %s AND movie_ID = %s; + """, (rating, movie_id)) + result = cursor.fetchone() + ratings[f'{rating}_star'] = result[0] + + cursor.close() + + return jsonify(ratings), 200 + + +@app.route("/api/get_users_number", methods=["GET"]) +@cache.cached(timeout=50) +def get_number_of_users(): + cursor = conn.cursor() + cursor.execute("select count(*) as num_of_users from users") + res = cursor.fetchall() + + cursor.close() + + return jsonify(res[0]), 200 + + +@app.route("/api/get_movie_rating_avg/", methods=["GET"]) +@cache.cached(timeout=50) +def get_movie_rating_avg(movie_id): + cursor = conn.cursor() + cursor.execute(""" + SELECT AVG(rating) as avg_rating + FROM ratings + WHERE movie_ID = %s; + """, (movie_id,)) + res = cursor.fetchall() + + cursor.close() + + return jsonify(res[0]), 200 + + +@app.route("/api/get_user_ratings/", methods=["GET"]) +@cache.cached(timeout=50) +def get_user_ratings(user_id): + cursor = conn.cursor() + cursor.execute(""" + SELECT movie_ID, rating + FROM ratings + WHERE oauth_ID = %s; + """, (user_id,)) + res = cursor.fetchall() + + cursor.close() + + return jsonify(res), 200 + + +if __name__ == "__main__": + config = ConfigParser() + config.read("init_scripts/constants.ini") + + while True: + try: + conn = psycopg2.connect( + host=config["postgres"]["host"], + database=config["postgres"]["database"], + user=config["postgres"]["user"], + password=config["postgres"]["password"], + port=int(config["postgres"]["port"]) + ) + + except Exception: + print("Trying to connect with database") + continue + else: + break + + cache.init_app(app) + app.run(host="localhost", port=8082, debug=True) + + conn.close() diff --git a/connector/Include/frontend_AI_connector.py b/connector/Include/frontend_AI_connector.py index 03209c79..c4326042 100644 --- a/connector/Include/frontend_AI_connector.py +++ b/connector/Include/frontend_AI_connector.py @@ -5,7 +5,7 @@ import pandas import json from configparser import ConfigParser from datetime import datetime - +import requests app = Flask(__name__) cache = Cache(config={'CACHE_TYPE': 'SimpleCache'}) @@ -13,27 +13,37 @@ db_connector = None conn = None movie_list = None + def error_decorator(fun): def inner1(*args, **kwargs): try: fun(*args, **kwargs) except psycopg2.DatabaseError: - return jsonify({"status": "Something... unexpected has occured :sweat_smile:"}), 500 - + return jsonify({"status": "Something... unexpected has occurred :sweat_smile:"}), 500 + return inner1 + @app.route("/", methods=["GET"]) @cache.cached(timeout=69) def hello(): return jsonify({"response": "Hello there", "time": datetime.now()}), 200 -#endpoint do wyciągania danych o userze + +# endpoint do wyciągania danych o userze @app.route("/api/v3/get/", methods=["GET"]) def access_user(username): - return jsonify({"us": "er"}), 200 + cursor = conn.cursor() + cursor.execute("select * from users where username='{}';".format(username)) + res = cursor.fetchall() -#endpoint służący do zapisu danych nowostworzonego użytkownika, podajemy mu -#id z oautha oraz login + cursor.close() + + return jsonify(res[0]), 200 + + +# endpoint służący do zapisu danych nowo stworzonego użytkownika, podajemy mu +# id z oautha oraz login @app.route("/api/v3/add//", methods=["POST"]) def add_user(oauth_ID, username): cursor = conn.cursor() @@ -42,7 +52,7 @@ def add_user(oauth_ID, username): if len(res): cursor.close() - return jsonify({"status": "User already exists"}), 500 + return jsonify({"status": "User already exists"}), 409 cursor.execute("INSERT INTO users (username, oauth_ID) VALUES ('{}','{}');".format( username, oauth_ID @@ -50,27 +60,33 @@ def add_user(oauth_ID, username): conn.commit() cursor.close() - + return jsonify({"status": "success"}), 200 -#roboczy endpoint służący do wyciąganiu rekomendacji +# roboczy endpoint służący do wyciąganiu rekomendacji @app.route("/api/v3/ai/", methods=["GET"]) def get_recommendations(oauth_ID): - #request od frontu na rekomendacje - #wysyłanie requestu do AI API o rekomendacje dla usera - #przesłanie danych do - return jsonify({"movies": ["3", "Wiedźmin 3", "Najlepszy."]}), 200 + cursor = conn.cursor() + cursor.execute("select movie_ID from ratings where oauth_ID='{}'", oauth_ID) + res = cursor.fetchall() + movies = [int(i) for i in res[0]] + url = 'http://localhost:8081/api/v3/AI_recommendations' + response = requests.post(url, + json=movies, + headers={'Content-Type': 'application/json'}) + return jsonify(response.json()), 200 + @app.route("/api/v3/get_movie/", methods=["GET"]) def get_movie(movie_ID): movie_info = movie_list.loc[movie_list['movie_id'] == movie_ID] if movie_info.empty: return jsonify({"status": "Movie with ID {} doesn't exist".format(movie_ID)} - ), 500 + ), 404 - cast = json.loads(movie_info["cast"][0].replace('\\"','"')) - crew = json.loads(movie_info["crew"][0].replace('\\"','"')) + cast = json.loads(movie_info["cast"][0].replace('\\"', '"')) + crew = json.loads(movie_info["crew"][0].replace('\\"', '"')) output_json = {"movie_id": movie_ID, "title": movie_info["title"][0], @@ -79,15 +95,16 @@ def get_movie(movie_ID): return jsonify(output_json), 200 + @app.route("/api/v3/rate_movie///", methods=["POST"]) def rate_movie(uID, movie_ID, rating): movie_info = movie_list.loc[movie_list['movie_id'] == int(movie_ID)] if movie_info.empty: return jsonify({"status": "Movie with ID {} doesn't exist".format(movie_ID)} - ), 500 + ), 404 if rating < 1 or rating > 5: - return jsonify({"status": "Incorrect rating"}), 500 + return jsonify({"status": "Incorrect rating"}), 400 cursor = conn.cursor() cursor.execute("select * from users where oauth_ID='{}';".format(uID)) @@ -95,7 +112,7 @@ def rate_movie(uID, movie_ID, rating): if not len(res): cursor.close() - return jsonify({"status": "User doesn't exists"}), 500 + return jsonify({"status": "User doesn't exists"}), 404 cursor.execute("select * from ratings where oauth_ID='{}' AND movie_ID='{}';".format(uID, movie_ID)) res = cursor.fetchall() @@ -115,7 +132,7 @@ def rate_movie(uID, movie_ID, rating): conn.commit() cursor.close() - + return jsonify({"status": "success"}), 200 @@ -138,12 +155,10 @@ if __name__ == "__main__": continue else: break - movie_list = pandas.read_csv(config["movie"]["csv_path"]) cache.init_app(app) - app.run(host="0.0.0.0",port=8090, debug=True) - + app.run(host="localhost", port=8090, debug=True) conn.close() diff --git a/connector/Include/init_scripts/constants.ini b/connector/Include/init_scripts/constants.ini index e922b009..508fb671 100644 --- a/connector/Include/init_scripts/constants.ini +++ b/connector/Include/init_scripts/constants.ini @@ -1,9 +1,9 @@ [postgres] -host=db +host=localhost database=test_db user=root password=root port=5432 [movie] -csv_path=init_scripts/movies.csv +csv_path=../../movie_recommendations/datasets/tmdb_5000_credits.csv diff --git a/movie_recommendations/Test.http b/movie_recommendations/Test.http deleted file mode 100644 index b4ba46b7..00000000 --- a/movie_recommendations/Test.http +++ /dev/null @@ -1,15 +0,0 @@ -### GET request to example server -GET http://127.0.0.1:5000/boop - -### - -POST http://127.0.0.1:5000/api/v3/AI_recommendations -Content-Type: application/json - -[ - 49026, - 155, - 312113 -] - -### diff --git a/movie_recommendations/movie_recommender.py b/movie_recommendations/movie_recommender.py index 40e15c30..f8616380 100644 --- a/movie_recommendations/movie_recommender.py +++ b/movie_recommendations/movie_recommender.py @@ -1,26 +1,20 @@ -import hashlib -import json -from datetime import datetime - import pandas as pd import numpy as np from ast import literal_eval from sklearn.feature_extraction.text import CountVectorizer from sklearn.metrics.pairwise import cosine_similarity +import hashlib +import json +from configparser import ConfigParser +import psycopg2 from flask import Flask, request, jsonify from flask_caching import Cache -config = { - "DEBUG": True, # some Flask specific configs - "CACHE_TYPE": "SimpleCache", - "CACHE_DEFAULT_TIMEOUT": 300 -} - app = Flask(__name__) - -app.config.from_mapping(config) -cache = Cache(app) +cache = Cache(config={'CACHE_TYPE': 'SimpleCache'}) +db_connector = None +conn = None def get_director(x): @@ -130,8 +124,8 @@ class MovieRecommender: recommender = MovieRecommender() -recommender.fit('movie_recommendations/datasets/tmdb_5000_credits.csv', - 'movie_recommendations/datasets/tmdb_5000_movies.csv') +recommender.fit('datasets/tmdb_5000_credits.csv', + 'datasets/tmdb_5000_movies.csv') def make_cache_key(): @@ -147,13 +141,30 @@ def make_cache_key(): def AI_recommendations(): ids = request.get_json() recommendations = recommender.get_recommendations(ids) - recommendations[0] = datetime.now() return jsonify(recommendations) -# Przykładowe użycie: -# if __name__ == "__main__": -# recommender = MovieRecommender() -# recommender.fit('datasets/tmdb_5000_credits.csv', 'datasets/tmdb_5000_movies.csv') -# recommendations = recommender.get_recommendations([49026, 155, 312113]) -# print(recommendations) +if __name__ == "__main__": + config = ConfigParser() + config.read("../connector/Include/init_scripts/constants.ini") + + while True: + try: + conn = psycopg2.connect( + host=config["postgres"]["host"], + database=config["postgres"]["database"], + user=config["postgres"]["user"], + password=config["postgres"]["password"], + port=int(config["postgres"]["port"]) + ) + + except Exception: + print("Trying to connect with database") + continue + else: + break + + cache.init_app(app) + app.run(host="localhost", port=8081, debug=True) + + conn.close() diff --git a/test_scripts/Test.http b/test_scripts/Test.http new file mode 100644 index 00000000..af04531c --- /dev/null +++ b/test_scripts/Test.http @@ -0,0 +1,32 @@ +### +POST http://127.0.0.1:8081/api/v3/AI_recommendations +Content-Type: application/json + +[ + 49026, + 155, + 312113 +] +### +POST http://127.0.0.1:8090/api/v3/add/1234/blep +### +GET http://127.0.0.1:8090/api/v3/get/blep +### +POST http://127.0.0.1:8090/api/v3/add/6666/blop +### +POST http://127.0.0.1:8090/api/v3/rate_movie/1234/155/4 +### +POST http://127.0.0.1:8090/api/v3/rate_movie/6666/155/5 +### +POST http://127.0.0.1:8090/api/v3/rate_movie/1234/19995/5 +### +GET http://localhost:8082/api/get_movie_ratings/155 +### +GET http://localhost:8082/api/get_number_of_ratings +### +GET http://localhost:8082/api/get_users_number +### +GET http://localhost:8082/api/get_movie_rating_avg/155 +### +GET http://localhost:8082/api/get_user_ratings/1234 +### \ No newline at end of file