dwipper commited on
Commit
9b46c74
1 Parent(s): 45f2575

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -332
app.py CHANGED
@@ -7,19 +7,12 @@ import json
7
  from jinja2 import Template
8
  import requests
9
 
10
- # Initialize OpenAI
11
- openai.api_key = os.environ.get('OPENAI_API_KEY')
12
-
13
  # Configuration variables
14
  airtable_api_key = os.environ.get('AIRTABLE_API_KEY')
15
 
16
- # Airtable table names
17
- policies_table_name = 'tbla6PC65qZfqdJhE'
18
- prompts_table_name = 'tblYIZEB8m6JkGDEP'
19
- qalog_table_name = 'tbl4oNgFPWM5xH1XO'
20
  examples_table_name = 'tblu7sraOEmRgEGkp'
21
- users_table_name = 'tblLNe5ZL47SvrAEk'
22
- user_log_table_name = 'tblrlTsRrkl6BqMAJ'
23
 
24
  # Define the style and content for the response field
25
  label_text = "NILI Response"
@@ -28,9 +21,6 @@ background_color = "white"
28
  border_radius = "10px"
29
  response_label = f'<span style="display: inline-block; position: relative; z-index: var(--layer-4); border: solid var(--block-title-border-width) var(--block-title-border-color); border-radius: var(--block-title-radius); background: var(--block-title-background-fill); padding: var(--block-title-padding); color: var(--block-title-text-color); font-weight: var(--block-title-text-weight); font-size: var(--block-title-text-size); line-height: var(--line-sm); margin-bottom: var(--spacing-lg);">{label_text}</span>'
30
 
31
- #Airtable Base ID
32
- base_id = 'appcUK3hUWC7GM2Kb'
33
-
34
  #Name of the prompt temlate record
35
  #prompt_name = "NILI_v1"
36
 
@@ -44,133 +34,6 @@ headers = {
44
  "Accept": "application/json",
45
  }
46
 
47
- def set_defaults(request: gr.Request):
48
-
49
- if request.username:
50
- print(request.username)
51
- else:
52
- print("No User Name")
53
-
54
- return
55
-
56
- #Function to trim prompts....not used
57
- def prompt_trim(prompt: str) -> str:
58
- lines = prompt.split('\n')
59
- trimmed = '\n'.join([l.strip() for l in lines])
60
- return trimmed
61
-
62
- #Get the policies for the selected schools and concatenate them.
63
- def get_policies(user_school):
64
-
65
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{policies_table_name}'
66
-
67
- # Parameters for the API request to filter by 'school' field and retrieve 'policy_text'
68
- params = {
69
- 'filterByFormula': f'school = "{user_school}"',
70
- 'fields[]': 'policy_text' # Replace with the name of your field
71
- }
72
-
73
- # Initialize an empty string to store concatenated policies
74
- concatenated_policies = ''
75
-
76
- #print(params)
77
-
78
- try:
79
- # Send a GET request to the Airtable API
80
- response = requests.get(airtable_endpoint, headers=headers, params=params)
81
-
82
- # Check if the request was successful (status code 200)
83
- if response.status_code == 200:
84
- # Parse the JSON response
85
- data = response.json()
86
-
87
- # Check if there are records in the response
88
- if data.get('records'):
89
-
90
- # Extract the 'policy_text' values from each record and concatenate them
91
- for record in data['records']:
92
- policy_text = record['fields']['policy_text']
93
- if concatenated_policies:
94
- concatenated_policies += "\n----------\n"
95
- concatenated_policies += policy_text
96
-
97
- else:
98
- print("No records found in the 'policies' table for the selected schools.")
99
- else:
100
- print(f"Failed to retrieve data. Status code: {response.status_code}")
101
- except Exception as e:
102
- print(f"An error occurred: {str(e)}")
103
-
104
- #print(concatenated_policies)
105
-
106
- return concatenated_policies
107
-
108
- #Get a list of School Name from the policies for the UI dropdown
109
- def get_schools():
110
-
111
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{policies_table_name}'
112
-
113
- # Parameters for the API request to select only the 'school' field
114
- params = {
115
- 'filterByFormula': f'app = "{app}"',
116
- 'fields[]': 'school', # Replace with the name of your field
117
- 'sort[0][field]': 'school', # Sort by the 'school' field
118
- 'sort[0][direction]': 'asc', # Sort in ascending order
119
- }
120
-
121
- schools = []
122
-
123
- try:
124
- # Send a GET request to the Airtable API
125
- response = requests.get(airtable_endpoint, headers=headers, params=params)
126
-
127
- # Check if the request was successful (status code 200)
128
- if response.status_code == 200:
129
- # Parse the JSON response
130
- data = response.json()
131
-
132
- # Check if there are records in the response
133
- if data.get('records'):
134
- # Extract the 'school' values from each record
135
- schools = [record['fields']['school'] for record in data['records']]
136
-
137
-
138
- else:
139
- print("No records found in the 'policies' table.")
140
- else:
141
- print(f"Failed to retrieve data. Status code: {response.status_code}")
142
- except Exception as e:
143
- print(f"An error occurred: {str(e)}")
144
-
145
- return schools
146
-
147
- #Get the designated prompt template record
148
- def get_prompt(header, template_content):
149
-
150
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{prompts_table_name}'
151
-
152
- params = {
153
- 'filterByFormula': "prompt_name='NILI_v1'"
154
- }
155
-
156
- response = requests.get(airtable_endpoint, headers=headers, params=params)
157
-
158
- # Check for errors
159
- response.raise_for_status()
160
-
161
- data = response.json()
162
-
163
- # Check if there is at least one record matching the condition
164
- if data.get('records'):
165
- # Get the first record (there should be only one)
166
- record = data['records'][0]['fields']
167
-
168
- # Assign system_prompt and user_prompt to variables
169
- header = record.get('system_prompt', '')
170
- template_content = record.get('user_prompt', '')
171
-
172
- return header, template_content
173
-
174
 
