awacke1 commited on
Commit
30f9bc6
β€’
1 Parent(s): 403a411

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +587 -39
app.py CHANGED
@@ -25,64 +25,159 @@ Key = os.environ.get("Key") # πŸ”‘ Don't forget your key!
25
  # 🏠 Your local app URL (Change this to your app's URL)
26
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
27
 
28
- # πŸ“ Initialize logging system
29
- if 'logs' not in st.session_state:
30
- st.session_state.logs = []
31
-
32
- def log_event(message):
33
- """Adds a log entry to the log session state."""
34
- timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
35
- st.session_state.logs.append(f"[{timestamp}] {message}")
36
-
37
- # 🏠 Add logs to sidebar
38
- st.sidebar.title("πŸ“ Log Viewer")
39
- st.sidebar.write("\n".join(st.session_state.logs))
40
-
41
  # πŸ€– OpenAI configuration
42
  # openai.api_key = os.environ.get("OPENAI_API_KEY")
43
  # MODEL = "gpt-3.5-turbo" # Replace with your desired model
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  # 🌟 Cosmos DB functions
46
  def insert_record(container, record):
 
47
  try:
48
  container.create_item(body=record)
49
- log_event("Record inserted successfully!")
50
  return True, "Record inserted successfully! πŸŽ‰"
51
  except exceptions.CosmosHttpResponseError as e:
52
- log_event(f"HTTP error occurred: {str(e)} 🚨")
53
  return False, f"HTTP error occurred: {str(e)} 🚨"
54
  except Exception as e:
55
- log_event(f"An unexpected error occurred: {str(e)} 😱")
56
  return False, f"An unexpected error occurred: {str(e)} 😱"
57
 
58
  def update_record(container, updated_record):
 
59
  try:
60
  container.upsert_item(body=updated_record)
61
- log_event(f"Record with id {updated_record['id']} successfully updated.")
62
  return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΈ"
63
  except exceptions.CosmosHttpResponseError as e:
64
- log_event(f"HTTP error occurred: {str(e)} 🚨")
65
  return False, f"HTTP error occurred: {str(e)} 🚨"
66
  except Exception as e:
67
- log_event(f"An unexpected error occurred: {traceback.format_exc()} 😱")
68
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
69
 
70
  def delete_record(container, name, id):
 
71
  try:
72
  container.delete_item(item=id, partition_key=id)
73
- log_event(f"Successfully deleted record with name: {name} and id: {id}")
74
  return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
75
  except exceptions.CosmosResourceNotFoundError:
76
- log_event(f"Record with id {id} not found. It may have been already deleted.")
77
  return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
78
  except exceptions.CosmosHttpResponseError as e:
79
- log_event(f"HTTP error occurred: {str(e)} 🚨")
80
  return False, f"HTTP error occurred: {str(e)} 🚨"
81
  except Exception as e:
82
- log_event(f"An unexpected error occurred: {traceback.format_exc()} 😱")
83
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
84
 
85
  # 🎲 Function to generate a unique UUID
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  def generate_unique_id():
87
  return str(uuid.uuid4())
88
 
@@ -109,21 +204,122 @@ def save_to_cosmos_db(container, query, response1, response2):
109
  try:
110
  container.create_item(body=record)
111
  st.success(f"Record saved successfully with ID: {record['id']}")
112
- log_event(f"Record saved to Cosmos DB with ID: {record['id']}")
113
  # Refresh the documents display
114
  st.session_state.documents = get_documents(container)
115
  except exceptions.CosmosHttpResponseError as e:
116
  st.error(f"Error saving record to Cosmos DB: {e}")
117
- log_event(f"Error saving record to Cosmos DB: {e}")
118
  else:
119
  st.error("Cosmos DB container is not initialized.")
120
- log_event("Error: Cosmos DB container is not initialized.")
121
  except Exception as e:
122
  st.error(f"An unexpected error occurred: {str(e)}")
