keefereuther commited on
Commit
5d75348
·
verified ·
1 Parent(s): c826d6e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -58
app.py CHANGED
@@ -13,34 +13,43 @@ import io
13
  import config
14
  from openai import OpenAI
15
 
 
 
 
16
  ############################################################################################################
17
  # Password protection
18
 
19
- def check_password():
20
- """Returns `True` if the user had the correct password."""
21
-
22
- def password_entered():
23
- """Checks whether a password entered by the user is correct."""
24
- if hmac.compare_digest(st.session_state["password"], st.secrets["password"]):
25
- st.session_state["password_correct"] = True
 
 
 
 
26
  del st.session_state["password"] # Don't store the password.
27
  else:
28
- st.session_state["password_correct"] = False
29
 
30
- # Return True if the password is validated.
31
- if st.session_state.get("password_correct", False):
32
  return True
33
 
34
- # Show input for password.
35
- st.text_input(
36
- "Password", type="password", on_change=password_entered, key="password"
37
- )
38
- if "password_correct" in st.session_state:
39
- st.error("😕 Password incorrect")
40
  return False
41
 
42
- if not check_password():
43
- st.stop() # Do not continue if check_password is not True.
 
 
44
 
45
  ############################################################################################################
46
  # Streamlit app layout
@@ -55,13 +64,6 @@ df = pd.read_csv(config.default_terms_csv)
55
  st.title(config.app_title)
56
  st.markdown(config.intro_para)
57
  st.caption(config.app_author)
58
- with st.expander("INSTRUCTIONS FOR STUDENTS:"):
59
- st.markdown(config.instructions)
60
- with st.expander("**INSTRUCTORS**: For a look at the current terms file driving the interaction, click here:"):
61
- st.markdown("This is the terms.csv file that drives the interaction. You can edit this file to change the terms and context that the chatbot uses. You may add any term or phrase. You may leave the context blank if you prefer or you can add anything relevant that the GPT does not normally know about the term. This may include relevant learning objectives, course examples, notable scientists, assessment dates, syllabus information, etc.")
62
- st.table(df)
63
- with st.expander("**INSTRUCTORS**: For a look at the prompt driving the chatbot, click here:"):
64
- st.markdown(config.display_prompt)
65
  st.sidebar.title(config.sidebar_title)
66
  with st.sidebar:
67
  with st.expander("Click here for instructions."):
@@ -71,7 +73,6 @@ with st.sidebar:
71
  # File Uploader in sidebar
72
 
73
  # Load terms from a CSV file
74
- # https://discuss.streamlit.io/t/how-to-upload-a-csv-file/7052/2
75
  def load_terms(file_input):
76
  try:
77
  if isinstance(file_input, str):
@@ -133,52 +134,59 @@ st.sidebar.markdown('<hr>', unsafe_allow_html=True)
133
  ############################################################################################################
134
  # Term Selection and session state
135
 
136
- # Define a basic initial context at the beginning of your script
137
- initial_context = {
138
- "role": "system",
139
- "content": config.initial_prompt
140
- }
141
-
142
  # Initialize the session state variables for selected term, context, and display messages
143
  if 'selected_term' not in st.session_state:
144
  st.session_state.selected_term = None
145
  if 'selected_context' not in st.session_state:
146
  st.session_state.selected_context = None
147
  if 'display_messages' not in st.session_state:
148
- st.session_state.display_messages = [initial_context]
149
 
150
  # Initialize session states for the selected term, counter, and display flag
151
- if 'selected_term' not in st.session_state:
152
- st.session_state.selected_term = None
153
  if 'display_term' not in st.session_state:
154
- st.session_state.display_term = False
 
 
 
 
 
 
155
 
156
  # Dropdown menu for selecting a term
157
- selected_term = st.selectbox('Select a term/question and brainstorm everything about it. This could include a definition, examples, misconceptions, associations, etc.', term_list)
 
158
  if selected_term:
 
 
 
 
 
 
 
159
  selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
160
  st.session_state.selected_term = selected_term
161
  st.session_state.selected_context = selected_context
162
  st.session_state.display_term = True
163
-
164
- # Ensure the session state variables are set correctly
165
- # if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
166
  # Update the prompt for the API
167
  updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
168
- initial_context = {
169
- "role": "system",
170
- "content": updated_prompt
171
- }
172
- # Reset the conversation with the new initial context
173
- st.session_state.display_messages[0] = [initial_context]
174
 
