sanjeev21/ProductRecv3
0
1import streamlit as st2import re3import altair as alt4from folder_management import create_folder, remove_files_folder5 6st.set_page_config('Product Recommendation Application', layout='wide', page_icon='airtory_logo.PNG')7 8 9# Functions/Pages10def intro():11 import streamlit as st12 13 st.markdown("## Welcome to the Product Recommendation Application! ๐")14 st.sidebar.success("Select a page from above.")15 16 st.markdown(17 """18 **๐ Select a page from the navigation bar to the left**19 20### Functionality of Pages21#### Generate Recommendations Page22- This page allows you to generate recommendations for a particular keyword/publisherid combo.23- The recommendations for each keyword/publisherid combo, are stored in a separate SQLite Database Table.24- 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.25#### Product Recommendations Page26- This page displays the Product Recommendations for each keyword/publisherid combo for which the recommendations were generated in the previous page.27- You can currently select the available keywords from the dropdown provided in the side bar.28- For the time being, the Publisher ID is restricted to a single known value. This can be easily updated later.29- 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. 30- For each session, once a product is clicked on, it is no longer displayed.31- You can choose the number of recommendations to be displayed, between 1 & 5.32- The maximum number of recommendations that are available for display for each keyword/publisherid combo is restricted to 50.33- The minumum number depends on the products available from bizrate.34- 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.35#### Analytics Page36- Displays a Line Chart and a Bar Chart, to show the distribution of clicks across Session ID, Keyword, Publisher ID, SKU or Date.37- Displays a table of the most clicked SKU's38 """39 )40 41 42def generate_recommendations():43 import os44 import string45 import random46 import streamlit as st47 import warnings48 warnings.filterwarnings('ignore')49 50 # custom module51 # from clickcounter import clickcounter52 from folder_management import create_folder, remove_files_folder53 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table54 from recommend import query_bizrate, recommend, generate_clickreport55 56 # Functions57 def random_string(N=7):58 res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N))59 return str(res)60 61 def query_and_recommend(keyword, publisherid):62 query_bizrate(keyword, publisherid)63 recommend(keyword, publisherid)64 generate_clickreport()65 66 # Main Program67 68 # st.set_page_config('Generate Recommendations', layout='wide')69 70 st.title('Generate Recommendations')71 st.markdown('''<pre style="text-align:center">72 <strong><span style="color:#6a8759">73 Generate Recommendations for any Keyword - Publisher ID Combo. <br><br> </span></strong></pre>''',74 unsafe_allow_html=True)75 76 col1, col2 = st.columns(2)77 78 selected_keyword = ''79 publisher_id = ''80 81 with col1:82 selected_keyword = st.text_input('Enter a single word as keyword:', 'bed')83 selected_keyword = selected_keyword.lower()84 selected_keyword = selected_keyword.replace('-', '')85 selected_keyword = ''.join(re.split(r"[ \|\\\/,.]", selected_keyword))86 # selected_keyword = ''.join(selected_keyword.split())87 st.write(selected_keyword)88 89 with col2:90 publisher_id = st.text_input("Enter a Publisher ID: ", '726189')91 # st.write(publisher_id)92 93 keyword_pubid_list = []94 for file in os.listdir('bizrate'):95 keyword_pubid_list.append(file.replace(".xml", ""))96 97 if selected_keyword + "_" + publisher_id in keyword_pubid_list:98 st.error('Keyword - Publisher ID Combo Exists!')99 else:100 st.info("Keyword - Publisher ID Combo doesn't exist. Must be queried")101 st.button('Generate Recommendations', key=random_string(), on_click=query_and_recommend,102 args=([selected_keyword, publisher_id]))103 104 105def display_recommendations():106 import pandas as pd107 import numpy as np108 import requests109 from bs4 import BeautifulSoup110 import urllib.parse111 import os112 import string113 import random114 115 import time116 117 import streamlit as st118 import uuid119 120 import warnings121 import sys122 123 warnings.filterwarnings('ignore')124 125 # custom module126 # from clickcounter import clickcounter127 from folder_management import create_folder, remove_files_folder128 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table129 130 # Functions131 def random_string(N=7):132 res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N))133 return str(res)134 135 # def display_products(dfp):136 # product_list = list(dfp['title'])137 # image_list = list(dfp['Image'])138 # price_list = list(dfp['price'])139 # org_price = list(dfp['originalPrice'])140 # disc_list = list(dfp['markdownPercent'])141 # dfp['Skus'] = dfp['Skus'].astype('object')142 # sku_list = list(dfp['Skus'])143 # url_list = list(dfp['url'])144 # clicked_sku, counter_dict = clickcounter(image_list, sku_list, price_list, disc_list, org_price, url_list, product_list)145 # return clicked_sku, counter_dict146 147 # Main Program148 # st.set_page_config('Product Recommender System', layout='wide')149 st.title('Product Recommender System')150 st.markdown('''<pre style="text-align:center">151 <strong><span style="color:#6a8759">152 It will take as inputs: Keyword and Publisher ID. 153 Displays (upto) Top 5 Recommendations & Collects Click Information. <br><br> </span></strong></pre>''',154 unsafe_allow_html=True)155 156 # Generating Session ID:157 if 'store' not in st.session_state:158 st.session_state.store = False159 160 try:161 df_session = pd.read_excel('df_session.xlsx')162 df_row = pd.DataFrame({'ID': uuid.uuid4()}, index=[0])163 df_session = pd.concat([df_session, df_row], ignore_index=True)164 df_session.to_excel('df_session.xlsx', index=False)165 df_sku = pd.DataFrame({'SessionID': pd.Series(dtype='object'), 'Keyword': pd.Series(dtype='object'),166 'Skus': pd.Series(dtype='object'),167 'Count': pd.Series(dtype='int')}) # Initializing the SKU-Count DataFrame168 df_sku.to_excel('df_sku.xlsx', index=False)169 170 except FileNotFoundError:171 df_session = pd.DataFrame({'ID': uuid.uuid4()}, index=[0]) # Initializing the SKU-Count DataFrame172 df_session.to_excel('df_session.xlsx', index=False)173 174 df_session = pd.read_excel('df_session.xlsx')175 session_id = list(df_session['ID'])[-1]176 # st.sidebar.write(session_id) # Uncomment to display the Session ID177 178 # Inputs179 180 # selected_keyword = st.sidebar.text_input("Enter a single word as Keyword: ", 'aquaman')181 # publisher_id = st.sidebar.text_input("Enter Publisher ID: ", '725895')182 list_keywords = []183 list_publisherid = []184 for file in os.listdir('bizrate'):185 keyword_publisherid = file.replace(".xml", "")186 list_keywords.append(keyword_publisherid.split("_")[0])187 list_publisherid.append(keyword_publisherid.split("_")[1])188 # list_keywords = ['aquaman', 'superman', 'batman', 'shoes', 'electronics', 'wallet', 'movies', 'books'] # Temporary189 list_publisherid = ['726189'] # For the time being Publisher ID is being HardCoded.190 selected_keyword = st.sidebar.selectbox("Select a Keyword:", set(sorted(list_keywords)))191 publisher_id = st.sidebar.selectbox("Select a Publisher ID:", set(list_publisherid))192 193 # st.write(selected_keyword)194 # st.write(publisher_id)195 196 # Query clickReport.db, aggregate clicks and sort most clicked197 clickreport_df = query_table('clickReport', 'clickReport')198 clicked_df = clickreport_df[clickreport_df['keyword'] == selected_keyword]199 clicked_df = clicked_df[['keyword', 'Skus', 'clicks']].groupby(['keyword', 'Skus']).sum().reset_index()200 clicked_df = clicked_df.sort_values(by='clicks', ascending=False)201 to_display_df = clicked_df.copy()202 clicked_df = clicked_df[['Skus', 'clicks']]203 print("LINE 202: Most Clicked: \n {}".format(clicked_df.head()))204 # Query Recommended Data as per Keyword and Publisher ID205 206 try:207 rec_df = query_table('RecSysData', selected_keyword + "_" + publisher_id)208 rec_df = pd.merge(clicked_df, rec_df, how='right', on=['Skus'])209 rec_df = rec_df.sort_values(by='clicks', ascending=False)210 print("LINE 209: \n {}".format(rec_df.head()))211 print("LINE 210: \n {}".format(rec_df.columns))212 except pd.errors.DatabaseError:213 # st.error('This Keyword Publisher ID Combo Doesnt Exist!')214 rec_df = pd.DataFrame({}, columns=['title', 'Brand', 'url', 'Image', 'Skus', 'price', 'originalPrice',215 'markdownPercent', 'totalPrice', 'condition', 'stock', 'relevancy'])216 rec_df = pd.merge(clicked_df, rec_df, how='left', on=['Skus'])217 rec_df = rec_df.sort_values(by='clicks', ascending=False)218 219 # Logic to Decide which SKU's to Display220 221 # 1. If a SKU has already been clicked on. It cannot be displayed again.222 223 try:224 click_data_df = query_table('session_data', 'session_data')225 226 if click_data_df.empty:227 # df_top_rec = rec_df.head(5)228 rec_df = rec_df.head(5)229 else:230 displayed_skus = list(click_data_df[click_data_df['session_id'] == session_id][231 'Skus']) # List of SKU's already displayed in the current session232 # st.write("Clicked SKUs in this Session: ")233 # st.write(displayed_skus)234 rec_df = rec_df[~rec_df['Skus'].isin(displayed_skus)]235 except pd.errors.DatabaseError as e:236 print(e)237 238 # Top 5 Recommendations239 # top_df = rec_df.head(5).reset_index()240 try:241 top_df = rec_df.head().sample(5).reset_index() # random 5 recommendations242 except Exception as e:243 # st.error(e)244 top_df = rec_df.head(5).reset_index()245 246 recs_to_display = 0247 if len(top_df) > 5:248 recs_to_display = st.sidebar.slider('Recommendations to Display', 1, 5)249 elif len(top_df) > 1:250 recs_to_display = st.sidebar.slider('Recommendations to Display', 1, len(top_df), len(top_df))251 else:252 recs_to_display = 1253 254 # recs_to_display image width dictionary255 image_width_dictionary = {256 5: 200,257 4: 240,258 3: 280,259 2: 320,260 1: 400}261 262 if recs_to_display > 0:263 idx = 0264 cols = st.columns(recs_to_display)265 for col in cols:266 with col:267 try:268 title = top_df['title'][idx]269 img_link = top_df['url'][idx]270 sku = top_df['Skus'][idx]271 list_price = top_df['originalPrice'][idx]272 selling_price = top_df['price'][idx]273 discount = top_df['markdownPercent'][idx]274 st.image(top_df['Image'][idx], width=image_width_dictionary[recs_to_display])275 # st.write('SKU: {}'.format(sku))276 # st.write('SKU: {}'.format(sku))277 # st.write('SKU: {}'.format(sku))278 content = '''<p><strong> <a href={}>{}</a> </strong> <br>279 <strong>SKU:</strong> {} <br>280 <strong>S.P:</strong> $ {}<br>281 <strong>Discount:</strong> % {} <br>282 <strong>L.P:</strong> $ {} <br>283 </p>'''.format(img_link, title, sku, selling_price, discount, list_price)284 st.markdown(content, unsafe_allow_html=True)285 st.button('Select', key=random_string(), on_click=insert_clickdata_table,286 args=([session_id, selected_keyword, publisher_id, sku, 1]))287 except KeyError:288 st.info('No more recommendations to display for this Keyword-PublisherID Combo!')289 st.info('You can search for another keyword or reload the page!')290 idx += 1291 else:292 st.text(293 'No more recommendations to display for this Keyword-PublisherID Combo! You can search for another keyword or reload the page!')294 295 # Display Click Table showing total clicks and clicks in current session296 st.write("\n")297 st.write("\n")298 st.write("Most Clicked SKUs for keyword : {}".format(selected_keyword))299 st.dataframe(to_display_df.reset_index(drop=True).head(10))300 st.write("Clicked SKUs in this Session: ")301 st.dataframe(click_data_df[click_data_df['session_id'] == session_id].reset_index(drop=True))302 303 304def display_analytics():305 import pandas as pd306 import numpy as np307 import requests308 from bs4 import BeautifulSoup309 import urllib.parse310 import os311 import string312 import random313 314 import time315 316 import streamlit as st317 import uuid318 319 import warnings320 321 warnings.filterwarnings('ignore')322 323 # custom module324 # from clickcounter import clickcounter325 from folder_management import create_folder, remove_files_folder326 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table327 328 # Main Program329 # st.set_page_config('Analytics', layout='wide')330 st.title('Analytics')331 332 df = query_table('session_data', 'session_data')333 # print(pd.Timestamp(df['clicked_at'][0]).date())334 df['date'] = df['clicked_at'].map(lambda x: pd.Timestamp(x).date())335 x_col_list = list(df.columns)336 x_col_list.remove('count')337 x_col_list.remove('clicked_at')338 print(x_col_list)339 column = st.selectbox('Select a Dimension:', x_col_list)340 341 # Grouping the DataFrame342 if column:343 grouped_df = df.groupby([column]).sum().reset_index()344 if column != 'date':345 grouped_df = grouped_df.sort_values(by='count', ascending=False)346 grouped_df.rename(columns={'count': 'clicks'}, inplace=True)347 # st.dataframe(grouped_df.head())348 col1, col2 = st.columns(2)349 with col1:350 # st.line_chart(grouped_df, x=column, y='clicks')351 alt_line_chart = alt.Chart(grouped_df).mark_line(color='#3ac81e').encode(x=column, y='clicks')352 st.altair_chart(alt_line_chart, use_container_width=True)353 354 with col2:355 # st.bar_chart(grouped_df, x=column, y='clicks')356 alt_bar_chart = alt.Chart(grouped_df).mark_bar(color='#3ac81e').encode(x=column, y='clicks')357 st.altair_chart(alt_bar_chart, use_container_width=True)358 359 st.title("Top Products")360 agg_df = df[['keyword', 'publisherid', 'Skus', 'count']]361 agg_df.rename(columns={'keyword': 'Keywords', 'publisherid': 'PublisherID', 'count': 'Clicks'}, inplace=True)362 agg_df = agg_df.groupby(['Skus', 'Keywords', 'PublisherID']).sum().reset_index()363 agg_df = agg_df.sort_values(by='Clicks', ascending=False).reset_index(drop=True)364 st.dataframe(agg_df.head(20), width=1000)365 366 367create_folder('bizrate')368create_folder('sqlite_databases')369 370page_names_to_funcs = {371 "โ": intro,372 "Generate Recommendations": generate_recommendations,373 "Product Recommendations": display_recommendations,374 "Analytics": display_analytics375}376 377page_name = st.sidebar.selectbox("Choose a Page", page_names_to_funcs.keys())378page_names_to_funcs[page_name]()379 