123
- log_event(f"An unexpected error occurred while saving to Cosmos DB: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  # 🎀 Function to process text input
126
  def process_text(text_input):
 
127
  if text_input:
128
  if 'messages' not in st.session_state:
129
  st.session_state.messages = []
@@ -136,10 +332,74 @@ def process_text(text_input):
136
  with st.chat_message("assistant"):
137
  search_glossary(text_input)
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  # 🎈 Main function
140
  def main():
 
141
  st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
142
 
 
143
  if 'logged_in' not in st.session_state:
144
  st.session_state.logged_in = False
145
  if 'selected_records' not in st.session_state:
@@ -157,23 +417,24 @@ def main():
157
  if 'cloned_doc' not in st.session_state:
158
  st.session_state.cloned_doc = None
159
 
160
- # βš™οΈ Check query parameters for any action
161
  try:
162
  query_params = st.query_params
163
  query = query_params.get('q') or query_params.get('query') or ''
164
  if query:
 
165
  process_text(query)
166
- st.stop()
167
  except Exception as e:
168
  st.markdown(' ')
169
-
170
  # πŸ” Automatic Login
171
  if Key:
172
  st.session_state.primary_key = Key
173
  st.session_state.logged_in = True
174
  else:
175
  st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
176
- return
177
 
178
  if st.session_state.logged_in:
179
  # 🌌 Initialize Cosmos DB client
@@ -181,7 +442,9 @@ def main():
181
  if st.session_state.client is None:
182
  st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
183
 
 
184
  st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
 
185
  databases = get_databases(st.session_state.client)
186
  selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
187
 
@@ -231,11 +494,51 @@ def main():
231
  selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
232
 
233
  if selected_view == 'Show as Markdown':
 
 
234
  doc = documents[st.session_state.current_index]
235
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  content = json.dumps(doc, indent=2)
237
  st.markdown(f"```json\n{content}\n```")
238
 
 
239
  col_prev, col_next = st.columns([1, 1])
240
  with col_prev:
241
  if st.button("⬅️ Previous", key='prev_markdown'):
@@ -249,10 +552,11 @@ def main():
249
  st.rerun()
250
 
251
  elif selected_view == 'Show as Code Editor':
 
 
252
  doc = documents[st.session_state.current_index]
253
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
254
  doc_str = st.text_area("Edit Document", value=json.dumps(doc, indent=2), height=300, key=f'code_editor_{st.session_state.current_index}')
255
-
256
  col_prev, col_next = st.columns([1, 1])
257
  with col_prev:
258
  if st.button("⬅️ Previous", key='prev_code'):
@@ -264,7 +568,6 @@ def main():
264
  if st.session_state.current_index < total_docs - 1:
265
  st.session_state.current_index += 1
266
  st.rerun()
267
-
268
  if st.button("πŸ’Ύ Save Changes", key=f'save_button_{st.session_state.current_index}'):
269
  try:
270
  updated_doc = json.loads(doc_str)
@@ -279,24 +582,30 @@ def main():
279
  st.error(f"Invalid JSON: {str(e)} 🚫")
280
 
281
  elif selected_view == 'Show as Edit and Save':
 
282
  st.markdown("#### Edit the document fields below:")
 
 
283
  num_cols = len(documents_to_display)
284
  cols = st.columns(num_cols)
285
 
 
286
  for idx, (col, doc) in enumerate(zip(cols, documents_to_display)):
287
  with col:
288
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
289
  editable_id = st.text_input("ID", value=doc.get('id', ''), key=f'edit_id_{idx}')
 
290
  editable_doc = doc.copy()
291
  editable_doc.pop('id', None)
292
  doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300, key=f'doc_str_{idx}')
293
 
 
294
  col_save, col_ai = st.columns(2)
295
  with col_save:
296
  if st.button("πŸ’Ύ Save Changes", key=f'save_button_{idx}'):
297
  try:
298
  updated_doc = json.loads(doc_str)
299
- updated_doc['id'] = editable_id
300
  success, message = update_record(container, updated_doc)
301
  if success:
302
  st.success(f"Document {updated_doc['id']} saved successfully.")
@@ -308,20 +617,26 @@ def main():
308
  st.error(f"Invalid JSON: {str(e)} 🚫")
309
  with col_ai:
310
  if st.button("πŸ€– Run With AI", key=f'run_with_ai_button_{idx}'):
 
311
  search_glossary(json.dumps(editable_doc, indent=2))
 
 
312
 
 
 
313
  elif selected_view == 'Clone Document':
 
314
  st.markdown("#### Clone a document:")
315
  for idx, doc in enumerate(documents_to_display):
316
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
317
  if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
318
  cloned_doc = doc.copy()
 
319
  cloned_doc['id'] = generate_unique_id()
320
  st.session_state.cloned_doc = cloned_doc
321
  st.session_state.cloned_doc_str = json.dumps(cloned_doc, indent=2)
322
  st.session_state.clone_mode = True
323
  st.rerun()
324
-
325
  if st.session_state.get('clone_mode', False):
326
  st.markdown("#### Edit Cloned Document:")
327
  cloned_doc_str = st.text_area("Cloned Document Content (in JSON format)", value=st.session_state.cloned_doc_str, height=300)
@@ -340,8 +655,9 @@ def main():
340
  st.error(message)
341
  except json.JSONDecodeError as e:
342
  st.error(f"Invalid JSON: {str(e)} 🚫")
343
-
344
  elif selected_view == 'New Record':
 
345
  st.markdown("#### Create a new document:")
346
  if st.button("πŸ€– Insert Auto-Generated Record"):
347
  success, message = insert_auto_generated_record(container)
@@ -356,17 +672,18 @@ def main():
356
  if st.button("βž• Create New Document"):
357
  try:
358
  new_doc = json.loads(new_doc_str)
359
- new_doc['id'] = new_id
360
  success, message = insert_record(container, new_doc)
361
  if success:
362
  st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
363
  st.session_state.selected_document_id = new_doc['id']
 
364
  st.rerun()
365
  else:
366
  st.error(message)
367
  except json.JSONDecodeError as e:
368
  st.error(f"Invalid JSON: {str(e)} 🚫")
369
-
370
  else:
371
  st.sidebar.info("No documents found in this container. πŸ“­")
372
 
@@ -378,7 +695,7 @@ def main():
378
  st.dataframe(df)
379
  else:
380
  st.info("No documents to display. 🧐")
381
-
382
  # πŸ™ GitHub section
383
  st.subheader("πŸ™ GitHub Operations")
384
  github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
@@ -439,6 +756,237 @@ def main():
439
  st.session_state.selected_document_id = None
440
  st.session_state.current_index = 0
441
  st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
 
