Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.streamlit/secrets.toml
# Ignore Python cache files
*.pyc
__pycache__/
Binary file added __pycache__/chatbot.cpython-310.pyc
Binary file not shown.
Binary file added __pycache__/sidebar.cpython-310.pyc
Binary file not shown.
Empty file added admin_panel.py
Empty file.
Empty file added chatbot.py
Empty file.
Empty file added chatlog.py
Empty file.
Empty file added db.py
Empty file.
Empty file added export.py
Empty file.
Empty file added instructions.py
Empty file.
239 changes: 217 additions & 22 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import logging
# main.py
import datetime
import io
import csv
import psycopg2
from openai import OpenAI
import logging
import streamlit as st
import psycopg2
from sidebar import setup_sidebar
# from chatbot import process_chat_input
# from admin_panel import handle_admin_actions

st.title("CherGPT Basic")

# Initialize session state for admin
if "is_admin" not in st.session_state:
st.session_state["is_admin"] = False


# Set up the sidebar
setup_sidebar()

# Admin panel actions
# handle_admin_actions()

# Chatbot interaction
# process_chat_input()


# Initialize variables for custom and existing instructions
custom_instructions = ""
existing_instructions = ""

client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])

with st.sidebar:
st.title("Settings")
with st.expander("Admin config"):
admin_password = st.text_input("Enter Admin Password", type="password")

if admin_password == st.secrets["ADMIN_PASSWORD"]:
st.session_state["is_admin"] = True
st.success("Authenticated as Admin")
elif admin_password: # Only display message if something was entered
st.error("Incorrect password")
st.session_state["is_admin"] = False


def connect_to_db():
try:
Expand All @@ -40,26 +46,194 @@ 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
);
""")

# 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:
logging.error(f"Error initializing database: {e}")
finally:
if conn is not None:
conn.close()


# Call the initialization function at the appropriate place in your application
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()
print("Checked for 'instructions' table; created if not exists.")
logging.info("Chat log inserted successfully.")
except Exception as e:
print(f"Error creating 'instructions' table: {e}")
logging.error(f"Error inserting chat log: {e}")
finally:
conn.close()
if conn is not None:
conn.close()

# fetch chatlog

create_instructions_table_if_not_exists()

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}")
return []
finally:
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


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

# 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
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:
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


def update_instructions(new_instructions):
Expand Down Expand Up @@ -109,6 +283,7 @@ def get_latest_instructions():

custominstructions_area_height = 300


# Admin panel for custom instructions
if st.session_state.get("is_admin"):
with st.sidebar:
Expand All @@ -122,6 +297,25 @@ def get_latest_instructions():
update_instructions(custom_instructions)
st.success("Instructions updated successfully")
st.experimental_rerun()
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"):
delete_all_chatlogs()

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"
Expand Down Expand Up @@ -161,6 +355,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
Expand Down
Empty file added openai_integration.py
Empty file.
17 changes: 17 additions & 0 deletions sidebar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import streamlit as st


def setup_sidebar():
with st.sidebar:
st.title("Settings")
with st.expander("Admin config"):
admin_password = st.text_input(
"Enter Admin Password", type="password")

if admin_password == st.secrets["ADMIN_PASSWORD"]:
st.session_state["is_admin"] = True
st.success("Authenticated as Admin")
elif admin_password: # Only display message if something was entered
st.error("Incorrect password")
st.session_state["is_admin"] = False
pass