175
  # Display the selected term and its context
176
  if st.session_state.display_term and st.session_state.selected_term:
177
  st.header(st.session_state.selected_term)
178
- # Pass the displayed term to the assistant as part of the message
179
- user_message = f"Define '{st.session_state.selected_term}':"
180
- elif not st.session_state.selected_term:
181
- st.write("")
 
 
 
 
 
182
 
183
  ############################################################################################################
184
  # ChatGPT
@@ -190,20 +198,19 @@ if "openai_model" not in st.session_state:
190
  st.session_state["openai_model"] = config.ai_model
191
 
192
  if "display_messages" not in st.session_state:
193
- st.session_state.display_messages[0] = [initial_context]
194
 
195
  # Update initial_context with the latest selected term and context
196
  if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
197
  updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
198
- initial_context = {
199
- "role": "system",
200
- "content": updated_prompt
201
- }
202
  # Replace the initial context in display_messages with the updated prompt
203
- st.session_state.display_messages[0] = initial_context
 
 
 
204
 
205
  # Get user input
206
- prompt = st.chat_input("Type your message here...")
207
 
208
  # Input for new messages
209
  if prompt:
@@ -214,7 +221,7 @@ if prompt:
214
 
215
  # Function to reset all chat-related session state
216
  def reset_chat_history():
217
- st.session_state["display_messages"] = [initial_context]
218
  # Reset other chat-related session states if they exist
219
  if 'selected_term' in st.session_state:
220
  st.session_state.selected_term = None
@@ -256,12 +263,16 @@ with st.container(height=400, border=True):
256
  st.session_state["display_messages"].append(
257
  {"role": "assistant", "content": response}
258
  )
 
 
259
  except Exception as e:
260
  st.error(f"An error occurred: {str(e)}")
 
261
 
262
  # Add Clear Chat History button between container and warning message
263
  if st.button("Clear Chat History"):
264
  reset_chat_history()
 
265
 
266
  st.markdown(config.warning_message, unsafe_allow_html=True)
267
 
 
13
  import config
14
  from openai import OpenAI
15
 
16
+ # Set up logging
17
+ logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
18
+
19
  ############################################################################################################
20
  # Password protection
21
 
22
+ def check_credentials():
23
+ """Returns `True` if the user had the correct username and password."""
24
+
25
+ def credentials_entered():
26
+ """Checks whether the entered username and password are correct."""
27
+ if (
28
+ hmac.compare_digest(st.session_state["username"], st.secrets["username"]) and
29
+ hmac.compare_digest(st.session_state["password"], st.secrets["password"])
30
+ ):
31
+ st.session_state["credentials_correct"] = True
32
+ del st.session_state["username"] # Don't store the username.
33
  del st.session_state["password"] # Don't store the password.
34
  else:
35
+ st.session_state["credentials_correct"] = False
36
 
37
+ # Return True if the credentials are validated.
38
+ if st.session_state.get("credentials_correct", False):
39
  return True
40
 
41
+ # Show input for username and password.
42
+ st.text_input("Username", on_change=credentials_entered, key="username")
43
+ st.text_input("Password", type="password", on_change=credentials_entered, key="password")
44
+
45
+ if "credentials_correct" in st.session_state:
46
+ logging.warning("Invalid login attempt") # Log invalid login attempts
47
  return False
48
 
49
+ if not check_credentials():
50
+ st.stop() # Do not continue if check_credentials is not True.
51
+ else:
52
+ logging.info("Successful login") # Log successful logins
53
 
54
  ############################################################################################################
55
  # Streamlit app layout
 
64
  st.title(config.app_title)
65
  st.markdown(config.intro_para)
66
  st.caption(config.app_author)
 
 
 
 
 
 
 
67
  st.sidebar.title(config.sidebar_title)
68
  with st.sidebar:
69
  with st.expander("Click here for instructions."):
 
73
  # File Uploader in sidebar
74
 
75
  # Load terms from a CSV file
 
76
  def load_terms(file_input):
77
  try:
78
  if isinstance(file_input, str):
 
134
  ############################################################################################################
135
  # Term Selection and session state
136
 
 
 
 
 
 
 
137
  # Initialize the session state variables for selected term, context, and display messages
138
  if 'selected_term' not in st.session_state:
139
  st.session_state.selected_term = None