443
  if __name__ == "__main__":
444
  main()
 
25
  # 🏠 Your local app URL (Change this to your app's URL)
26
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  # πŸ€– OpenAI configuration
29
  # openai.api_key = os.environ.get("OPENAI_API_KEY")
30
  # MODEL = "gpt-3.5-turbo" # Replace with your desired model
31
 
32
+ # πŸ™ GitHub configuration
33
+ def download_github_repo(url, local_path):
34
+ # 🚚 Let's download that GitHub repo!
35
+ if os.path.exists(local_path):
36
+ shutil.rmtree(local_path)
37
+ Repo.clone_from(url, local_path)
38
+
39
+ def create_zip_file(source_dir, output_filename):
40
+ # πŸ“¦ Zipping up files like a pro!
41
+ shutil.make_archive(output_filename, 'zip', source_dir)
42
+
43
+ def create_repo(g, repo_name):
44
+ # πŸ› οΈ Creating a new GitHub repo. Magic!
45
+ user = g.get_user()
46
+ return user.create_repo(repo_name)
47
+
48
+ def push_to_github(local_path, repo, github_token):
49
+ # πŸš€ Pushing code to GitHub. Hold on tight!
50
+ repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
51
+ local_repo = Repo(local_path)
52
+
53
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
54
+ origin = local_repo.remote('origin')
55
+ origin.set_url(repo_url)
56
+ else:
57
+ origin = local_repo.create_remote('origin', repo_url)
58
+
59
+ if not local_repo.heads:
60
+ local_repo.git.checkout('-b', 'main')
61
+ current_branch = 'main'
62
+ else:
63
+ current_branch = local_repo.active_branch.name
64
+
65
+ local_repo.git.add(A=True)
66
+
67
+ if local_repo.is_dirty():
68
+ local_repo.git.commit('-m', 'Initial commit')
69
+
70
+ origin.push(refspec=f'{current_branch}:{current_branch}')
71
+
72
+ def get_base64_download_link(file_path, file_name):
73
+ # πŸ§™β€β™‚οΈ Generating a magical download link!
74
+ with open(file_path, "rb") as file:
75
+ contents = file.read()
76
+ base64_encoded = base64.b64encode(contents).decode()
77
+ return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">⬇️ Download {file_name}</a>'
78
+
79
+
80
+ # 🧭 New functions for dynamic sidebar navigation
81
+ def get_databases(client):
82
+ # πŸ“š Fetching list of databases. So many options!
83
+ return [db['id'] for db in client.list_databases()]
84
+
85
+ def get_containers(database):
86
+ # πŸ“‚ Getting containers. Containers within containers!
87
+ return [container['id'] for container in database.list_containers()]
88
+
89
+ def get_documents(container, limit=None):
90
+ # πŸ“ Retrieving documents. Shhh, don't tell anyone!
91
+ query = "SELECT * FROM c ORDER BY c._ts DESC"
92
+ items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
93
+ return items
94
+
95
+
96
  # 🌟 Cosmos DB functions
97
  def insert_record(container, record):
98
+ # πŸ“₯ Inserting a record into the Cosmosβ€”hope we don't disturb any aliens! πŸ‘½
99
  try:
100
  container.create_item(body=record)
 
101
  return True, "Record inserted successfully! πŸŽ‰"
102
  except exceptions.CosmosHttpResponseError as e:
 
103
  return False, f"HTTP error occurred: {str(e)} 🚨"
104
  except Exception as e:
 
105
  return False, f"An unexpected error occurred: {str(e)} 😱"
106
 
107
  def update_record(container, updated_record):
108
+ # πŸ”„ Updating a recordβ€”giving it a cosmic makeover! ✨
109
  try:
110
  container.upsert_item(body=updated_record)
 
111
  return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΈ"
112
  except exceptions.CosmosHttpResponseError as e:
 
113
  return False, f"HTTP error occurred: {str(e)} 🚨"
114
  except Exception as e:
 
115
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
116
 
117
  def delete_record(container, name, id):
118
+ # πŸ—‘οΈ Deleting a recordβ€”sending it into the cosmic void! 🌌
119
  try:
120
  container.delete_item(item=id, partition_key=id)
 
121
  return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
122
  except exceptions.CosmosResourceNotFoundError:
 
123
  return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
124
  except exceptions.CosmosHttpResponseError as e:
 
125
  return False, f"HTTP error occurred: {str(e)} 🚨"
126
  except Exception as e:
 
127
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
128
 
129
  # 🎲 Function to generate a unique UUID
