umangchaudhry commited on
Commit
7599676
·
1 Parent(s): 0c0e0a5

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +227 -0
app.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import streamlit_authenticator as stauth
3
+ from deta import Deta
4
+ import yaml
5
+ from yaml.loader import SafeLoader
6
+ import os
7
+ from cryptography.fernet import Fernet
8
+
9
+ 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")
24
+ config = config_drive.get("config.yaml").read()
25
+
26
+ config = yaml.load(config, Loader=SafeLoader)
27
+
28
+ # Create an authenticator
29
+ authenticator = stauth.Authenticate(
30
+ config['credentials'],
31
+ config['cookie']['name'],
32
+ config['cookie']['key'],
33
+ config['cookie']['expiry_days'],
34
+ config['preauthorized']
35
+ )
36
+
37
+ def get_user_data(user):
38
+ data = db.fetch().items
39
+ for person in data:
40
+ if person['key'] == 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
+
55
+ # If the user is authenticated
56
+ if authentication_status:
57
+ authenticator.logout('Logout', 'main', key='unique_key')
58
+ st.write(f'Welcome *{name}*')
59
+
60
+ # Sidebar for navigation
61
+ page = st.sidebar.radio("Choose a page", ["OpenAI API Key Setup", "Account Setup", "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("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")
77
+ encrypted_api_key = str(encrypt(api_input, fernet))
78
+ st.session_state.api_key = api_input
79
+
80
+ principles = st.text_input("My Principles", 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_input("My Writing Style (Paste Examples)", 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_input("Sources (Provide all sources you would like to use)", value=st.session_state.sources if 'sources' in st.session_state else '', key = 'sources_key')
83
+
84
+ # Update button
85
+ if st.button("Save Changes"):
86
+ db.put({"key": username, "principles": principles, "writing_style": writing_style, "sources": sources, "api_key": encrypted_api_key})
87
+
88
+ if page == "OpenAI API Key Setup":
89
+ st.title("OpenAI API Key Setup")
90
+
91
+ st.header('What is an API key?')
92
+ 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.')
93
+
94
+ st.header('Why do you need an API key?')
95
+ 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.')
96
+
97
+ image = 'free_speech_app/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, clamp=False, channels="RGB", output_format="auto")
103
+ st.write('4. Copy the generated API key and keep it private like a password')
104
+
105
+ st.header('Using your API key')
106
+ st.write('When making calls to the OpenAI API, include your API key in the request headers or parameters to authenticate.')
107
+ st.code('headers = {"Authorization": f"Bearer {YOUR_API_KEY}"}')
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 (references, relevant information, best practices for responding)", height = 700, value=st.session_state.background_info if 'background_info' in st.session_state else '', key = 'background_info_key')
121
+
122
+ with left_col:
123
+ original_post = st.text_area("Paste Original Post Here \n", height=100)
124
+
125
+ chat_mdl = None
126
+ draft_response = ''
127
+
128
+ # Check if the "Submit" button is clicked
129
+ if st.button("Submit"):
130
+ if st.session_state.api_key:
131
+ os.environ["OPENAI_API_KEY"] = st.session_state.api_key
132
+ # add condition to check for passphrase to allow use of DSI api key stored in secrets
133
+ if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
134
+ os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
135
+ chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
136
+
137
+ if chat_mdl is not None:
138
+ if user_data is None:
139
+ draft_response, background_text, sources_text = generate_custom_response(original_post, chat_mdl, "", "")
140
+ st.session_state.draft_response = draft_response.content
141
+ st.session_state.background_text = background_text
142
+ st.session_state.sources_text = sources_text
143
+ st.session_state.background_info = background_text
144
+ st.session_state.sources = sources_text
145
+ st.rerun()
146
+ else:
147
+ draft_response, background_text, sources_text = generate_custom_response(original_post, chat_mdl, user_data['principles'], user_data['writing_style'])
148
+ st.session_state.draft_response = draft_response.content
149
+ st.session_state.background_text = background_text
150
+ st.session_state.sources_text = sources_text
151
+ st.session_state.background_info = background_text
152
+ st.session_state.sources = sources_text
153
+ st.rerun()
154
+
155
+
156
+ # Ensure session state variables are initialized
157
+ if 'draft_response' not in st.session_state:
158
+ st.session_state.draft_response = ''
159
+ if 'regenerate_prompt' not in st.session_state:
160
+ st.session_state.regenerate_prompt = ''
161
+
162
+ # Output from function
163
+ response_textarea = st.text_area(
164
+ label="Draft Response. Please edit here or prompt suggestions in the box below.",
165
+ value=st.session_state.draft_response if 'draft_response' in st.session_state else '',
166
+ height=350,
167
+ key='draft_response_key'
168
+ )
169
+
170
+ # Initialization of the regeneration flag
171
+ if 'is_regenerating' not in st.session_state:
172
+ st.session_state.is_regenerating = False
173
+
174
+ # Check if the app is in the "regeneration" phase
175
+ if st.session_state.is_regenerating:
176
+ # Display the regenerated response explicitly
177
+ regenerate_prompt = st.text_area(
178
+ "Request a new draft",
179
+ value=st.session_state.regenerate_prompt,
180
+ placeholder="You may edit the regenerated draft directly above, or request further changes here.",
181
+ height=100,
182
+ key='regenerate_prompt_key'
183
+ )
184
+ # Reset the regeneration flag
185
+ st.session_state.is_regenerating = False
186
+ else:
187
+ # Normal behavior: display the text area for manual input
188
+ regenerate_prompt = st.text_area(
189
+ "Request a new draft",
190
+ placeholder="You may edit the draft directly above, or request a new draft with additional guidance here.",
191
+ height=100,
192
+ key='regenerate_prompt_key'
193
+ )
194
+
195
+ if (draft_response is not None) and (regenerate_prompt is not None):
196
+ if st.button("Regenerate"):
197
+ if st.session_state.api_key:
198
+ os.environ['OPENAI_API_KEY'] = st.session_state.api_key
199
+ # add condition to check for passphrase to allow use of DSI api key stored in secrets
200
+ if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
201
+ os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
202
+ chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
203
+
204
+ if chat_mdl is not None:
205
+ updated_response = regenerate_custom_response(chat_mdl, regenerate_prompt, st.session_state.draft_response).content
206
+ st.session_state.regenerate_prompt = updated_response
207
+ st.session_state.is_regenerating = True
208
+
209
+ st.rerun()
210
+
211
+
212
+ elif authentication_status is False:
213
+ st.error('Username/password is incorrect')
214
+
215
+ elif authentication_status is None:
216
+ st.warning('Please enter your username and password')
217
+
218
+ try:
219
+ if authenticator.register_user('New User Registration', preauthorization=False):
220
+ st.success('User Registered Successfully! Please log in above.')
221
+ except Exception as e:
222
+ st.error(e)
223
+
224
+ with open('config.yaml', 'w') as file:
225
+ yaml.dump(config, file, default_flow_style=False)
226
+
227
+ config_drive.put("config.yaml", path = "config.yaml")