Skip to content

Commit

Permalink
resolve cyclic import
Browse files Browse the repository at this point in the history
  • Loading branch information
yeh-sudo committed Oct 24, 2023
1 parent dc7c801 commit 8c50dd2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 37 deletions.
41 changes: 41 additions & 0 deletions app/utils/connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Establish connection or delete connection between application and MongoDB, Redis."""

import os
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
import redis

def connect_to_database():
"""
Connect to database.
Return:
object: connection to database.
"""

try:
connection = MongoClient(os.getenv("MONGO_URI"))
except ConnectionFailure as error:
print(f"Error: MongoDB connection not established {error}")
else:
print("MongoDB: Connection established.")
return connection

def connect_to_redis():
"""
Connect to Redis.
Return:
object: connection to Redis.
"""

try:
connection = redis.Redis(host=os.getenv("REDIS_HOST"),
port=os.getenv("REDIS_PORT"),
encoding="utf8",
decode_responses=True)
except ConnectionError as error:
print(f"Error: Redis connection not established {error}")
else:
print("Redis: Connection established.")
return connection
27 changes: 6 additions & 21 deletions app/utils/databases.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
"""Database class variables."""

import os
from fastapi import HTTPException, status
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure, OperationFailure
import redis
from pymongo.errors import OperationFailure
from ..models.user import User
from ..models.recommend_list import RecommendList
from .recommend_task import RecommendComputeTask
from . import recommend_task
from .connection import connect_to_redis, connect_to_database

class RedisDB():
"""
Expand Down Expand Up @@ -37,15 +35,7 @@ class RedisDB():

def __init__(self) -> None:
if RedisDB.client is None:
try:
RedisDB.client = redis.Redis(host=os.getenv("REDIS_HOST"),
port=os.getenv("REDIS_PORT"),
encoding="utf8",
decode_responses=True)
except ConnectionError as error:
print(f"Error: Redis connection not established {error}")
else:
print("Redis: Connection established.")
RedisDB.client = connect_to_redis()

def create_user_hmap(self, uid: str, preferences: list):
"""
Expand Down Expand Up @@ -98,12 +88,7 @@ class NckufeedDB():

def __init__(self) -> None:
if NckufeedDB.client is None:
try:
NckufeedDB.client = MongoClient(os.getenv("MONGO_URI"))
except ConnectionFailure as error:
print(f"Error: MongoDB connection not established {error}")
else:
print("MongoDB: Connection established.")
NckufeedDB.client = connect_to_database()

def find_user(self, uid: str):
"""
Expand Down Expand Up @@ -217,7 +202,7 @@ def modify_user(self, uid: str, user_data: dict):
detail="Can't update user's self_intro.") from error
if "preference" in user_data:
RedisDB().create_user_hmap(uid, user_data["preference"])
thread = RecommendComputeTask(uid)
thread = recommend_task.RecommendComputeTask(uid)
thread.start()
thread.join()
RedisDB().create_user_hmap(uid, user_data["preference"])
Expand Down
42 changes: 26 additions & 16 deletions app/utils/recommend_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import pandas as pd
import numpy as np
from sklearn.preprocessing import MultiLabelBinarizer
from pymongo.errors import OperationFailure
from fastapi import HTTPException, status
from . import databases
from pymongo.errors import OperationFailure
from ..models.recommend_list import RecommendList
from ..models.restaurant import Restaurant
from .connection import connect_to_redis, connect_to_database


class RecommendComputeTask(Thread):
Expand All @@ -25,8 +25,24 @@ def __init__(self, uid: str):
uid (str): user's uid
"""

super(RecommendComputeTask, self).__init__()
super().__init__()
self.__uid = uid
self.__redis_client = connect_to_redis()
self.__mongo_client = connect_to_database()

def calculate_similarity(self, restaurants_df, new_preferences):
"""Calculate similarity and return it.
"""

new_preferences_matrix = np.array(new_preferences, dtype=np.float32)
tags = restaurants_df.loc[:, "tags"]

# One hot encoding tags and compute similarity
mlb = MultiLabelBinarizer()
tags_matrix = pd.DataFrame(mlb.fit_transform(tags),
columns=mlb.classes_,
index=tags.index).to_numpy(dtype=np.float32)
return np.dot(tags_matrix, np.transpose(new_preferences_matrix)).tolist()

def run(self):
"""
Expand All @@ -35,10 +51,10 @@ def run(self):
"""

# Get's user's new preference from redis
new_preferences = databases.RedisDB().get_preference(self.__uid)
new_preferences = [float(x) for x in self.__redis_client.hvals(self.__uid)]

# Update user's new preference in database.
user_collection = databases.NckufeedDB.client.nckufeed["users"]
user_collection = self.__mongo_client.nckufeed["users"]
try:
user_collection.update_one(
{ "uid": self.__uid },
Expand All @@ -52,20 +68,14 @@ def run(self):
print(f"Error: Couldn't update new preference {error}")
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
detail="Can't update preference.") from error
databases.RedisDB.client.delete(self.__uid)
new_preferences_matrix = np.array(new_preferences, dtype=np.float32)
self.__redis_client.delete(self.__uid)

# Get all restaurants' info from database
restaurants = databases.NckufeedDB.client.nckufeed["restaurants"]
restaurants = self.__mongo_client.nckufeed["restaurants"]
restaurants_df = pd.DataFrame(list(restaurants.find({})))
tags = restaurants_df.loc[:, "tags"]

# One hot encoding tags and compute similarity
mlb = MultiLabelBinarizer()
tags_matrix = pd.DataFrame(mlb.fit_transform(tags),
columns=mlb.classes_,
index=tags.index).to_numpy(dtype=np.float32)
similarity = np.dot(tags_matrix, np.transpose(new_preferences_matrix)).tolist()
# Get similarity
similarity = self.calculate_similarity(restaurants_df, new_preferences)

# Insert similarity to dataframe and generate new recommend list
restaurants_df.insert(0, "similarity", similarity)
Expand All @@ -74,7 +84,7 @@ def run(self):
recommendation = []
count = 0
page = 1
recommend_list_collection = databases.NckufeedDB.client.nckufeed["recommend_list"]
recommend_list_collection = self.__mongo_client.nckufeed["recommend_list"]
for _, row in restaurants_df.iterrows():
if count == 100:
count = 0
Expand Down

0 comments on commit 8c50dd2

Please sign in to comment.