130
+ def generate_unique_id():
131
+ # πŸ§™β€β™‚οΈ Generating a unique UUID!
132
+ return str(uuid.uuid4())
133
+
134
+ # πŸ“¦ Function to archive current container
135
+ def archive_current_container(database_name, container_name, client):
136
+ # πŸ“¦ Archiving the entire containerβ€”time to pack up the stars! 🌠
137
+ try:
138
+ base_dir = "./cosmos_archive_current_container"
139
+ if os.path.exists(base_dir):
140
+ shutil.rmtree(base_dir)
141
+ os.makedirs(base_dir)
142
+
143
+ db_client = client.get_database_client(database_name)
144
+ container_client = db_client.get_container_client(container_name)
145
+ items = list(container_client.read_all_items())
146
+
147
+ container_dir = os.path.join(base_dir, container_name)
148
+ os.makedirs(container_dir)
149
+
150
+ for item in items:
151
+ item_id = item.get('id', f"unknown_{datetime.now().strftime('%Y%m%d%H%M%S')}")
152
+ with open(os.path.join(container_dir, f"{item_id}.json"), 'w') as f:
153
+ json.dump(item, f, indent=2)
154
+
155
+ archive_name = f"{container_name}_archive_{datetime.now().strftime('%Y%m%d%H%M%S')}"
156
+ shutil.make_archive(archive_name, 'zip', base_dir)
157
+
158
+ return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
159
+ except Exception as e:
160
+ return f"An error occurred while archiving data: {str(e)} 😒"
161
+
162
+
163
+ # πŸ”— Helper to extract hyperlinks
164
+ def extract_hyperlinks(responses):
165
+ # πŸ”— Extracting hyperlinksβ€”connecting the dots across the universe! πŸ•ΈοΈ
166
+ hyperlinks = []
167
+ for response in responses:
168
+ parsed_response = json.loads(response)
169
+ links = [value for key, value in parsed_response.items() if isinstance(value, str) and value.startswith("http")]
170
+ hyperlinks.extend(links)
171
+ return hyperlinks
172
+
173
+ # πŸ“‹ Helper to format text with line numbers
174
+ def format_with_line_numbers(text):
175
+ # πŸ“‹ Formatting text with line numbersβ€”organizing the cosmos one line at a time! πŸ“
176
+ lines = text.splitlines()
177
+ formatted_text = '\n'.join(f"{i+1}: {line}" for i, line in enumerate(lines))
178
+ return formatted_text
179
+
180
+
181
  def generate_unique_id():
182
  return str(uuid.uuid4())
183
 
 
204
  try:
205
  container.create_item(body=record)
206
  st.success(f"Record saved successfully with ID: {record['id']}")
 
207
  # Refresh the documents display
208
  st.session_state.documents = get_documents(container)
209
  except exceptions.CosmosHttpResponseError as e:
210
  st.error(f"Error saving record to Cosmos DB: {e}")
 
211
  else:
212
  st.error("Cosmos DB container is not initialized.")
 
213
  except Exception as e:
214
  st.error(f"An unexpected error occurred: {str(e)}")
215
+
216
+ # Add dropdowns for model and database choices
217
+ def search_glossary(query):
218
+ st.markdown(f"### πŸ” Search Glossary for: `{query}`")
219
+
220
+ # Dropdown for model selection
221
+ model_options = ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None']
222
+ model_choice = st.selectbox('🧠 Select LLM Model', options=model_options, index=1)
223
+
224
+ # Dropdown for database selection
225
+ database_options = ['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)']
226
+ database_choice = st.selectbox('πŸ“š Select Database', options=database_options, index=0)
227
+
228
+
229
+
230
+ # Run Button with Emoji
231
+ #if st.button("πŸš€ Run"):
232
+
233
+ # πŸ•΅οΈβ€β™‚οΈ Searching the glossary for: query
234
+ all_results = ""
235
+ st.markdown(f"- {query}")
236
+
237
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM
238
+ #database_choice Literal['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)'] Default: "Semantic Search"
239
+ #llm_model_picked Literal['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None'] Default: "mistralai/Mistral-7B-Instruct-v0.2"
240
+ client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
241
+
242
+
243
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
244
+ result = client.predict(
245
+ prompt=query,
246
+ llm_model_picked="mistralai/Mixtral-8x7B-Instruct-v0.1",
247
+ stream_outputs=True,
248
+ api_name="/ask_llm"
249
+ )
250
+ st.markdown(result)
251
+ st.code(result, language="python", line_numbers=True)
252
+
253
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
254
+ result2 = client.predict(
255
+ prompt=query,
256
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
257
+ stream_outputs=True,
258
+ api_name="/ask_llm"
259
+ )
260
+ st.markdown(result2)
261
+ st.code(result2, language="python", line_numbers=True)
262
+
263
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
264
+ result3 = client.predict(
265
+ prompt=query,
266
+ llm_model_picked="google/gemma-7b-it",
267
+ stream_outputs=True,
268
+ api_name="/ask_llm"
269
+ )
270
+ st.markdown(result3)
271
+ st.code(result3, language="python", line_numbers=True)
272
+
273
+
274
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /update_with_rag_md
275
+ response2 = client.predict(
276
+ message=query, # str in 'parameter_13' Textbox component
277
+ llm_results_use=10,
278
+ database_choice="Semantic Search",
279
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
280
+ api_name="/update_with_rag_md"
281
+ ) # update_with_rag_md Returns tuple of 2 elements [0] str The output value that appears in the "value_14" Markdown component. [1] str
282
+
283
+ st.markdown(response2[0])
284
+ st.code(response2[0], language="python", line_numbers=True, wrap_lines=True)
285
+
286
+ st.markdown(response2[1])
287
+ st.code(response2[1], language="python", line_numbers=True, wrap_lines=True)
288
+
289
+ # When saving results, pass the container
290
+ try:
291
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result, result)
292
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result2, result2)
293
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result3, result3)
294
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[0], response2[0])
295
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[1], response2[1])
296
+ except exceptions.CosmosHttpResponseError as e:
297
+ return False, f"HTTP error occurred: {str(e)} 🚨"
298
+ except Exception as e:
299
+ return False, f"An unexpected error occurred: {str(e)} 😱"
300
+
301
+
302
+ try:
303
+ # Aggregate hyperlinks and show with emojis
304
+ hyperlinks = extract_hyperlinks([response1, response2])
305
+ st.markdown("### πŸ”— Aggregated Hyperlinks")
306
+ for link in hyperlinks:
307
+ st.markdown(f"πŸ”— [{link}]({link})")
308
+
309
+ # Show responses in a code format with line numbers
310
+ st.markdown("### πŸ“œ Response Outputs with Line Numbers")
311
+ st.code(f"Response 1: \n{format_with_line_numbers(response1)}\n\nResponse 2: \n{format_with_line_numbers(response2)}", language="json")
312
+ except exceptions.CosmosHttpResponseError as e:
313
+ return False, f"HTTP error occurred: {str(e)} 🚨"
314
+ except Exception as e:
315
+ return False, f"An unexpected error occurred: {str(e)} 😱"
316
+
317
+
318
+
319
 