175
  def get_examples():
176
 
@@ -201,216 +64,23 @@ def get_examples():
201
 
202
  return ui_examples
203
 
204
- def append_to_at_qalog(your_role, school_selection, output_format, input_text, gpt_response,response_time,question_cost,prompt_tokens,completion_tokens):
205
-
206
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{qalog_table_name}'
207
-
208
- # Organize data for Airtable
209
- new_fields = {
210
- 'your_role': str(your_role),
211
- 'school_selection': str(school_selection),
212
- 'output_format': str(output_format),
213
- 'input_text': str(input_text),
214
- 'gpt_response': str(gpt_response),
215
- 'response_time': str(response_time),
216
- 'question_cost': question_cost,
217
- 'user_name': str(logged_in_user),
218
- 'prompt_tokens': prompt_tokens,
219
- 'completion_tokens': completion_tokens
220
- }
221
-
222
- data = {
223
- 'fields': new_fields
224
- }
225
- try:
226
- # Post data to Airtable
227
- response = requests.post(airtable_endpoint, headers=headers, json=data)
228
-
229
- # Check for errors
230
- response.raise_for_status()
231
-
232
- except requests.exceptions.HTTPError as http_error:
233
- # Handle the HTTP error (e.g., log it or display an error message)
234
- print(f"HTTP error occurred: {http_error}")
235
-
236
- except Exception as e:
237
- # Handle exceptions, log errors, or raise them as needed
238
- print(f"An error occurred: {str(e)}")
239
-
240
- #Chatbot Function
241
- def chatbot(school_ddss,input_text):
242
-
243
- start_time = datetime.datetime.now()
244
-
245
- school_text = school_ddss
246
-
247
- # Read the Hydrated policies
248
- policies = get_policies(school_text)
249
-
250
- template_content = ''
251
- header = ''
252
-
253
- header, template_content = get_prompt(header, template_content)
254
-
255
- header_template = Template(header)
256
-
257
- #merged_header = header_template.render(your_role=your_role)
258
- merged_header = header_template.render(your_role=user_user_role)
259
-
260
- # Create a Jinja2 template from the content
261
- template = Template(template_content)
262
-
263
- # Render the template with the policy JSON
264
- analysis_input = template.render(policies=policies, question=input_text,format=user_output_format,your_role=user_user_role)
265
- trimmed_input = prompt_trim(analysis_input)
266
-
267
- response = openai.ChatCompletion.create(
268
- model="gpt-4",
269
- temperature=0,
270
- messages=[
271
- {
272
- "role": "system",
273
- "content": merged_header
274
- },
275
- {
276
- "role": "user",
277
- "content": analysis_input
278
- }
279
- ]
280
- )
281
-
282
- gpt_response = response.choices[0].message["content"]
283
-
284
- tokens_used = response.usage
285
- question_cost = (tokens_used.get('total_tokens', 0) / 1000) * .03
286
- prompt_tokens = tokens_used.get('prompt_tokens',)
287
- completion_tokens = tokens_used.get('completion_tokens', 0)
288
-
289
- end_time = datetime.datetime.now()
290
- response_time = end_time - start_time
291
-
292
- append_to_at_qalog(user_user_role, school_text, user_output_format, input_text, gpt_response, response_time,
293
- question_cost, prompt_tokens, completion_tokens)
294
-
295
- return {nili_response_html: gpt_response}
296
-
297
- def log_login(username):
298
-
299
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{user_log_table_name}'
300
-
301
- # Organize data for Airtable
302
- new_fields = {
303
- 'user_name': str(username),
304
- 'app': str(app)
305
- }
306
-
307
- data = {
308
- 'fields': new_fields
309
- }
310
-
311
- try:
312
- # Post data to Airtable
313
- response = requests.post(airtable_endpoint, headers=headers, json=data)
314
-
315
- # Check for errors
316
- response.raise_for_status()
317
-
318
- except requests.exceptions.HTTPError as http_error:
319
- # Handle the HTTP error (e.g., log it or display an error message)
320
- print(f"HTTP error occurred: {http_error}")
321
-
322
- except Exception as e:
323
- # Handle exceptions, log errors, or raise them as needed
324
- print(f"An error occurred: {str(e)}")
325
-
326
-
327
- def login_auth(username, password):
328
-
329
- airtable_endpoint = f'https://api.airtable.com/v0/{base_id}/{users_table_name}'
330
-
331
- # Query the 'users' table to check for a match with the provided username and password
332
- params = {
333
- 'filterByFormula': f'AND(user_name = "{username}", password = "{password}")'
334
- }
335
-
336
- response = requests.get(airtable_endpoint, headers=headers, params=params)
337
-
338
- if response.status_code == 200:
339
- data = response.json()
340
- #If the matching user/password record is found:
341
- if data.get('records'):
342
-
343
- user_details = data['records'][0]['fields']
344
-
345
- log_login(username)
346
-
347
- #Set the global logged_in_user variable. This used in the append_to_at_qalog function to track what user asked the question
348
- global logged_in_user,user_user_role, user_output_format, user_school
349
- user_user_role = user_details.get('user_role')
350
- user_output_format = user_details.get('output_format')
351
- user_school = user_details.get('school_name', [None])[0]
352
- logged_in_user = username
353
-
354
- return True
355
-
356
- print(f"Invalid user/password combination")
357
-
358
- return False
359
-
360
  #Gradio UI
