Spaces:
Running
Running
File size: 18,889 Bytes
7599676 8e04782 7599676 8e04782 2c9c4d1 7599676 2c9c4d1 7599676 b899970 8e04782 7599676 4529c9d 8e04782 4529c9d 8e04782 7599676 4529c9d 8e04782 7599676 8e04782 7599676 4529c9d 8e04782 7599676 4529c9d 6648371 a418616 6648371 4529c9d 5148424 4529c9d 8e04782 0852d5d 7599676 5148424 0852d5d 7599676 a7669c5 7599676 4529c9d 7599676 a632361 8e04782 2c9c4d1 5148424 8e04782 4529c9d 8e04782 4529c9d 8e04782 4529c9d 8e04782 4529c9d 2c9c4d1 f7c16f8 8aad46a 7599676 8e04782 2c9c4d1 8e04782 a7669c5 4529c9d 8e04782 7599676 8e04782 7599676 8e04782 7599676 93669b9 8e04782 4529c9d 8e04782 4529c9d 8e04782 7599676 8e04782 4529c9d 8e04782 4529c9d 8e04782 7599676 4529c9d 8e04782 df6534a 587e02a df6534a 8e04782 a7669c5 8e04782 4529c9d 8e04782 6648371 8e04782 6648371 8e04782 4529c9d b899970 8e04782 4529c9d a7669c5 e7374ff 4529c9d 8e04782 4529c9d 8e04782 4529c9d e7374ff 8e04782 4529c9d a7669c5 e7374ff 4529c9d 8e04782 4529c9d 8e04782 4529c9d e7374ff 8e04782 4529c9d 8e04782 e7374ff 4529c9d 8e04782 4529c9d 15bcf31 2c9c4d1 15bcf31 e7374ff 06e4f99 8e04782 4529c9d 8e04782 6648371 4529c9d 93669b9 6648371 4529c9d 6648371 4529c9d 8e04782 df6534a e7374ff 57a8fee df6534a 8e04782 4529c9d 7599676 4529c9d 93669b9 7599676 4529c9d 7599676 6479a6e 8e04782 7599676 b899970 7599676 8e04782 4529c9d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
import streamlit as st
import streamlit_authenticator as stauth
from deta import Deta
import yaml
from yaml.loader import SafeLoader
import os
from cryptography.fernet import Fernet
import streamlit_survey as ss
from free_speech_app.DataLoadDb import *
from free_speech_app.FreeSpeechPromptsResponses import *
from langchain.chat_models import ChatOpenAI
import json as json_module
#connect to/create Deta user database
deta = Deta(st.secrets["deta_key"])
db = deta.Base("user_data")
# fernet key (generated locally, stored in streamlit secrets)
fernet = Fernet(bytes(st.secrets["fernet_key"], 'utf-8'))
# activeloop_token
os.environ["ACTIVELOOP_TOKEN"] = st.secrets["deeplake_key"]
config_drive = deta.Drive("passwords")
config = config_drive.get("config.yaml").read()
config = yaml.load(config, Loader=SafeLoader)
# Create an authenticator
authenticator = stauth.Authenticate(
config['credentials'],
config['cookie']['name'],
config['cookie']['key'],
config['cookie']['expiry_days'],
config['preauthorized']
)
def get_user_data(user):
data = db.fetch().items
for person in data:
if person['key'] == user:
return person
return None
def encrypt(api_key: str, fernet) -> bytes:
"""Encrypt the API key."""
return fernet.encrypt(api_key.encode())
def decrypt(encrypted_api_key: bytes, fernet) -> str:
"""Decrypt the encrypted API key."""
return fernet.decrypt(encrypted_api_key).decode()
def add_logos():
st.title("Freequalizer")
left_col_log, right_col_log = st.columns(2)
free_speech_logo = './free_speech_app/logos/Future-of-Free-Speech-logo.png'
vu_logo = './free_speech_app/logos/Vanderbilt-University-Logo.png'
with left_col_log:
st.image(free_speech_logo, caption=None, width=200, use_column_width=None,
clamp=False, channels="RGB", output_format="auto")
with right_col_log:
st.image(vu_logo, caption=None, width=200, use_column_width=None,
clamp=False, channels="RGB", output_format="auto")
authentication_status = None
if not authentication_status:
add_logos()
# Render the login module
name, authentication_status, username = authenticator.login()
# If the user is authenticated
if authentication_status:
authenticator.logout()
st.write(f'Welcome *{name}*')
# Sidebar for navigation
page = st.sidebar.radio("Choose a page", ["Account Setup", "API Key Help", "Respond to Post"])
# Fetch user data from the database
user_data = get_user_data(username)
# get principles from organization-wide file
with open('org-principles.txt', 'r') as file:
org_principles = str(file.read())
if page == "Account Setup":
if not user_data or user_data.get('login_count') in [None, 0]:
survey = ss.StreamlitSurvey("Please answer the following questions to help define your principles")
survey.text_input("Who would you identify as a hero or exemplar, fictional or real, whose moral courage reflects what you also believe in? Why?", id="Q1")
survey.text_input("What is an instance of hate that would cross a line for you, making you feel a need to respond?", id="Q2")
survey.text_input("Given your character, how would you seek to address the harms of hate (i.e., to educate, persuade, deescalate, forgive, repair, etc.)?", id="Q3")
json_string = survey.to_json()
json_dict = json_module.loads(json_string)
survey_responses = json_dict["Q1"]["value"] + " " + json_dict["Q2"]["value"] + " " + json_dict["Q3"]["value"]
st.title("Account Setup")
st.markdown("Please use this page to provide your OpenAI API Key, Principles and Writing Style. **Please make sure to press the Save Changes button after providing the information.**")
# Input boxes with existing data
if 'api_key' not in st.session_state:
st.session_state.api_key = ""
api_input = st.text_input("Paste OpenAI API Key", value=decrypt(user_data["api_key"].encode()[
2:-1], fernet) if user_data and "api_key" in user_data else "", type="password")
encrypted_api_key = str(encrypt(api_input, fernet))
st.session_state.api_key = api_input
principles = st.text_area("My Principles (Enter or autopopulates from questions above)", height = 300, value= user_data["principles"] +"\n" + org_principles if user_data and "principles" in user_data and user_data["principles"].strip() != "" else survey_responses + "\n" + org_principles)
writing_style = st.text_area("My Writing Style (Paste Examples)", height = 300, placeholder = "Provide examples of your writing style here", value=user_data["writing_style"] if user_data and "writing_style" in user_data else "")
#sources = st.text_area("Sources (This autopopulates for your reference)", value=st.session_state.sources if 'sources' in st.session_state else '', key = 'sources_key', height = 100)
# Update button
if st.button("Save Changes"):
db.put({"key": username, "principles": principles, "writing_style": writing_style, "api_key": encrypted_api_key, "login_count": 0 if principles.strip() == "" else 1})
if page == "API Key Help":
st.title("OpenAI API Key Setup")
st.header('What is an API key?')
st.write('An API (Application Programming Interface) key is like a password that allows you to access certain functions or data from a website or service. Many sites use API keys to identify you and control access to their APIs.')
st.header('Why do you need an API key?')
st.write('API keys allow sites to track usage and prevent abuse of their services. They help keep things secure. When you request an API key, the site knows the calls are coming from you.')
image = 'apikeyex.png'
st.header('How to get an OpenAI API key:')
st.write('1. Go to https://platform.openai.com/account/api-keys')
st.write('2. Log in or create an OpenAI account if you do not have one')
st.write('3. Click "Create new secret key" and give your key a name')
st.image(image, caption=None, width=None, use_column_width=None,
clamp=False, channels="RGB", output_format="auto")
st.write('4. Copy the generated API key and keep it private like a password')
st.header('Using your API key')
st.write('When making calls to the OpenAI API, include your API key in the request headers or parameters to authenticate.')
st.code('headers = {"Authorization": f"Bearer {YOUR_API_KEY}"}')
st.warning('Treat your API key like a secret! Do not share it publicly.')
elif page == "Respond to Post":
st.title("Respond to Post")
left_col, right_col = st.columns(2)
# Input boxes
with right_col:
regenerate_background = False
background_info = st.text_area("Background information on original post (This autopopulates for your reference). The Background information is generated by OpenAI's GPT-4, and used by the model to generate a response. Because the Background information is generated by an LLM, it may contain mistakes.", height = 780, value=st.session_state.background_info if 'background_info' in st.session_state else '', key = 'background_info_key')
if st.button("Request New Background Information"):
regenerate_background = True
with left_col:
original_post = st.text_area("Paste Original Post Here \n", height=100)
word_limit = st.text_input("Word Limit for Response", placeholder = "Please provide a word limit for the response")
chat_mdl = None
draft_response = ''
# Check if the "Submit" button is clicked
if st.button("Submit"):
if st.session_state.api_key:
os.environ["OPENAI_API_KEY"] = st.session_state.api_key
# add condition to check for passphrase to allow use of DSI api key stored in secrets
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
#umang key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase2"]):
#abbie key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key2"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase3"]):
#myranda key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key3"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase4"]):
#jasmine key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key4"]
chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
else:
st.warning('Please enter Open AI API Key')
if chat_mdl is not None:
if user_data is None:
draft_response, background_text = generate_custom_response(original_post, chat_mdl, "", "", word_limit)
response_assessment = assessing_response(chat_mdl, draft_response.content)
st.session_state.draft_response = draft_response.content
st.session_state.background_text = background_text
# st.session_state.sources_text = sources_text
st.session_state.background_info = background_text
# st.session_state.sources = sources_text
st.session_state.response_assessment = response_assessment
st.rerun()
else:
draft_response, background_text = generate_custom_response(original_post, chat_mdl, user_data['principles'], user_data['writing_style'], word_limit)
response_assessment = assessing_response(chat_mdl, draft_response.content)
st.session_state.draft_response = draft_response.content
st.session_state.background_text = background_text
# st.session_state.sources_text = sources_text
st.session_state.background_info = background_text
# st.session_state.sources = sources_text
st.session_state.response_assessment = response_assessment.content
st.rerun()
# Ensure session state variables are initialized
if 'draft_response' not in st.session_state:
st.session_state.draft_response = ''
if 'regenerate_prompt' not in st.session_state:
st.session_state.regenerate_prompt = ''
if 'response_assessment' not in st.session_state:
st.session_state.response_assessment = ''
# Output from function
response_textarea = st.text_area(
label="Draft Response. Please edit here or prompt suggestions in the box below.",
value=st.session_state.draft_response if 'draft_response' in st.session_state else '',
height=350,
key='draft_response_key'
)
# Add option to save responses
if st.button("Save This Response", help="Save this response to your writing style."):
#user_data["writing_style"] += st.session_state.draft_response
writing_style = user_data["writing_style"] + "\n" + st.session_state.draft_response
principles = user_data["principles"] if user_data and "principles" in user_data else ""
encrypted_api_key = str(encrypt(st.session_state.api_key, fernet))
db.put({"key": username, "writing_style": writing_style, "principles": principles,"api_key": encrypted_api_key, "login_count": 0 if principles.strip() == "" else 1})
st.write("Response saved to your writing style.")
# Assessment of the response
response_assessment = st.text_area(
label="Assessment of the Response",
value=st.session_state.response_assessment if 'response_assessment' in st.session_state else '',
height=350,
key='response_assessment_key'
)
# Initialization of the regeneration flag
if 'is_regenerating' not in st.session_state:
st.session_state.is_regenerating = False
# Check if the app is in the "regeneration" phase
if st.session_state.is_regenerating:
# Display the regenerated response explicitly
regenerate_prompt = st.text_area(
"Request a new draft",
value=st.session_state.regenerate_prompt,
placeholder="You may edit the regenerated draft directly above, or request further changes here.",
height=100,
key='regenerate_prompt_key'
)
# Reset the regeneration flag
st.session_state.is_regenerating = False
else:
# Normal behavior: display the text area for manual input
regenerate_prompt = st.text_area(
"Request a new draft",
placeholder="You may edit the draft directly above, or request a new draft with additional guidance here.",
height=100,
key='regenerate_prompt_key'
)
if (draft_response is not None) and (regenerate_prompt is not None):
if st.button("Regenerate"):
if st.session_state.api_key:
os.environ['OPENAI_API_KEY'] = st.session_state.api_key
# add condition to check for passphrase to allow use of DSI api key stored in secrets
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
#umang key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase2"]):
#abbie key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key2"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase3"]):
#myranda key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key3"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase4"]):
#jasmine key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key4"]
chat_mdl = ChatOpenAI(
model_name='gpt-4', temperature=0.1)
if chat_mdl is not None:
updated_response, background_info = regenerate_custom_response(
original_post, chat_mdl, regenerate_prompt, st.session_state.draft_response, regenerate_background, st.session_state.background_text)
st.session_state.draft_response = updated_response.content
updated_response_assessment = assessing_response(chat_mdl, updated_response).content
st.session_state.response_assessment = updated_response_assessment
st.session_state.is_regenerating = False
st.rerun()
if regenerate_background:
if st.session_state.api_key:
os.environ['OPENAI_API_KEY'] = st.session_state.api_key
# add condition to check for passphrase to allow use of DSI api key stored in secrets
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
#umang key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase2"]):
#abbie key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key2"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase3"]):
#myranda key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key3"]
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase4"]):
#jasmine key
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key4"]
chat_mdl = ChatOpenAI(
model_name='gpt-4', temperature=0.1)
if chat_mdl is not None:
updated_response, background_text = regenerate_custom_response(
original_post, chat_mdl, regenerate_prompt, st.session_state.draft_response, regenerate_background, st.session_state.background_text)
st.session_state.draft_response = updated_response.content
st.session_state.background_text = background_info
st.session_state.background_info = background_info # what is the difference between this and background_text?
regenerate_background = False
st.session_state.is_regenerating = False
st.rerun()
elif authentication_status is False:
st.error('Username/password is incorrect')
# added registration module if username/password is incorrect
try:
if authenticator.register_user('New User Registration', preauthorization=False):
st.success('User Registered Successfully! Please log in above.')
except Exception as e:
st.error(e)
elif authentication_status is None:
st.warning('Please enter your username and password')
try:
if authenticator.register_user(preauthorization=False):
st.success('User Registered Successfully! Please log in above.')
except Exception as e:
st.error(e)
with open('config.yaml', 'w') as file:
yaml.dump(config, file, default_flow_style=False)
config_drive.put("config.yaml", path="config.yaml")
|