320
  # 🎀 Function to process text input
321
  def process_text(text_input):
322
+ # 🎀 Processing text inputβ€”translating human words into cosmic signals! πŸ“‘
323
  if text_input:
324
  if 'messages' not in st.session_state:
325
  st.session_state.messages = []
 
332
  with st.chat_message("assistant"):
333
  search_glossary(text_input)
334
 
335
+ # πŸ“ Function to generate a filename
336
+ def generate_filename(text, file_type):
337
+ # πŸ“ Generate a filename based on the text input
338
+ safe_text = "".join(c if c.isalnum() or c in (' ', '.', '_') else '_' for c in text)
339
+ safe_text = "_".join(safe_text.strip().split())
340
+ filename = f"{safe_text}.{file_type}"
341
+ return filename
342
+
343
+ # πŸ•΅οΈβ€β™€οΈ Function to extract markdown title
344
+ def extract_markdown_title(content):
345
+ # πŸ•΅οΈβ€β™€οΈ Extracting markdown titleβ€”finding the headline in the cosmic news! πŸ“°
346
+ lines = content.splitlines()
347
+ for line in lines:
348
+ if line.startswith('#'):
349
+ return line.lstrip('#').strip()
350
+ return None
351
+
352
+ # πŸ’Ύ Function to create and save a file
353
+ def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
354
+ # πŸ’Ύ Creating and saving a fileβ€”capturing cosmic wisdom! πŸ“
355
+ if not should_save:
356
+ return None
357
+
358
+ # Step 1: Generate filename based on the prompt or content
359
+ filename = generate_filename(prompt if prompt else content, file_type)
360
+
361
+ # Step 2: If it's a markdown file, check if it has a title
362
+ if file_type == "md":
363
+ title_from_content = extract_markdown_title(content)
364
+ if title_from_content:
365
+ filename = generate_filename(title_from_content, file_type)
366
+
367
+ # Step 3: Save the file
368
+ with open(filename, "w", encoding="utf-8") as f:
369
+ if is_image:
370
+ f.write(content)
371
+ else:
372
+ f.write(prompt + "\n\n" + content)
373
+
374
+ return filename
375
+
376
+ # πŸ€– Function to insert an auto-generated record
377
+ def insert_auto_generated_record(container):
378
+ # πŸ€– Automatically generating a record and inserting it into Cosmos DB!
379
+ try:
380
+ # Generate a unique id
381
+ new_id = generate_unique_id()
382
+ # Create a sample JSON document
383
+ new_doc = {
384
+ 'id': new_id,
385
+ 'name': f'Sample Name {new_id[:8]}',
386
+ 'description': 'This is a sample auto-generated description.',
387
+ 'timestamp': datetime.utcnow().isoformat()
388
+ }
389
+ # Insert the document
390
+ container.create_item(body=new_doc)
391
+ return True, f"Record inserted successfully with id: {new_id} πŸŽ‰"
392
+ except exceptions.CosmosHttpResponseError as e:
393
+ return False, f"HTTP error occurred: {str(e)} 🚨"
394
+ except Exception as e:
395
+ return False, f"An unexpected error occurred: {str(e)} 😱"
396
+
397
  # 🎈 Main function
398
  def main():
399
+ # 🎈 Let's modify the main app to be more fun!
400
  st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
401
 
402
+ # 🚦 Initialize session state
403
  if 'logged_in' not in st.session_state:
404
  st.session_state.logged_in = False
405
  if 'selected_records' not in st.session_state:
 
417
  if 'cloned_doc' not in st.session_state:
418
  st.session_state.cloned_doc = None
419
 
420
+ # βš™οΈ q= Run ArXiv search from query parameters
421
  try:
422
  query_params = st.query_params
423
  query = query_params.get('q') or query_params.get('query') or ''
424
  if query:
425
+ # πŸ•΅οΈβ€β™‚οΈ We have a query! Let's process it!
426
  process_text(query)
427
+ st.stop() # Stop further execution
428
  except Exception as e:
429
  st.markdown(' ')
430
+
431
  # πŸ” Automatic Login
432
  if Key:
433
  st.session_state.primary_key = Key
434
  st.session_state.logged_in = True
435
  else:
436
  st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
437
+ return # Can't proceed without a key
438
 
439
  if st.session_state.logged_in:
440
  # 🌌 Initialize Cosmos DB client
 
442
  if st.session_state.client is None:
443
  st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
444
 
445
+ # πŸ—„οΈ Sidebar for database, container, and document selection
446
  st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
447
+
448
  databases = get_databases(st.session_state.client)
449
  selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
450
 
 
494
  selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
495
 
496
  if selected_view == 'Show as Markdown':
497
+ # πŸ–ŒοΈ Show each record as Markdown with navigation
498
+ total_docs = len(documents)
499
  doc = documents[st.session_state.current_index]
500
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
501
+
502
+ # πŸ•΅οΈβ€β™‚οΈ Let's extract values from the JSON that have at least one space
503
+ values_with_space = []
504
+ def extract_values(obj):
505
+ if isinstance(obj, dict):
506
+ for k, v in obj.items():
507
+ extract_values(v)
508
+ elif isinstance(obj, list):
509
+ for item in obj:
510
+ extract_values(item)
511
+ elif isinstance(obj, str):
512
+ if ' ' in obj:
513
+ values_with_space.append(obj)
514
+
515
+ extract_values(doc)
516
+
517
+ # πŸ”— Let's create a list of links for these values
518
+ search_urls = {
519
+ "πŸš€πŸŒŒArXiv": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}",
520
+ "πŸƒAnalyst": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix')}",
521
+ "πŸ“šPyCoder": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix2')}",
522
+ "πŸ”¬JSCoder": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix3')}",
523
+ "🏠": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}",
524
+ "πŸ“–": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
525
+ "πŸ”": lambda k: f"https://www.google.com/search?q={quote(k)}",
526
+ "▢️": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
527
+ "πŸ”Ž": lambda k: f"https://www.bing.com/search?q={quote(k)}",
528
+ "πŸŽ₯": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
529
+ "🐦": lambda k: f"https://twitter.com/search?q={quote(k)}",
530
+ }
531
+
532
+ st.markdown("#### πŸ”— Links for Extracted Texts")
533
+ for term in values_with_space:
534
+ links_md = ' '.join([f"[{emoji}]({url(term)})" for emoji, url in search_urls.items()])
535
+ st.markdown(f"**{term}** <small>{links_md}</small>", unsafe_allow_html=True)
536
+
537
+ # Show the document content as markdown
538
  content = json.dumps(doc, indent=2)
539
  st.markdown(f"```json\n{content}\n```")
540
 
541
+ # Navigation buttons
542
  col_prev, col_next = st.columns([1, 1])
543
  with col_prev:
544
  if st.button("⬅️ Previous", key='prev_markdown'):
 
552
  st.rerun()
553
 
554
  elif selected_view == 'Show as Code Editor':
555
+ # πŸ’» Show each record in a code editor with navigation
556
+ total_docs = len(documents)
557
  doc = documents[st.session_state.current_index]
558
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
559
  doc_str = st.text_area("Edit Document", value=json.dumps(doc, indent=2), height=300, key=f'code_editor_{st.session_state.current_index}')
 
560
  col_prev, col_next = st.columns([1, 1])
561
  with col_prev:
562
  if st.button("⬅️ Previous", key='prev_code'):
 
568
  if st.session_state.current_index < total_docs - 1:
569
  st.session_state.current_index += 1
570
  st.rerun()
 
571
  if st.button("πŸ’Ύ Save Changes", key=f'save_button_{st.session_state.current_index}'):
572
  try:
573
  updated_doc = json.loads(doc_str)
 
582
  st.error(f"Invalid JSON: {str(e)} 🚫")
583
 
584
  elif selected_view == 'Show as Edit and Save':
585
+ # ✏️ Show as Edit and Save in columns
586
  st.markdown("#### Edit the document fields below:")
587
+
588
+ # Create columns for each document
589
  num_cols = len(documents_to_display)
590
  cols = st.columns(num_cols)
591
 
592
+
593
  for idx, (col, doc) in enumerate(zip(cols, documents_to_display)):
594
  with col:
595
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
596
  editable_id = st.text_input("ID", value=doc.get('id', ''), key=f'edit_id_{idx}')
597
+ # Remove 'id' from the document for editing other fields
598
  editable_doc = doc.copy()
599
  editable_doc.pop('id', None)
600
  doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300, key=f'doc_str_{idx}')
601
 
602
+ # Add the "Run With AI" button next to "Save Changes"
603
  col_save, col_ai = st.columns(2)
604
  with col_save:
605
  if st.button("πŸ’Ύ Save Changes", key=f'save_button_{idx}'):
606
  try:
607
  updated_doc = json.loads(doc_str)
608
+ updated_doc['id'] = editable_id # Include the possibly edited ID
609
  success, message = update_record(container, updated_doc)
610
  if success:
611
  st.success(f"Document {updated_doc['id']} saved successfully.")
 
617
  st.error(f"Invalid JSON: {str(e)} 🚫")
618
  with col_ai:
619
  if st.button("πŸ€– Run With AI", key=f'run_with_ai_button_{idx}'):
620
+ # Use the entire document as input
621
  search_glossary(json.dumps(editable_doc, indent=2))
622
+
623
+
624
 
625
+
626
+
627
  elif selected_view == 'Clone Document':
628
+ # 🧬 Clone Document per record
629
  st.markdown("#### Clone a document:")