140
  if 'selected_context' not in st.session_state:
141
  st.session_state.selected_context = None
142
  if 'display_messages' not in st.session_state:
143
+ st.session_state.display_messages = []
144
 
145
  # Initialize session states for the selected term, counter, and display flag
 
 
146
  if 'display_term' not in st.session_state:
147
+ st.session_state.display_term = False
148
+ if 'initial_message_displayed' not in st.session_state:
149
+ st.session_state.initial_message_displayed = False
150
+
151
+ # Initialize state to track the previously selected term
152
+ if 'old_term' not in st.session_state:
153
+ st.session_state.old_term = None
154
 
155
  # Dropdown menu for selecting a term
156
+ selected_term = st.selectbox('**SELECT FROM THE DROPDOWN MENU**', term_list)
157
+
158
  if selected_term:
159
+ # If a new term is selected (including first time selection), reset or show the message
160
+ if selected_term != st.session_state.old_term:
161
+ user_message = f"What is one thing you know about '{selected_term}'? What do you want to know about it? This could include a definition, examples, misconceptions, associations with other course terms, opinions, etc."
162
+ st.session_state["display_messages"].append({"role": "user", "content": user_message})
163
+ # Update old_term in session state
164
+ st.session_state.old_term = selected_term
165
+
166
  selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
167
  st.session_state.selected_term = selected_term
168
  st.session_state.selected_context = selected_context
169
  st.session_state.display_term = True
170
+
 
 
171
  # Update the prompt for the API
172
  updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
173
+
174
+ else:
175
+ # If nothing is selected or the selection is cleared, reset the old_term
176
+ st.session_state.old_term = None
 
 
177
 
178
  # Display the selected term and its context
179
  if st.session_state.display_term and st.session_state.selected_term:
180
  st.header(st.session_state.selected_term)
181
+
182
+ with st.expander("INSTRUCTIONS FOR STUDENTS:"):
183
+ st.markdown(config.instructions)
184
+ with st.expander("**INSTRUCTORS**: For a look at the current terms file driving the interaction, click here:"):
185
+ st.markdown("This is the terms.csv file that drives the interaction. You can edit this file to change the terms and context that the chatbot uses. You may add any term or phrase. You may leave the context blank if you prefer or you can add anything relevant that the GPT does not normally know about the term. This may include relevant learning objectives, course examples, notable scientists, assessment dates, syllabus information, etc.")
186
+ st.table(df)
187
+ with st.expander("**INSTRUCTORS**: For a look at the prompt driving the chatbot, click here:"):
188
+ prompt_text = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
189
+ st.markdown(prompt_text)
190
 
191
  ############################################################################################################
192
  # ChatGPT
 
198
  st.session_state["openai_model"] = config.ai_model
199
 
200
  if "display_messages" not in st.session_state:
201
+ st.session_state.display_messages = []
202
 
203
  # Update initial_context with the latest selected term and context
204
  if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
205
  updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
 
 
 
 
206
  # Replace the initial context in display_messages with the updated prompt
207
+ if st.session_state.display_messages:
208
+ st.session_state.display_messages[0]["content"] = updated_prompt
209
+ else:
210
+ st.session_state.display_messages = [{"role": "system", "content": updated_prompt}]
211
 
212
  # Get user input
213
+ prompt = st.chat_input("What do you know? What do you want to know?")
214
 
215
  # Input for new messages
216
  if prompt:
 
221
 
222
  # Function to reset all chat-related session state
223
  def reset_chat_history():
224
+ st.session_state["display_messages"] = []
225
  # Reset other chat-related session states if they exist
226
  if 'selected_term' in st.session_state:
227
  st.session_state.selected_term = None
 
263
  st.session_state["display_messages"].append(
264
  {"role": "assistant", "content": response}
265
  )
266
+ logging.info(f"User prompt: {prompt}") # Log user prompts
267
+ logging.info(f"Assistant response: {response}") # Log assistant responses
268
  except Exception as e:
269
  st.error(f"An error occurred: {str(e)}")
270
+ logging.exception(f"Error generating response: {e}") # Log errors
271
 
272
  # Add Clear Chat History button between container and warning message
273
  if st.button("Clear Chat History"):
274
  reset_chat_history()
275
+ logging.info("Chat history cleared") # Log when chat history is cleared
276
 
277
  st.markdown(config.warning_message, unsafe_allow_html=True)
278