Spaces:
Sleeping
Sleeping
Myranda
commited on
Commit
•
4529c9d
1
Parent(s):
a7669c5
Merge pull request #113 from vanderbilt-data-science/issue-90
Browse files
app.py
CHANGED
@@ -10,14 +10,14 @@ from free_speech_app.DataLoadDb import *
|
|
10 |
from free_speech_app.FreeSpeechPromptsResponses import *
|
11 |
from langchain.chat_models import ChatOpenAI
|
12 |
|
13 |
-
#connect to/create Deta user database
|
14 |
deta = Deta(st.secrets["deta_key"])
|
15 |
db = deta.Base("user_data")
|
16 |
|
17 |
-
#fernet key (generated locally, stored in streamlit secrets)
|
18 |
-
fernet = Fernet(bytes(st.secrets["fernet_key"],'utf-8'))
|
19 |
|
20 |
-
#activeloop_token
|
21 |
os.environ["ACTIVELOOP_TOKEN"] = st.secrets["deeplake_key"]
|
22 |
|
23 |
config_drive = deta.Drive("passwords")
|
@@ -34,6 +34,7 @@ authenticator = stauth.Authenticate(
|
|
34 |
config['preauthorized']
|
35 |
)
|
36 |
|
|
|
37 |
def get_user_data(user):
|
38 |
data = db.fetch().items
|
39 |
for person in data:
|
@@ -41,14 +42,24 @@ def get_user_data(user):
|
|
41 |
return person
|
42 |
return None
|
43 |
|
|
|
44 |
def encrypt(api_key: str, fernet) -> bytes:
|
45 |
"""Encrypt the API key."""
|
46 |
return fernet.encrypt(api_key.encode())
|
47 |
|
|
|
48 |
def decrypt(encrypted_api_key: bytes, fernet) -> str:
|
49 |
"""Decrypt the encrypted API key."""
|
50 |
return fernet.decrypt(encrypted_api_key).decode()
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
# Render the login module
|
53 |
name, authentication_status, username = authenticator.login('Login', 'main')
|
54 |
|
@@ -60,23 +71,25 @@ if authentication_status:
|
|
60 |
# Sidebar for navigation
|
61 |
page = st.sidebar.radio("Choose a page", ["Account Setup", "API Key Help", "Respond to Post"])
|
62 |
|
|
|
63 |
# Fetch user data from the database
|
64 |
user_data = get_user_data(username)
|
65 |
|
66 |
if page == "Account Setup":
|
|
|
67 |
|
68 |
st.title("Account Setup")
|
69 |
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.**")
|
70 |
-
|
71 |
-
|
72 |
# Input boxes with existing data
|
73 |
-
|
74 |
if 'api_key' not in st.session_state:
|
75 |
st.session_state.api_key = ""
|
76 |
-
api_input = st.text_input("Paste OpenAI API Key", value=decrypt(user_data["api_key"].encode()[
|
|
|
77 |
encrypted_api_key = str(encrypt(api_input, fernet))
|
78 |
st.session_state.api_key = api_input
|
79 |
-
|
80 |
principles = st.text_area("My Principles (Paste Principles here)", height = 100, placeholder = "Enter the main principles of your life you wish this response to uphold", value=user_data["principles"] if user_data and "principles" in user_data else "")
|
81 |
writing_style = st.text_area("My Writing Style (Paste Examples)", height = 100, placeholder = "Provide examples of your writing style here", value=user_data["writing_style"] if user_data and "writing_style" in user_data else "")
|
82 |
#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)
|
@@ -86,6 +99,8 @@ if authentication_status:
|
|
86 |
db.put({"key": username, "principles": principles, "writing_style": writing_style, "api_key": encrypted_api_key})
|
87 |
|
88 |
if page == "API Key Help":
|
|
|
|
|
89 |
st.title("OpenAI API Key Setup")
|
90 |
|
91 |
st.header('What is an API key?')
|
@@ -96,10 +111,11 @@ if authentication_status:
|
|
96 |
|
97 |
image = 'apikeyex.png'
|
98 |
st.header('How to get an OpenAI API key:')
|
99 |
-
st.write('1. Go to https://platform.openai.com/account/api-keys')
|
100 |
st.write('2. Log in or create an OpenAI account if you do not have one')
|
101 |
st.write('3. Click "Create new secret key" and give your key a name')
|
102 |
-
st.image(image, caption=None, width=None, use_column_width=None,
|
|
|
103 |
st.write('4. Copy the generated API key and keep it private like a password')
|
104 |
|
105 |
st.header('Using your API key')
|
@@ -108,14 +124,15 @@ if authentication_status:
|
|
108 |
|
109 |
st.warning('Treat your API key like a secret! Do not share it publicly.')
|
110 |
|
111 |
-
|
112 |
elif page == "Respond to Post":
|
|
|
113 |
st.title("Respond to Post")
|
114 |
-
|
115 |
left_col, right_col = st.columns(2)
|
116 |
-
|
117 |
# Input boxes
|
118 |
|
|
|
119 |
with right_col:
|
120 |
background_info = st.text_area("Background information on original post (This autopopulates for your reference)", height = 780, value=st.session_state.background_info if 'background_info' in st.session_state else '', key = 'background_info_key')
|
121 |
|
@@ -125,7 +142,7 @@ if authentication_status:
|
|
125 |
|
126 |
chat_mdl = None
|
127 |
draft_response = ''
|
128 |
-
|
129 |
# Check if the "Submit" button is clicked
|
130 |
if st.button("Submit"):
|
131 |
if st.session_state.api_key:
|
@@ -134,32 +151,35 @@ if authentication_status:
|
|
134 |
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
|
135 |
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
|
136 |
chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
|
137 |
-
|
138 |
if chat_mdl is not None:
|
139 |
if user_data is None:
|
|
|
140 |
draft_response, background_text = generate_custom_response(original_post, chat_mdl, "", "", word_limit)
|
|
|
141 |
st.session_state.draft_response = draft_response.content
|
142 |
st.session_state.background_text = background_text
|
143 |
-
#st.session_state.sources_text = sources_text
|
144 |
st.session_state.background_info = background_text
|
145 |
-
#st.session_state.sources = sources_text
|
146 |
st.rerun()
|
147 |
else:
|
|
|
148 |
draft_response, background_text = generate_custom_response(original_post, chat_mdl, user_data['principles'], user_data['writing_style'], word_limit)
|
|
|
149 |
st.session_state.draft_response = draft_response.content
|
150 |
st.session_state.background_text = background_text
|
151 |
-
#st.session_state.sources_text = sources_text
|
152 |
st.session_state.background_info = background_text
|
153 |
-
#st.session_state.sources = sources_text
|
154 |
st.rerun()
|
155 |
-
|
156 |
-
|
157 |
# Ensure session state variables are initialized
|
158 |
if 'draft_response' not in st.session_state:
|
159 |
st.session_state.draft_response = ''
|
160 |
if 'regenerate_prompt' not in st.session_state:
|
161 |
st.session_state.regenerate_prompt = ''
|
162 |
-
|
163 |
# Output from function
|
164 |
response_textarea = st.text_area(
|
165 |
label="Draft Response. Please edit here or prompt suggestions in the box below.",
|
@@ -167,11 +187,11 @@ if authentication_status:
|
|
167 |
height=350,
|
168 |
key='draft_response_key'
|
169 |
)
|
170 |
-
|
171 |
# Initialization of the regeneration flag
|
172 |
if 'is_regenerating' not in st.session_state:
|
173 |
st.session_state.is_regenerating = False
|
174 |
-
|
175 |
# Check if the app is in the "regeneration" phase
|
176 |
if st.session_state.is_regenerating:
|
177 |
# Display the regenerated response explicitly
|
@@ -199,23 +219,27 @@ if authentication_status:
|
|
199 |
os.environ['OPENAI_API_KEY'] = st.session_state.api_key
|
200 |
# add condition to check for passphrase to allow use of DSI api key stored in secrets
|
201 |
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
|
202 |
-
|
|
|
203 |
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase2"]):
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
207 |
if chat_mdl is not None:
|
208 |
-
updated_response = regenerate_custom_response(
|
|
|
209 |
st.session_state.draft_response = updated_response
|
210 |
st.session_state.is_regenerating = True
|
211 |
|
212 |
st.rerun()
|
213 |
-
|
214 |
-
|
215 |
elif authentication_status is False:
|
216 |
st.error('Username/password is incorrect')
|
217 |
-
#added registration module if username/password is incorrect
|
218 |
-
|
219 |
try:
|
220 |
if authenticator.register_user('New User Registration', preauthorization=False):
|
221 |
st.success('User Registered Successfully! Please log in above.')
|
@@ -224,7 +248,7 @@ elif authentication_status is False:
|
|
224 |
|
225 |
elif authentication_status is None:
|
226 |
st.warning('Please enter your username and password')
|
227 |
-
|
228 |
try:
|
229 |
if authenticator.register_user('New User Registration', preauthorization=False):
|
230 |
st.success('User Registered Successfully! Please log in above.')
|
@@ -234,4 +258,4 @@ elif authentication_status is None:
|
|
234 |
with open('config.yaml', 'w') as file:
|
235 |
yaml.dump(config, file, default_flow_style=False)
|
236 |
|
237 |
-
config_drive.put("config.yaml", path
|
|
|
10 |
from free_speech_app.FreeSpeechPromptsResponses import *
|
11 |
from langchain.chat_models import ChatOpenAI
|
12 |
|
13 |
+
# connect to/create Deta user database
|
14 |
deta = Deta(st.secrets["deta_key"])
|
15 |
db = deta.Base("user_data")
|
16 |
|
17 |
+
# fernet key (generated locally, stored in streamlit secrets)
|
18 |
+
fernet = Fernet(bytes(st.secrets["fernet_key"], 'utf-8'))
|
19 |
|
20 |
+
# activeloop_token
|
21 |
os.environ["ACTIVELOOP_TOKEN"] = st.secrets["deeplake_key"]
|
22 |
|
23 |
config_drive = deta.Drive("passwords")
|
|
|
34 |
config['preauthorized']
|
35 |
)
|
36 |
|
37 |
+
|
38 |
def get_user_data(user):
|
39 |
data = db.fetch().items
|
40 |
for person in data:
|
|
|
42 |
return person
|
43 |
return None
|
44 |
|
45 |
+
|
46 |
def encrypt(api_key: str, fernet) -> bytes:
|
47 |
"""Encrypt the API key."""
|
48 |
return fernet.encrypt(api_key.encode())
|
49 |
|
50 |
+
|
51 |
def decrypt(encrypted_api_key: bytes, fernet) -> str:
|
52 |
"""Decrypt the encrypted API key."""
|
53 |
return fernet.decrypt(encrypted_api_key).decode()
|
54 |
|
55 |
+
|
56 |
+
def add_logos():
|
57 |
+
st.markdown(
|
58 |
+
'![image](free_speech_app/logos/Future-of-Free-Speech-logo.png)')
|
59 |
+
st.markdown(
|
60 |
+
'![image](free_speech_app/logos/Vanderbilt-University-Logo.png)')
|
61 |
+
|
62 |
+
|
63 |
# Render the login module
|
64 |
name, authentication_status, username = authenticator.login('Login', 'main')
|
65 |
|
|
|
71 |
# Sidebar for navigation
|
72 |
page = st.sidebar.radio("Choose a page", ["Account Setup", "API Key Help", "Respond to Post"])
|
73 |
|
74 |
+
|
75 |
# Fetch user data from the database
|
76 |
user_data = get_user_data(username)
|
77 |
|
78 |
if page == "Account Setup":
|
79 |
+
add_logos()
|
80 |
|
81 |
st.title("Account Setup")
|
82 |
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.**")
|
83 |
+
|
|
|
84 |
# Input boxes with existing data
|
85 |
+
|
86 |
if 'api_key' not in st.session_state:
|
87 |
st.session_state.api_key = ""
|
88 |
+
api_input = st.text_input("Paste OpenAI API Key", value=decrypt(user_data["api_key"].encode()[
|
89 |
+
2:-1], fernet) if user_data and "api_key" in user_data else "", type="password")
|
90 |
encrypted_api_key = str(encrypt(api_input, fernet))
|
91 |
st.session_state.api_key = api_input
|
92 |
+
|
93 |
principles = st.text_area("My Principles (Paste Principles here)", height = 100, placeholder = "Enter the main principles of your life you wish this response to uphold", value=user_data["principles"] if user_data and "principles" in user_data else "")
|
94 |
writing_style = st.text_area("My Writing Style (Paste Examples)", height = 100, placeholder = "Provide examples of your writing style here", value=user_data["writing_style"] if user_data and "writing_style" in user_data else "")
|
95 |
#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)
|
|
|
99 |
db.put({"key": username, "principles": principles, "writing_style": writing_style, "api_key": encrypted_api_key})
|
100 |
|
101 |
if page == "API Key Help":
|
102 |
+
add_logos()
|
103 |
+
|
104 |
st.title("OpenAI API Key Setup")
|
105 |
|
106 |
st.header('What is an API key?')
|
|
|
111 |
|
112 |
image = 'apikeyex.png'
|
113 |
st.header('How to get an OpenAI API key:')
|
114 |
+
st.write('1. Go to https://platform.openai.com/account/api-keys')
|
115 |
st.write('2. Log in or create an OpenAI account if you do not have one')
|
116 |
st.write('3. Click "Create new secret key" and give your key a name')
|
117 |
+
st.image(image, caption=None, width=None, use_column_width=None,
|
118 |
+
clamp=False, channels="RGB", output_format="auto")
|
119 |
st.write('4. Copy the generated API key and keep it private like a password')
|
120 |
|
121 |
st.header('Using your API key')
|
|
|
124 |
|
125 |
st.warning('Treat your API key like a secret! Do not share it publicly.')
|
126 |
|
|
|
127 |
elif page == "Respond to Post":
|
128 |
+
add_logos()
|
129 |
st.title("Respond to Post")
|
130 |
+
|
131 |
left_col, right_col = st.columns(2)
|
132 |
+
|
133 |
# Input boxes
|
134 |
|
135 |
+
|
136 |
with right_col:
|
137 |
background_info = st.text_area("Background information on original post (This autopopulates for your reference)", height = 780, value=st.session_state.background_info if 'background_info' in st.session_state else '', key = 'background_info_key')
|
138 |
|
|
|
142 |
|
143 |
chat_mdl = None
|
144 |
draft_response = ''
|
145 |
+
|
146 |
# Check if the "Submit" button is clicked
|
147 |
if st.button("Submit"):
|
148 |
if st.session_state.api_key:
|
|
|
151 |
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
|
152 |
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
|
153 |
chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
|
154 |
+
|
155 |
if chat_mdl is not None:
|
156 |
if user_data is None:
|
157 |
+
|
158 |
draft_response, background_text = generate_custom_response(original_post, chat_mdl, "", "", word_limit)
|
159 |
+
|
160 |
st.session_state.draft_response = draft_response.content
|
161 |
st.session_state.background_text = background_text
|
162 |
+
# st.session_state.sources_text = sources_text
|
163 |
st.session_state.background_info = background_text
|
164 |
+
# st.session_state.sources = sources_text
|
165 |
st.rerun()
|
166 |
else:
|
167 |
+
|
168 |
draft_response, background_text = generate_custom_response(original_post, chat_mdl, user_data['principles'], user_data['writing_style'], word_limit)
|
169 |
+
|
170 |
st.session_state.draft_response = draft_response.content
|
171 |
st.session_state.background_text = background_text
|
172 |
+
# st.session_state.sources_text = sources_text
|
173 |
st.session_state.background_info = background_text
|
174 |
+
# st.session_state.sources = sources_text
|
175 |
st.rerun()
|
176 |
+
|
|
|
177 |
# Ensure session state variables are initialized
|
178 |
if 'draft_response' not in st.session_state:
|
179 |
st.session_state.draft_response = ''
|
180 |
if 'regenerate_prompt' not in st.session_state:
|
181 |
st.session_state.regenerate_prompt = ''
|
182 |
+
|
183 |
# Output from function
|
184 |
response_textarea = st.text_area(
|
185 |
label="Draft Response. Please edit here or prompt suggestions in the box below.",
|
|
|
187 |
height=350,
|
188 |
key='draft_response_key'
|
189 |
)
|
190 |
+
|
191 |
# Initialization of the regeneration flag
|
192 |
if 'is_regenerating' not in st.session_state:
|
193 |
st.session_state.is_regenerating = False
|
194 |
+
|
195 |
# Check if the app is in the "regeneration" phase
|
196 |
if st.session_state.is_regenerating:
|
197 |
# Display the regenerated response explicitly
|
|
|
219 |
os.environ['OPENAI_API_KEY'] = st.session_state.api_key
|
220 |
# add condition to check for passphrase to allow use of DSI api key stored in secrets
|
221 |
if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
|
222 |
+
# umang key
|
223 |
+
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
|
224 |
elif (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase2"]):
|
225 |
+
# abbie key
|
226 |
+
os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key2"]
|
227 |
+
chat_mdl = ChatOpenAI(
|
228 |
+
model_name='gpt-4', temperature=0.1)
|
229 |
+
|
230 |
if chat_mdl is not None:
|
231 |
+
updated_response = regenerate_custom_response(
|
232 |
+
chat_mdl, regenerate_prompt, st.session_state.draft_response).content
|
233 |
st.session_state.draft_response = updated_response
|
234 |
st.session_state.is_regenerating = True
|
235 |
|
236 |
st.rerun()
|
237 |
+
|
238 |
+
|
239 |
elif authentication_status is False:
|
240 |
st.error('Username/password is incorrect')
|
241 |
+
# added registration module if username/password is incorrect
|
242 |
+
|
243 |
try:
|
244 |
if authenticator.register_user('New User Registration', preauthorization=False):
|
245 |
st.success('User Registered Successfully! Please log in above.')
|
|
|
248 |
|
249 |
elif authentication_status is None:
|
250 |
st.warning('Please enter your username and password')
|
251 |
+
|
252 |
try:
|
253 |
if authenticator.register_user('New User Registration', preauthorization=False):
|
254 |
st.success('User Registered Successfully! Please log in above.')
|
|
|
258 |
with open('config.yaml', 'w') as file:
|
259 |
yaml.dump(config, file, default_flow_style=False)
|
260 |
|
261 |
+
config_drive.put("config.yaml", path="config.yaml")
|