630
  for idx, doc in enumerate(documents_to_display):
631
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
632
  if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
633
  cloned_doc = doc.copy()
634
+ # Generate a unique ID
635
  cloned_doc['id'] = generate_unique_id()
636
  st.session_state.cloned_doc = cloned_doc
637
  st.session_state.cloned_doc_str = json.dumps(cloned_doc, indent=2)
638
  st.session_state.clone_mode = True
639
  st.rerun()
 
640
  if st.session_state.get('clone_mode', False):
641
  st.markdown("#### Edit Cloned Document:")
642
  cloned_doc_str = st.text_area("Cloned Document Content (in JSON format)", value=st.session_state.cloned_doc_str, height=300)
 
655
  st.error(message)
656
  except json.JSONDecodeError as e:
657
  st.error(f"Invalid JSON: {str(e)} 🚫")
658
+
659
  elif selected_view == 'New Record':
660
+ # πŸ†• New Record
661
  st.markdown("#### Create a new document:")
662
  if st.button("πŸ€– Insert Auto-Generated Record"):
663
  success, message = insert_auto_generated_record(container)
 
672
  if st.button("βž• Create New Document"):
673
  try:
674
  new_doc = json.loads(new_doc_str)
675
+ new_doc['id'] = new_id # Use the provided ID
676
  success, message = insert_record(container, new_doc)
677
  if success:
678
  st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
679
  st.session_state.selected_document_id = new_doc['id']
680
+ # Switch to 'Show as Edit and Save' mode
681
  st.rerun()
682
  else:
683
  st.error(message)
684
  except json.JSONDecodeError as e:
685
  st.error(f"Invalid JSON: {str(e)} 🚫")
686
+
687
  else:
688
  st.sidebar.info("No documents found in this container. πŸ“­")
689
 
 
695
  st.dataframe(df)
696
  else:
697
  st.info("No documents to display. 🧐")
698
+
699
  # πŸ™ GitHub section
700
  st.subheader("πŸ™ GitHub Operations")
701
  github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
 
756
  st.session_state.selected_document_id = None
757
  st.session_state.current_index = 0
758
  st.rerun()
