import streamlit as st import re import altair as alt from folder_management import create_folder, remove_files_folder st.set_page_config('Product Recommendation Application', layout='wide', page_icon='airtory_logo.PNG') # Functions/Pages def intro(): import streamlit as st st.markdown("## Welcome to the Product Recommendation Application! 👋") st.sidebar.success("Select a page from above.") st.markdown( """ **👈 Select a page from the navigation bar to the left** ### Functionality of Pages #### Generate Recommendations Page - This page allows you to generate recommendations for a particular keyword/publisherid combo. - The recommendations for each keyword/publisherid combo, are stored in a separate SQLite Database Table. - Ideally, for each keyword/publisherid combo, the recommendations should only be generated once per day. To mock this, you are only allowed to generate recommendations for a specific keyword/publisherid combo once. #### Product Recommendations Page - This page displays the Product Recommendations for each keyword/publisherid combo for which the recommendations were generated in the previous page. - You can currently select the available keywords from the dropdown provided in the side bar. - For the time being, the Publisher ID is restricted to a single known value. This can be easily updated later. - Note: Since the click tracker I was using had issues, as a workaround I had to use a Button instead. So now, to register a click against a product, you need to click on the 'Select' button provided below each product. - For each session, once a product is clicked on, it is no longer displayed. - You can choose the number of recommendations to be displayed, between 1 & 5. - The maximum number of recommendations that are available for display for each keyword/publisherid combo is restricted to 50. - The minumum number depends on the products available from bizrate. - If/when all available recommendations for a keyword/publisherid combo has been clicked on, you can either choose a different keyword, reload the application to create a new session. #### Analytics Page - Displays a Line Chart and a Bar Chart, to show the distribution of clicks across Session ID, Keyword, Publisher ID, SKU or Date. - Displays a table of the most clicked SKU's """ ) def generate_recommendations(): import os import string import random import streamlit as st import warnings warnings.filterwarnings('ignore') # custom module # from clickcounter import clickcounter from folder_management import create_folder, remove_files_folder from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table from recommend import query_bizrate, recommend, generate_clickreport # Functions def random_string(N=7): res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N)) return str(res) def query_and_recommend(keyword, publisherid): query_bizrate(keyword, publisherid) recommend(keyword, publisherid) generate_clickreport() # Main Program # st.set_page_config('Generate Recommendations', layout='wide') st.title('Generate Recommendations') st.markdown('''
Generate Recommendations for any Keyword - Publisher ID Combo.
''',
unsafe_allow_html=True)
col1, col2 = st.columns(2)
selected_keyword = ''
publisher_id = ''
with col1:
selected_keyword = st.text_input('Enter a single word as keyword:', 'bed')
selected_keyword = selected_keyword.lower()
selected_keyword = selected_keyword.replace('-', '')
selected_keyword = ''.join(re.split(r"[ \|\\\/,.]", selected_keyword))
# selected_keyword = ''.join(selected_keyword.split())
st.write(selected_keyword)
with col2:
publisher_id = st.text_input("Enter a Publisher ID: ", '726189')
# st.write(publisher_id)
keyword_pubid_list = []
for file in os.listdir('bizrate'):
keyword_pubid_list.append(file.replace(".xml", ""))
if selected_keyword + "_" + publisher_id in keyword_pubid_list:
st.error('Keyword - Publisher ID Combo Exists!')
else:
st.info("Keyword - Publisher ID Combo doesn't exist. Must be queried")
st.button('Generate Recommendations', key=random_string(), on_click=query_and_recommend,
args=([selected_keyword, publisher_id]))
def display_recommendations():
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
import urllib.parse
import os
import string
import random
import time
import streamlit as st
import uuid
import warnings
import sys
warnings.filterwarnings('ignore')
# custom module
# from clickcounter import clickcounter
from folder_management import create_folder, remove_files_folder
from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table
# Functions
def random_string(N=7):
res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N))
return str(res)
# def display_products(dfp):
# product_list = list(dfp['title'])
# image_list = list(dfp['Image'])
# price_list = list(dfp['price'])
# org_price = list(dfp['originalPrice'])
# disc_list = list(dfp['markdownPercent'])
# dfp['Skus'] = dfp['Skus'].astype('object')
# sku_list = list(dfp['Skus'])
# url_list = list(dfp['url'])
# clicked_sku, counter_dict = clickcounter(image_list, sku_list, price_list, disc_list, org_price, url_list, product_list)
# return clicked_sku, counter_dict
# Main Program
# st.set_page_config('Product Recommender System', layout='wide')
st.title('Product Recommender System')
st.markdown('''
It will take as inputs: Keyword and Publisher ID.
Displays (upto) Top 5 Recommendations & Collects Click Information.
''',
unsafe_allow_html=True)
# Generating Session ID:
if 'store' not in st.session_state:
st.session_state.store = False
try:
df_session = pd.read_excel('df_session.xlsx')
df_row = pd.DataFrame({'ID': uuid.uuid4()}, index=[0])
df_session = pd.concat([df_session, df_row], ignore_index=True)
df_session.to_excel('df_session.xlsx', index=False)
df_sku = pd.DataFrame({'SessionID': pd.Series(dtype='object'), 'Keyword': pd.Series(dtype='object'),
'Skus': pd.Series(dtype='object'),
'Count': pd.Series(dtype='int')}) # Initializing the SKU-Count DataFrame
df_sku.to_excel('df_sku.xlsx', index=False)
except FileNotFoundError:
df_session = pd.DataFrame({'ID': uuid.uuid4()}, index=[0]) # Initializing the SKU-Count DataFrame
df_session.to_excel('df_session.xlsx', index=False)
df_session = pd.read_excel('df_session.xlsx')
session_id = list(df_session['ID'])[-1]
# st.sidebar.write(session_id) # Uncomment to display the Session ID
# Inputs
# selected_keyword = st.sidebar.text_input("Enter a single word as Keyword: ", 'aquaman')
# publisher_id = st.sidebar.text_input("Enter Publisher ID: ", '725895')
list_keywords = []
list_publisherid = []
for file in os.listdir('bizrate'):
keyword_publisherid = file.replace(".xml", "")
list_keywords.append(keyword_publisherid.split("_")[0])
list_publisherid.append(keyword_publisherid.split("_")[1])
# list_keywords = ['aquaman', 'superman', 'batman', 'shoes', 'electronics', 'wallet', 'movies', 'books'] # Temporary
list_publisherid = ['726189'] # For the time being Publisher ID is being HardCoded.
selected_keyword = st.sidebar.selectbox("Select a Keyword:", set(sorted(list_keywords)))
publisher_id = st.sidebar.selectbox("Select a Publisher ID:", set(list_publisherid))
# st.write(selected_keyword)
# st.write(publisher_id)
# Query clickReport.db, aggregate clicks and sort most clicked
clickreport_df = query_table('clickReport', 'clickReport')
clicked_df = clickreport_df[clickreport_df['keyword'] == selected_keyword]
clicked_df = clicked_df[['keyword', 'Skus', 'clicks']].groupby(['keyword', 'Skus']).sum().reset_index()
clicked_df = clicked_df.sort_values(by='clicks', ascending=False)
to_display_df = clicked_df.copy()
clicked_df = clicked_df[['Skus', 'clicks']]
print("LINE 202: Most Clicked: \n {}".format(clicked_df.head()))
# Query Recommended Data as per Keyword and Publisher ID
try:
rec_df = query_table('RecSysData', selected_keyword + "_" + publisher_id)
rec_df = pd.merge(clicked_df, rec_df, how='right', on=['Skus'])
rec_df = rec_df.sort_values(by='clicks', ascending=False)
print("LINE 209: \n {}".format(rec_df.head()))
print("LINE 210: \n {}".format(rec_df.columns))
except pd.errors.DatabaseError:
# st.error('This Keyword Publisher ID Combo Doesnt Exist!')
rec_df = pd.DataFrame({}, columns=['title', 'Brand', 'url', 'Image', 'Skus', 'price', 'originalPrice',
'markdownPercent', 'totalPrice', 'condition', 'stock', 'relevancy'])
rec_df = pd.merge(clicked_df, rec_df, how='left', on=['Skus'])
rec_df = rec_df.sort_values(by='clicks', ascending=False)
# Logic to Decide which SKU's to Display
# 1. If a SKU has already been clicked on. It cannot be displayed again.
try:
click_data_df = query_table('session_data', 'session_data')
if click_data_df.empty:
# df_top_rec = rec_df.head(5)
rec_df = rec_df.head(5)
else:
displayed_skus = list(click_data_df[click_data_df['session_id'] == session_id][
'Skus']) # List of SKU's already displayed in the current session
# st.write("Clicked SKUs in this Session: ")
# st.write(displayed_skus)
rec_df = rec_df[~rec_df['Skus'].isin(displayed_skus)]
except pd.errors.DatabaseError as e:
print(e)
# Top 5 Recommendations
# top_df = rec_df.head(5).reset_index()
try:
top_df = rec_df.head().sample(5).reset_index() # random 5 recommendations
except Exception as e:
# st.error(e)
top_df = rec_df.head(5).reset_index()
recs_to_display = 0
if len(top_df) > 5:
recs_to_display = st.sidebar.slider('Recommendations to Display', 1, 5)
elif len(top_df) > 1:
recs_to_display = st.sidebar.slider('Recommendations to Display', 1, len(top_df), len(top_df))
else:
recs_to_display = 1
# recs_to_display image width dictionary
image_width_dictionary = {
5: 200,
4: 240,
3: 280,
2: 320,
1: 400}
if recs_to_display > 0:
idx = 0
cols = st.columns(recs_to_display)
for col in cols:
with col:
try:
title = top_df['title'][idx]
img_link = top_df['url'][idx]
sku = top_df['Skus'][idx]
list_price = top_df['originalPrice'][idx]
selling_price = top_df['price'][idx]
discount = top_df['markdownPercent'][idx]
st.image(top_df['Image'][idx], width=image_width_dictionary[recs_to_display])
# st.write('SKU: {}'.format(sku))
# st.write('SKU: {}'.format(sku))
# st.write('SKU: {}'.format(sku))
content = ''' {}
SKU: {}
S.P: $ {}
Discount: % {}
L.P: $ {}