From 1d935a1a09fe0dd9613b0bebfdba1f036264da52 Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 22:23:58 +0800 Subject: [PATCH 1/7] fix: update backend logic to handle schema for chatlogs --- main.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 6e4f41d..f4d2861 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ from openai import OpenAI import streamlit as st import psycopg2 +import csv st.title("CherGPT Basic") @@ -40,28 +41,44 @@ def connect_to_db(): return None -def create_instructions_table_if_not_exists(): +def initialize_db(): conn = connect_to_db() + if conn is None: + return try: - with conn.cursor() as cur: + with conn, conn.cursor() as cur: + # Create custom_instructions table cur.execute(""" - CREATE TABLE IF NOT EXISTS instructions ( + CREATE TABLE IF NOT EXISTS custom_instructions ( id SERIAL PRIMARY KEY, - content TEXT, + instructions TEXT, timestamp TIMESTAMP DEFAULT current_timestamp ); """) - conn.commit() - print("Checked for 'instructions' table; created if not exists.") + + # Create chat_logs table + cur.execute(""" + CREATE TABLE IF NOT EXISTS chat_logs ( + id SERIAL PRIMARY KEY, + timestamp TIMESTAMP DEFAULT current_timestamp, + prompt TEXT, + response TEXT + ); + """) except Exception as e: - print(f"Error creating 'instructions' table: {e}") + logging.error(f"Error initializing database: {e}") finally: - conn.close() + if conn is not None: + conn.close() + +# Call the initialization function at the appropriate place in your application +initialize_db() -create_instructions_table_if_not_exists() +# create chatlog +# Create update instructions def update_instructions(new_instructions): conn = connect_to_db() if conn is None: From d4ea33ef573700ec0e3dd6ff36a1adc93301b0b7 Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 22:25:01 +0800 Subject: [PATCH 2/7] feat: add fetch and export chatlog function --- main.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index f4d2861..f256c7e 100644 --- a/main.py +++ b/main.py @@ -76,9 +76,43 @@ def initialize_db(): initialize_db() -# create chatlog +# fetch chatlog +def fetch_chat_logs(): + conn = connect_to_db() + if conn is None: + return [] + try: + with conn, conn.cursor() as cur: + cur.execute("SELECT * FROM chat_logs") + chat_logs = cur.fetchall() + return chat_logs + except Exception as e: + logging.error(f"Error fetching chat logs: {e}") + return [] + finally: + if conn is not None: + conn.close() + +# export chatlog + + +def export_chat_logs_to_csv(filename='chat_logs.csv'): + chat_logs = fetch_chat_logs() + if not chat_logs: + print("No chat logs to export.") + return + + with open(filename, 'w', newline='') as file: + writer = csv.writer(file) + # Writing headers + writer.writerow(['ID', 'Timestamp', 'Prompt', 'Response']) + writer.writerows(chat_logs) + + print(f"Chat logs exported to {filename}") # Create update instructions + + def update_instructions(new_instructions): conn = connect_to_db() if conn is None: From 04d347bc2d55a3db64fcc57aa95ea173b03701d8 Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 22:43:58 +0800 Subject: [PATCH 3/7] fix: added insert chat log so chat responses are logged verified in local --- main.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/main.py b/main.py index f256c7e..357f0e3 100644 --- a/main.py +++ b/main.py @@ -76,15 +76,40 @@ def initialize_db(): initialize_db() +# insert chatlog into DB +def insert_chat_log(prompt, response): + conn = connect_to_db() + if conn is None: + logging.error("Failed to connect to the database.") + return + + try: + with conn, conn.cursor() as cur: + cur.execute(""" + INSERT INTO chat_logs (prompt, response) + VALUES (%s, %s) + """, (prompt, response)) + conn.commit() + logging.info("Chat log inserted successfully.") + except Exception as e: + logging.error(f"Error inserting chat log: {e}") + finally: + if conn is not None: + conn.close() + # fetch chatlog + + def fetch_chat_logs(): conn = connect_to_db() if conn is None: + logging.error("Failed to connect to the database for fetching logs.") return [] try: with conn, conn.cursor() as cur: cur.execute("SELECT * FROM chat_logs") chat_logs = cur.fetchall() + logging.info(f"Fetched {len(chat_logs)} chat log records.") return chat_logs except Exception as e: logging.error(f"Error fetching chat logs: {e}") @@ -110,6 +135,21 @@ def export_chat_logs_to_csv(filename='chat_logs.csv'): print(f"Chat logs exported to {filename}") + +# delete chatlog +def delete_all_chatlogs(): + conn = connect_to_db() + if conn is None: + return + try: + with conn, conn.cursor() as cur: + cur.execute("DELETE FROM chat_logs") + except Exception as e: + logging.error(f"Error deleting chat logs: {e}") + finally: + if conn is not None: + conn.close() + # Create update instructions @@ -160,6 +200,7 @@ def get_latest_instructions(): custominstructions_area_height = 300 + # Admin panel for custom instructions if st.session_state.get("is_admin"): with st.sidebar: @@ -173,6 +214,14 @@ def get_latest_instructions(): update_instructions(custom_instructions) st.success("Instructions updated successfully") st.experimental_rerun() + if st.button("Export Chat Logs"): + export_chat_logs_to_csv() + st.success("Chat logs exported successfully.") + if st.button("Delete All Chat Logs"): + if st.sidebar.checkbox("I understand this action is irreversible.", key="delete_confirm"): + delete_all_chatlogs() + st.sidebar.success("All chat logs deleted successfully.") + if "openai_model" not in st.session_state: st.session_state["openai_model"] = "gpt-3.5-turbo" @@ -212,6 +261,7 @@ def get_latest_instructions(): ): full_response += (response.choices[0].delta.content or "") message_placeholder.markdown(full_response + "▌") + insert_chat_log(prompt, full_response) message_placeholder.markdown(full_response) # Append the assistant's response to the messages for display From b60ac47d4a916aa72acc287b1a823026afcae3c9 Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 23:06:42 +0800 Subject: [PATCH 4/7] fix: attempt to do 1hr insights but does not work for now --- main.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index 357f0e3..2773f72 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,8 @@ import streamlit as st import psycopg2 import csv +import io +import datetime st.title("CherGPT Basic") @@ -118,6 +120,61 @@ def fetch_chat_logs(): if conn is not None: conn.close() +# fetch past hour chatlog + + +def fetch_recent_chat_logs(hours=1): + conn = connect_to_db() + if conn is None: + logging.error("Failed to connect to the database for fetching logs.") + return [] + + one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=hours) + logging.info(f"Fetching logs from: {one_hour_ago}") + + try: + with conn, conn.cursor() as cur: + cur.execute(""" + SELECT * FROM chat_logs + WHERE timestamp >= %s + """, (one_hour_ago,)) + chat_logs = cur.fetchall() + logging.info(f"Fetched {len(chat_logs)} chat log records.") + return chat_logs + except Exception as e: + logging.error(f"Error fetching recent chat logs: {e}") + return [] + finally: + if conn is not None: + conn.close() + +# test datetime conversion + + +def test_timestamp_conversion(): + conn = connect_to_db() + if conn is None: + logging.error("Failed to connect to the database.") + return + + try: + with conn, conn.cursor() as cur: + cur.execute("SELECT timestamp FROM chat_logs LIMIT 1") + record = cur.fetchone() + if record: + print("Timestamp type:", type(record[0])) + else: + print("No records found.") + except Exception as e: + logging.error(f"Error fetching a timestamp: {e}") + finally: + if conn is not None: + conn.close() + + +test_timestamp_conversion() + + # export chatlog @@ -127,13 +184,13 @@ def export_chat_logs_to_csv(filename='chat_logs.csv'): print("No chat logs to export.") return - with open(filename, 'w', newline='') as file: - writer = csv.writer(file) - # Writing headers - writer.writerow(['ID', 'Timestamp', 'Prompt', 'Response']) - writer.writerows(chat_logs) - - print(f"Chat logs exported to {filename}") + # Create a CSV in memory + output = io.StringIO() + writer = csv.writer(output) + # Writing headers + writer.writerow(['ID', 'Timestamp', 'Prompt', 'Response']) + writer.writerows(chat_logs) + return output.getvalue() # delete chatlog @@ -150,6 +207,26 @@ def delete_all_chatlogs(): if conn is not None: conn.close() +# insights + + +def generate_insights_with_openai(chat_logs): + # Constructing the conversation context for GPT-3.5-turbo + conversation_context = [ + {"role": "system", "content": "Analyze the following chat logs and provide the top 5 insights on how students' questioning techniques could be improved:"}] + for log in chat_logs: + conversation_context.append({"role": "user", "content": log[2]}) + conversation_context.append({"role": "assistant", "content": log[3]}) + + # Sending the context to OpenAI's GPT-3.5-turbo model + response = openai.ChatCompletion.create( + model="gpt-3.5-turbo", + messages=conversation_context + ) + + return response.choices[0].message['content'] + + # Create update instructions @@ -214,14 +291,27 @@ def get_latest_instructions(): update_instructions(custom_instructions) st.success("Instructions updated successfully") st.experimental_rerun() - if st.button("Export Chat Logs"): - export_chat_logs_to_csv() - st.success("Chat logs exported successfully.") + csv_data = export_chat_logs_to_csv() + if csv_data: + st.download_button( + label="Download Chat Logs", + data=csv_data, + file_name='chat_logs.csv', + mime='text/csv', + ) if st.button("Delete All Chat Logs"): if st.sidebar.checkbox("I understand this action is irreversible.", key="delete_confirm"): delete_all_chatlogs() st.sidebar.success("All chat logs deleted successfully.") + if st.button("Generate Insights from Recent Chats"): + recent_chats = fetch_recent_chat_logs(1) # Last hour + print(recent_chats) + if recent_chats: + insights = generate_insights_with_openai(recent_chats) + st.write(insights) + else: + st.write("No recent chats to analyze.") if "openai_model" not in st.session_state: st.session_state["openai_model"] = "gpt-3.5-turbo" From c7005b12ddc34603baa4b8c309160d156d8a8525 Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 23:11:53 +0800 Subject: [PATCH 5/7] fix: setup for refactoring --- __pycache__/chatbot.cpython-310.pyc | Bin 0 -> 139 bytes __pycache__/sidebar.cpython-310.pyc | Bin 0 -> 723 bytes admin_panel.py | 0 chatbot.py | 0 chatlog.py | 0 db.py | 0 export.py | 0 instructions.py | 0 main.py | 37 +++++++++++++++------------- openai_integration.py | 0 sidebar.py | 17 +++++++++++++ 11 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 __pycache__/chatbot.cpython-310.pyc create mode 100644 __pycache__/sidebar.cpython-310.pyc create mode 100644 admin_panel.py create mode 100644 chatbot.py create mode 100644 chatlog.py create mode 100644 db.py create mode 100644 export.py create mode 100644 instructions.py create mode 100644 openai_integration.py create mode 100644 sidebar.py diff --git a/__pycache__/chatbot.cpython-310.pyc b/__pycache__/chatbot.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5557460a48a5aa64cd57fd56d4632e78e27b925c GIT binary patch literal 139 zcmd1j<>g`kf`a|qQ$h4&5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HXerR!OQL%n@ zVn#-Oc}{AoesX>akjO|aN-rqUO-d}zOa}52OOoAzr){sn>;|BtzeC-0)*L4A`S5O5yv+xNcr&3g}Ki$)`0biRK1gnfsxZ#G#!#IgJ2 zYKs6E@DV%W;DGy%9XY^b7J1*P!n&Eo)!`J>$sdrb&jgyC@XH>j?+3bd#pjU=&K1Ah zw(*GvE_hIR@4RLgHm^YS7CUw19jH-O1%J=ptwG)1&BF^OcPaNFusK{?Y5KIINA}hw z)y6%h_NP?0_L6+P3M~FFC;f|cz12iv*Z47NE%Jeyg&i1+yp0aDJc z!#pdb#7wtV?H)yS<0x%vN&p_G(p0q2BQ!pqm1zzrO`!2iCn7H=R)v{FtxQ9qQliKc zrD+85lPn{~R8Y!7(vHpfCdq2dM<%b+i~ZhdKUXMK`!pR6i|GilofSYZL^&w+_Hn92 z)?Ti%Q=Z#7dQv7!# Date: Mon, 29 Jan 2024 23:23:53 +0800 Subject: [PATCH 6/7] fix: delete works --- main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index be9e335..9bba124 100644 --- a/main.py +++ b/main.py @@ -200,10 +200,13 @@ def export_chat_logs_to_csv(filename='chat_logs.csv'): def delete_all_chatlogs(): conn = connect_to_db() if conn is None: + logging.error("Failed to connect to the database.") return try: with conn, conn.cursor() as cur: cur.execute("DELETE FROM chat_logs") + conn.commit() + logging.info("All chat logs deleted successfully.") except Exception as e: logging.error(f"Error deleting chat logs: {e}") finally: @@ -303,9 +306,7 @@ def get_latest_instructions(): mime='text/csv', ) if st.button("Delete All Chat Logs"): - if st.sidebar.checkbox("I understand this action is irreversible.", key="delete_confirm"): - delete_all_chatlogs() - st.sidebar.success("All chat logs deleted successfully.") + delete_all_chatlogs() if st.button("Generate Insights from Recent Chats"): recent_chats = fetch_recent_chat_logs(1) # Last hour From 2265cea04107e930396234334ce8f88c6c733feb Mon Sep 17 00:00:00 2001 From: Kahhow Lee Date: Mon, 29 Jan 2024 23:25:42 +0800 Subject: [PATCH 7/7] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index fc70fb8..175a007 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .streamlit/secrets.toml +# Ignore Python cache files +*.pyc +__pycache__/ \ No newline at end of file