361
- #CIMStheme = gr.themes.Soft().set(button_primary_background_fill='#6562F4',body_background_fill='#e6effc')
362
  CIMStheme = gr.themes.Soft().set(button_primary_background_fill='#6562F4')
363
 
364
- # Initialize an empty list to store the examples
365
- #ui_examples = []
366
-
367
- school_selection = []
368
- #username_text = ""
369
-
370
- #Gets the school for the school selection DD
371
- schools = get_schools()
372
-
373
- #This code runs first before the login screen, so if there's no login screen used, this sets the logged_in_user. Otherwise it is set in the login function.
374
- logged_in_user = 'admin'
375
- #global user_user_role, user_output_format, user_school
376
- user_user_role = "Student Athlete"
377
- user_output_format = "Table"
378
- #user_school = []
379
-
380
  with gr.Blocks(CIMStheme) as iface:
381
- #with gr.Row():
382
- #with gr.Column():
383
- #gr.Image(label="Logo",value="CIMS Logo Purple.png",height=100,show_download_button=False,interactive=False,show_label=False,elem_id="logo",container=False)
384
  with gr.Row():
385
  with gr.Column():
386
  gr.Markdown(value="<H2 style='text-align: center;'>NILI - Powered by CIMS.AI</h2>")
387
- with gr.Row():
388
- with gr.Column(variant='panel'):
389
- school_ddss = gr.components.Dropdown(schools, multiselect=False, info="Select your school.", label="School")
390
  with gr.Row():
391
  with gr.Column(variant='panel'):
392
  question_tbox= gr.components.Textbox(lines=3, placeholder="Enter your question here", label="NIL Question",info="Depending the scope of your question, results may take 30-60 sec.",interactive=True)