759
+
760
+
761
+
762
+
763
+
764
+
765
+
766
+ # Set up the Anthropic client
767
+ client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
768
+
769
+ # Initialize session state
770
+ if "chat_history" not in st.session_state:
771
+ st.session_state.chat_history = []
772
+
773
+ # Helper Functions: All Your Essentials πŸš€
774
+
775
+ # Function to get a file download link (because you deserve easy downloads 😎)
776
+ def get_download_link(file_path):
777
+ with open(file_path, "rb") as file:
778
+ contents = file.read()
779
+ b64 = base64.b64encode(contents).decode()
780
+ file_name = os.path.basename(file_path)
781
+ return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}πŸ“‚</a>'
782
+
783
+ # Function to generate a filename based on prompt and time (because names matter πŸ•’)
784
+ def generate_filename(prompt, file_type):
785
+ central = pytz.timezone('US/Central')
786
+ safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
787
+ safe_prompt = re.sub(r'\W+', '_', prompt)[:90]
788
+ return f"{safe_date_time}_{safe_prompt}.{file_type}"
789
+
790
+ # Function to create and save a file (and avoid the black hole of lost data πŸ•³)
791
+ def create_file(filename, prompt, response, should_save=True):
792
+ if not should_save:
793
+ return
794
+ with open(filename, 'w', encoding='utf-8') as file:
795
+ file.write(prompt + "\n\n" + response)
796
+
797
+ # Function to load file content (for revisiting the past πŸ“œ)
798
+ def load_file(file_name):
799
+ with open(file_name, "r", encoding='utf-8') as file:
800
+ content = file.read()
801
+ return content
802
+
803
+ # Function to display handy glossary entity links (search like a pro πŸ”)
804
+ def display_glossary_entity(k):
805
+ search_urls = {
806
+ "πŸš€πŸŒŒArXiv": lambda k: f"/?q={quote(k)}",
807
+ "πŸ“–": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
808
+ "πŸ”": lambda k: f"https://www.google.com/search?q={quote(k)}",
809
+ "πŸŽ₯": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
810
+ }
811
+ links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()])
812
+ st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True)
813
+
814
+ # Function to create zip of files (because more is more 🧳)
815
+ def create_zip_of_files(files):
816
+ import zipfile
817
+ zip_name = "all_files.zip"
818
+ with zipfile.ZipFile(zip_name, 'w') as zipf:
819
+ for file in files:
820
+ zipf.write(file)
821
+ return zip_name
822
+
823
+ # Function to create HTML for autoplaying and looping video (for the full cinematic effect πŸŽ₯)
824
+ def get_video_html(video_path, width="100%"):
825
+ video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
826
+ return f'''
827
+ <video width="{width}" controls autoplay muted loop>
828
+ <source src="{video_url}" type="video/mp4">
829
+ Your browser does not support the video tag.
830
+ </video>
831
+ '''
832
+
833
+ # Function to create HTML for audio player (when life needs a soundtrack 🎢)
834
+ def get_audio_html(audio_path, width="100%"):
835
+ audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}"
836
+ return f'''
837
+ <audio controls style="width: {width};">
838
+ <source src="{audio_url}" type="audio/mpeg">
839
+ Your browser does not support the audio element.
840
+ </audio>
841
+ '''
842
+
843
+
844
+ # Streamlit App Layout (like a house with better flow 🏑)
845
+ def main():
846
+
847
+ # Sidebar with Useful Controls (All the VIP actions πŸŽ›)
848
+ st.sidebar.title("🧠ClaudeπŸ“")
849
+
850
+ all_files = glob.glob("*.md")
851
+ all_files.sort(reverse=True)
852
+
853
+ if st.sidebar.button("πŸ—‘ Delete All"):
854
+ for file in all_files:
855
+ os.remove(file)
856
+ st.rerun()
857
+
858
+ if st.sidebar.button("⬇️ Download All"):
859
+ zip_file = create_zip_of_files(all_files)
860
+ st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
861
+
862
+ for file in all_files:
863
+ col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
864
+ with col1:
865
+ if st.button("🌐", key="view_"+file):
866
+ st.session_state.current_file = file
867
+ st.session_state.file_content = load_file(file)
868
+ with col2:
869
+ st.markdown(get_download_link(file), unsafe_allow_html=True)
870
+ with col3:
871
+ if st.button("πŸ“‚", key="edit_"+file):
872
+ st.session_state.current_file = file
873
+ st.session_state.file_content = load_file(file)
874
+ with col4:
875
+ if st.button("πŸ—‘", key="delete_"+file):
876
+ os.remove(file)
877
+ st.rerun()
878
+
879
+ # Main Area: Chat with Claude (He’s a good listener πŸ’¬)
880
+ user_input = st.text_area("Message πŸ“¨:", height=100)
881
+
882
+ if st.button("Send πŸ“¨"):
883
+ if user_input:
884
+ response = client.messages.create(
885
+ model="claude-3-sonnet-20240229",
886
+ max_tokens=1000,
887
+ messages=[
888
+ {"role": "user", "content": user_input}
889
+ ]
890
+ )
891
+ st.write("Claude's reply 🧠:")
892
+ st.write(response.content[0].text)
893
+
894
+ filename = generate_filename(user_input, "md")
895
+ create_file(filename, user_input, response.content[0].text)
896
+
897
+ st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
898
+
899
+ # Display Chat History (Never forget a good chat πŸ’­)
900
+ st.subheader("Past Conversations πŸ“œ")
901
+ for chat in st.session_state.chat_history:
902
+ st.text_area("You said πŸ’¬:", chat["user"], height=100, disabled=True)
903
+ st.text_area("Claude replied πŸ€–:", chat["claude"], height=200, disabled=True)
904
+ st.markdown("---")
905
+
906
+ # File Editor (When you need to tweak things ✏️)
907
+ if hasattr(st.session_state, 'current_file'):
908
+ st.subheader(f"Editing: {st.session_state.current_file} πŸ› ")
909
+ new_content = st.text_area("File Content ✏️:", st.session_state.file_content, height=300)
910
+ if st.button("Save Changes πŸ’Ύ"):
911
+ with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
912
+ file.write(new_content)
913
+ st.success("File updated successfully! πŸŽ‰")
914
+
915
+ # Image Gallery (For your viewing pleasure πŸ“Έ)
916
+ st.subheader("Image Gallery πŸ–Ό")
917
+ image_files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg")
918
+ image_cols = st.slider("Gallery Columns πŸ–Ό", min_value=1, max_value=15, value=5)
919
+ cols = st.columns(image_cols)
920
+ for idx, image_file in enumerate(image_files):
921
+ with cols[idx % image_cols]:
922
+ img = Image.open(image_file)
923
+ #st.image(img, caption=image_file, use_column_width=True)
924
+ st.image(img, use_column_width=True)
925
+ display_glossary_entity(os.path.splitext(image_file)[0])
926
+
927
+ # Video Gallery (Let’s roll the tapes 🎬)
928
+ st.subheader("Video Gallery πŸŽ₯")
929
+ video_files = glob.glob("*.mp4")
930
+ video_cols = st.slider("Gallery Columns 🎬", min_value=1, max_value=5, value=3)
931
+ cols = st.columns(video_cols)
932
+ for idx, video_file in enumerate(video_files):
933
+ with cols[idx % video_cols]:
934
+ st.markdown(get_video_html(video_file, width="100%"), unsafe_allow_html=True)
935
+ display_glossary_entity(os.path.splitext(video_file)[0])
936
+
937
+ # Audio Gallery (Tunes for the mood 🎢)
938
+ st.subheader("Audio Gallery 🎧")
939
+ audio_files = glob.glob("*.mp3") + glob.glob("*.wav")
940
+ audio_cols = st.slider("Gallery Columns 🎢", min_value=1, max_value=15, value=5)
941
+ cols = st.columns(audio_cols)
942
+ for idx, audio_file in enumerate(audio_files):
943
+ with cols[idx % audio_cols]:
944
+ st.markdown(get_audio_html(audio_file, width="100%"), unsafe_allow_html=True)
945
+ display_glossary_entity(os.path.splitext(audio_file)[0])
946
+
947
+ if __name__ == "__main__":
948
+ main()
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+
967
+
968
+
969
+
970
+
971
+
972
+
973
+
974
+
975
+
976
+
977
+
978
+
979
+
980
+
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
 
991
  if __name__ == "__main__":
992
  main()