393
  with gr.Row(variant='panel'):
394
  with gr.Column():
395
  examples_cmpt= gr.Examples(examples=get_examples(),inputs=question_tbox,label="Sample NIL questions - Click to select one")
396
- with gr.Row():
397
- with gr.Column():
398
- submit_btn = gr.components.Button(value="Submit", size='sm', variant="primary")
399
- with gr.Row():
400
- with gr.Column(variant='panel'):
401
- response_label_md = gr.components.Markdown(response_label)
402
- nili_response_html = gr.components.HTML(label="NILI Response")
403
- submit_btn.click(fn=chatbot,inputs=[school_ddss, question_tbox],
404
- outputs=[nili_response_html])
405
  with gr.Row():
406
  with gr.Column():
407
  gr.Markdown(value="[Ask Questions/Provide Feedback](https://discord.com/channels/1168589934244929647/1168589934244929650)")
408
  with gr.Row():
409
  with gr.Column():
410
  gr.HTML('<center><i>© 2023 Collegiate Influencer Marketing Systems, Inc.</i><br>CIMS.AI, CIMS.AI logo, NILI, NILI logo, and EzNIL are trademarks of Collegiate Influencer Marketing Systems, Inc.</center>')
411
-
412
- #iface.load(fn=set_defaults)
413
-
414
- #iface.launch(auth=login_auth, auth_message= "Enter your username and password that you received from CIMS.AI. To request a login, please email 'info@cims.ai'")
415
- #iface.launch(auth=("admin","admin"))
416
  iface.launch()
 
7
  from jinja2 import Template
8
  import requests
9
 
 
 
 
10
  # Configuration variables
11
  airtable_api_key = os.environ.get('AIRTABLE_API_KEY')
12
 
 
 
 
 
13
  examples_table_name = 'tblu7sraOEmRgEGkp'
14
+ #Airtable Base ID
15
+ base_id = 'appcUK3hUWC7GM2Kb'
16
 
17
  # Define the style and content for the response field
18
  label_text = "NILI Response"
 
21
  border_radius = "10px"
22
  response_label = f'<span style="display: inline-block; position: relative; z-index: var(--layer-4); border: solid var(--block-title-border-width) var(--block-title-border-color); border-radius: var(--block-title-radius); background: var(--block-title-background-fill); padding: var(--block-title-padding); color: var(--block-title-text-color); font-weight: var(--block-title-text-weight); font-size: var(--block-title-text-size); line-height: var(--line-sm); margin-bottom: var(--spacing-lg);">{label_text}</span>'
23
 
 
 
 
24
  #Name of the prompt temlate record
25
  #prompt_name = "NILI_v1"
26
 
 
34
  "Accept": "application/json",
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  def get_examples():
39
 
 
64
 
65
  return ui_examples
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  #Gradio UI
 
68
  CIMStheme = gr.themes.Soft().set(button_primary_background_fill='#6562F4')
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  with gr.Blocks(CIMStheme) as iface:
 
 
 
71
  with gr.Row():
72
  with gr.Column():
73
  gr.Markdown(value="<H2 style='text-align: center;'>NILI - Powered by CIMS.AI</h2>")
 
 
 
74
  with gr.Row():
75
  with gr.Column(variant='panel'):
76
  question_tbox= gr.components.Textbox(lines=3, placeholder="Enter your question here", label="NIL Question",info="Depending the scope of your question, results may take 30-60 sec.",interactive=True)
77
  with gr.Row(variant='panel'):
78
  with gr.Column():
79
  examples_cmpt= gr.Examples(examples=get_examples(),inputs=question_tbox,label="Sample NIL questions - Click to select one")
 
 
 
 
 
 
 
 
 
80
  with gr.Row():
81
  with gr.Column():
82
  gr.Markdown(value="[Ask Questions/Provide Feedback](https://discord.com/channels/1168589934244929647/1168589934244929650)")
83
  with gr.Row():
84
  with gr.Column():
85
  gr.HTML('<center><i>© 2023 Collegiate Influencer Marketing Systems, Inc.</i><br>CIMS.AI, CIMS.AI logo, NILI, NILI logo, and EzNIL are trademarks of Collegiate Influencer Marketing Systems, Inc.</center>')
 
 
 
 
 
86
  iface.launch()