awacke1 commited on
Commit
79206fa
β€’
1 Parent(s): f40e60a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +177 -263
app.py CHANGED
@@ -18,9 +18,10 @@ import pytz
18
  import re
19
  from PIL import Image
20
  import zipfile
 
21
  import time
22
 
23
- # App Configuration
24
  Site_Name = 'πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent'
25
  title = "πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent"
26
  helpURL = 'https://huggingface.co/awacke1'
@@ -39,23 +40,25 @@ st.set_page_config(
39
  }
40
  )
41
 
42
- # Cosmos DB configuration
43
  ENDPOINT = "https://acae-afd.documents.azure.com:443/"
44
  DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
45
  CONTAINER_NAME = os.environ.get("COSMOS_CONTAINER_NAME")
46
  Key = os.environ.get("Key")
47
 
48
- # Your local app URL (Change this to your app's URL)
49
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
50
 
51
- # Anthropic configuration
52
  client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
53
 
54
- # Initialize session state
55
  if "chat_history" not in st.session_state:
56
  st.session_state.chat_history = []
57
 
58
- # Helper Functions
 
 
59
  def get_download_link(file_path):
60
  with open(file_path, "rb") as file:
61
  contents = file.read()
@@ -63,30 +66,33 @@ def get_download_link(file_path):
63
  file_name = os.path.basename(file_path)
64
  return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}πŸ“‚</a>'
65
 
 
66
  def generate_unique_id():
67
- now = datetime.now()
68
- date_time = now.strftime("%d%m%Y%H%M%S")
69
- ms = now.microsecond // 1000
70
- unique_id = f"{date_time}{ms:03d}"
71
- return unique_id
72
 
 
73
  def generate_filename(prompt, file_type):
74
  central = pytz.timezone('US/Central')
75
  safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
76
  safe_prompt = re.sub(r'\W+', '', prompt)[:90]
77
  return f"{safe_date_time}{safe_prompt}.{file_type}"
78
 
 
79
  def create_file(filename, prompt, response, should_save=True):
80
  if not should_save:
81
  return
82
  with open(filename, 'w', encoding='utf-8') as file:
83
  file.write(prompt + "\n\n" + response)
84
 
 
85
  def load_file(file_name):
86
  with open(file_name, "r", encoding='utf-8') as file:
87
  content = file.read()
88
  return content
89
 
 
90
  def display_glossary_entity(k):
91
  search_urls = {
92
  "πŸš€πŸŒŒArXiv": lambda k: f"/?q={quote(k)}",
@@ -97,6 +103,7 @@ def display_glossary_entity(k):
97
  links_md = ' '.join([f"<a href='{url(k)}' target='_blank'>{emoji}</a>" for emoji, url in search_urls.items()])
98
  st.markdown(f"{k} {links_md}", unsafe_allow_html=True)
99
 
 
100
  def create_zip_of_files(files):
101
  zip_name = "all_files.zip"
102
  with zipfile.ZipFile(zip_name, 'w') as zipf:
@@ -104,6 +111,7 @@ def create_zip_of_files(files):
104
  zipf.write(file)
105
  return zip_name
106
 
 
107
  def get_video_html(video_path, width="100%"):
108
  video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
109
  return f'''
@@ -113,6 +121,7 @@ def get_video_html(video_path, width="100%"):
113
  </video>
114
  '''
115
 
 
116
  def get_audio_html(audio_path, width="100%"):
117
  audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}"
118
  return f'''
@@ -122,18 +131,23 @@ def get_audio_html(audio_path, width="100%"):
122
  </audio>
123
  '''
124
 
125
- # Cosmos DB functions
 
 
126
  def get_databases(client):
127
  return [db['id'] for db in client.list_databases()]
128
 
 
129
  def get_containers(database):
130
  return [container['id'] for container in database.list_containers()]
131
 
 
132
  def get_documents(container, limit=None):
133
  query = "SELECT * FROM c ORDER BY c._ts DESC"
134
  items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
135
  return items
136
 
 
137
  def insert_record(container, record):
138
  try:
139
  container.create_item(body=record)
@@ -143,6 +157,7 @@ def insert_record(container, record):
143
  except Exception as e:
144
  return False, f"An unexpected error occurred: {str(e)} 😱"
145
 
 
146
  def update_record(container, updated_record):
147
  try:
148
  container.upsert_item(body=updated_record)
@@ -152,6 +167,7 @@ def update_record(container, updated_record):
152
  except Exception as e:
153
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
154
 
 
155
  def delete_record(container, name, id):
156
  try:
157
  container.delete_item(item=id, partition_key=id)
@@ -163,11 +179,71 @@ def delete_record(container, name, id):
163
  except Exception as e:
164
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
165
 
166
- import uuid
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
- def generate_unique_id():
169
- return str(uuid.uuid4())
170
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  def save_or_clone_to_cosmos_db(container, query=None, response=None, clone_id=None):
172
  try:
173
  if not container:
@@ -216,34 +292,52 @@ def save_or_clone_to_cosmos_db(container, query=None, response=None, clone_id=No
216
  except Exception as e:
217
  st.error(f"An unexpected error occurred: {str(e)}")
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
- # Add dropdowns for model and database choices
221
  def search_glossary(query):
222
- st.markdown(f"### πŸ” Search Glossary for: `{query}`")
223
-
224
  # Dropdown for model selection
225
  model_options = ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None']
226
  model_choice = st.selectbox('🧠 Select LLM Model', options=model_options, index=1)
227
-
228
  # Dropdown for database selection
229
  database_options = ['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)']
230
  database_choice = st.selectbox('πŸ“š Select Database', options=database_options, index=0)
231
 
232
-
233
-
234
- # Run Button with Emoji
235
- #if st.button("πŸš€ Run"):
236
-
237
  # πŸ•΅οΈβ€β™‚οΈ Searching the glossary for: query
238
  all_results = ""
239
  st.markdown(f"- {query}")
240
 
241
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM
242
- #database_choice Literal['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)'] Default: "Semantic Search"
243
- #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"
244
  client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
245
 
246
-
247
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
248
  result = client.predict(
249
  prompt=query,
@@ -253,7 +347,7 @@ def search_glossary(query):
253
  )
254
  st.markdown(result)
255
  st.code(result, language="python", line_numbers=True)
256
-
257
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
258
  result2 = client.predict(
259
  prompt=query,
@@ -274,7 +368,6 @@ def search_glossary(query):
274
  st.markdown(result3)
275
  st.code(result3, language="python", line_numbers=True)
276
 
277
-
278
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /update_with_rag_md
279
  response2 = client.predict(
280
  message=query, # str in 'parameter_13' Textbox component
@@ -282,173 +375,25 @@ def search_glossary(query):
282
  database_choice="Semantic Search",
283
  llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
284
  api_name="/update_with_rag_md"
285
- ) # update_with_rag_md Returns tuple of 2 elements [0] str The output value that appears in the "value_14" Markdown component. [1] str
286
 
287
  st.markdown(response2[0])
288
  st.code(response2[0], language="python", line_numbers=True, wrap_lines=True)
289
-
290
  st.markdown(response2[1])
291
  st.code(response2[1], language="python", line_numbers=True, wrap_lines=True)
292
 
293
- # When saving results, pass the container
294
- try:
295
- #save_to_cosmos_db(st.session_state.cosmos_container, query, result, result)
296
- #save_to_cosmos_db(st.session_state.cosmos_container, query, result2, result2)
297
- #save_to_cosmos_db(st.session_state.cosmos_container, query, result3, result3)
298
- #save_to_cosmos_db(st.session_state.cosmos_container, query, response2[0], response2[0])
299
- #save_to_cosmos_db(st.session_state.cosmos_container, query, response2[1], response2[1])
300
-
301
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=query, response=result, clone_id=None)
302
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=query, response=result2, clone_id=None)
303
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=query, response=result3, clone_id=None)
304
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=query, response=response2[0], clone_id=None)
305
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=query, response=response2[1], clone_id=None)
306
-
307
-
308
-
309
- except exceptions.CosmosHttpResponseError as e:
310
- return False, f"HTTP error occurred: {str(e)} 🚨"
311
- except Exception as e:
312
- return False, f"An unexpected error occurred: {str(e)} 😱"
313
-
314
-
315
- try:
316
- # Aggregate hyperlinks and show with emojis
317
- hyperlinks = extract_hyperlinks([response1, response2])
318
- st.markdown("### πŸ”— Aggregated Hyperlinks")
319
- for link in hyperlinks:
320
- st.markdown(f"πŸ”— [{link}]({link})")
321
-
322
- # Show responses in a code format with line numbers
323
- st.markdown("### πŸ“œ Response Outputs with Line Numbers")
324
- st.code(f"Response 1: \n{format_with_line_numbers(response1)}\n\nResponse 2: \n{format_with_line_numbers(response2)}", language="json")
325
- except exceptions.CosmosHttpResponseError as e:
326
- return False, f"HTTP error occurred: {str(e)} 🚨"
327
- except Exception as e:
328
- return False, f"An unexpected error occurred: {str(e)} 😱"
329
-
330
-
331
-
332
- # 🎀 Function to process text input
333
- def process_text(text_input):
334
- # 🎀 Processing text inputβ€”translating human words into cosmic signals! πŸ“‘
335
- if text_input:
336
- if 'messages' not in st.session_state:
337
- st.session_state.messages = []
338
-
339
- st.session_state.messages.append({"role": "user", "content": text_input})
340
-
341
- with st.chat_message("user"):
342
- st.markdown(text_input)
343
-
344
- with st.chat_message("assistant"):
345
- search_glossary(text_input)
346
-
347
- # πŸ“ Function to generate a filename
348
- def generate_filename(text, file_type):
349
- # πŸ“ Generate a filename based on the text input
350
- safe_text = "".join(c if c.isalnum() or c in (' ', '.', '_') else '_' for c in text)
351
- safe_text = "_".join(safe_text.strip().split())
352
- filename = f"{safe_text}.{file_type}"
353
- return filename
354
-
355
- # πŸ•΅οΈβ€β™€οΈ Function to extract markdown title
356
- def extract_markdown_title(content):
357
- # πŸ•΅οΈβ€β™€οΈ Extracting markdown titleβ€”finding the headline in the cosmic news! πŸ“°
358
- lines = content.splitlines()
359
- for line in lines:
360
- if line.startswith('#'):
361
- return line.lstrip('#').strip()
362
- return None
363
-
364
- # πŸ’Ύ Function to create and save a file
365
- def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
366
- # πŸ’Ύ Creating and saving a fileβ€”capturing cosmic wisdom! πŸ“
367
- if not should_save:
368
- return None
369
-
370
- # Step 1: Generate filename based on the prompt or content
371
- filename = generate_filename(prompt if prompt else content, file_type)
372
 
373
- # Step 2: If it's a markdown file, check if it has a title
374
- if file_type == "md":
375
- title_from_content = extract_markdown_title(content)
376
- if title_from_content:
377
- filename = generate_filename(title_from_content, file_type)
378
-
379
- # Step 3: Save the file
380
- with open(filename, "w", encoding="utf-8") as f:
381
- if is_image:
382
- f.write(content)
383
- else:
384
- f.write(prompt + "\n\n" + content)
385
-
386
- return filename
387
-
388
- # πŸ€– Function to insert an auto-generated record
389
- def insert_auto_generated_record(container):
390
- # πŸ€– Automatically generating a record and inserting it into Cosmos DB!
391
- try:
392
- # Generate a unique id
393
- new_id = generate_unique_id()
394
- # Create a sample JSON document
395
- new_doc = {
396
- 'id': new_id,
397
- 'name': f'Sample Name {new_id[:8]}',
398
- 'description': 'This is a sample auto-generated description.',
399
- 'timestamp': datetime.utcnow().isoformat()
400
- }
401
- # Insert the document
402
- container.create_item(body=new_doc)
403
- return True, f"Record inserted successfully with id: {new_id} πŸŽ‰"
404
- except exceptions.CosmosHttpResponseError as e:
405
- return False, f"HTTP error occurred: {str(e)} 🚨"
406
- except Exception as e:
407
- return False, f"An unexpected error occurred: {str(e)} 😱"
408
-
409
-
410
-
411
- # GitHub functions
412
- def download_github_repo(url, local_path):
413
- if os.path.exists(local_path):
414
- shutil.rmtree(local_path)
415
- Repo.clone_from(url, local_path)
416
-
417
- def create_zip_file(source_dir, output_filename):
418
- shutil.make_archive(output_filename, 'zip', source_dir)
419
-
420
- def create_repo(g, repo_name):
421
- user = g.get_user()
422
- return user.create_repo(repo_name)
423
-
424
- def push_to_github(local_path, repo, github_token):
425
- repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
426
- local_repo = Repo(local_path)
427
-
428
- if 'origin' in [remote.name for remote in local_repo.remotes]:
429
- origin = local_repo.remote('origin')
430
- origin.set_url(repo_url)
431
- else:
432
- origin = local_repo.create_remote('origin', repo_url)
433
-
434
- if not local_repo.heads:
435
- local_repo.git.checkout('-b', 'main')
436
- current_branch = 'main'
437
- else:
438
- current_branch = local_repo.active_branch.name
439
-
440
- local_repo.git.add(A=True)
441
-
442
- if local_repo.is_dirty():
443
- local_repo.git.commit('-m', 'Initial commit')
444
-
445
- origin.push(refspec=f'{current_branch}:{current_branch}')
446
-
447
- # Main function
448
  def main():
449
  st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
450
 
451
- # Initialize session state
 
 
 
 
452
  if 'client' not in st.session_state:
453
  st.session_state.client = None
454
  if 'selected_database' not in st.session_state:
@@ -459,27 +404,47 @@ def main():
459
  st.session_state.selected_document_id = None
460
  if 'current_index' not in st.session_state:
461
  st.session_state.current_index = 0
462
- if 'documents' not in st.session_state:
463
- st.session_state.documents = []
464
-
465
-
466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
- # Automatic Login
469
  if Key:
470
  st.session_state.primary_key = Key
471
  st.session_state.logged_in = True
472
  else:
473
  st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
474
- return
475
 
476
  if st.session_state.logged_in:
477
- # Initialize Cosmos DB client
478
  try:
479
  if st.session_state.client is None:
480
  st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
481
 
482
- # Sidebar for database, container, and document selection
483
  st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
484
 
485
  databases = get_databases(st.session_state.client)
@@ -505,24 +470,8 @@ def main():
505
 
506
  if st.session_state.selected_container:
507
  container = database.get_container_client(st.session_state.selected_container)
508
-
509
- if selected_db != st.session_state.selected_database:
510
- st.session_state.selected_database = selected_db
511
- st.session_state.selected_container = None
512
- st.session_state.selected_document_id = None
513
- st.session_state.current_index = 0
514
- st.rerun()
515
-
516
-
517
-
518
-
519
-
520
-
521
-
522
-
523
-
524
 
525
- # Add Export button
526
  if st.button("πŸ“¦ Export Container Data"):
527
  download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
528
  if download_link.startswith('<a'):
@@ -533,28 +482,6 @@ def main():
533
  # Fetch documents
534
  documents = get_documents(container)
535
  total_docs = len(documents)
536
-
537
- # Add buttons for saving new document and cloning
538
- if st.button("πŸ’Ύ Save New Document"):
539
- user_query = st.session_state.get('user_query', '')
540
- ai_response = st.session_state.get('ai_response', '')
541
- save_or_clone_to_cosmos_db(container, query=user_query, response=ai_response)
542
-
543
- if st.button("πŸ”„ Clone Document"):
544
- doc_to_clone = st.selectbox("Select document to clone", [doc['id'] for doc in st.session_state.documents])
545
- if doc_to_clone:
546
- save_or_clone_to_cosmos_db(container, clone_id=doc_to_clone)
547
-
548
- # Display documents
549
- if st.session_state.documents:
550
- for doc in st.session_state.documents:
551
- st.write(f"ID: {doc['id']}")
552
- st.write(f"Query: {doc.get('query', 'N/A')}")
553
- st.write(f"Response: {doc.get('response', 'N/A')}")
554
- st.write("---")
555
-
556
-
557
-
558
 
559
  if total_docs > 5:
560
  documents_to_display = documents[:5]
@@ -564,17 +491,17 @@ def main():
564
  st.info(f"Showing all {len(documents_to_display)} documents.")
565
 
566
  if documents_to_display:
567
- # Add Viewer/Editor selection
568
  view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
569
  selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
570
 
571
  if selected_view == 'Show as Markdown':
572
- # Show each record as Markdown with navigation
573
  total_docs = len(documents)
574
  doc = documents[st.session_state.current_index]
575
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
576
 
577
- # Extract values from the JSON that have at least one space
578
  values_with_space = []
579
  def extract_values(obj):
580
  if isinstance(obj, dict):
@@ -589,7 +516,7 @@ def main():
589
 
590
  extract_values(doc)
591
 
592
- # Create a list of links for these values
593
  st.markdown("#### πŸ”— Links for Extracted Texts")
594
  for term in values_with_space:
595
  display_glossary_entity(term)
@@ -612,7 +539,7 @@ def main():
612
  st.rerun()
613
 
614
  elif selected_view == 'Show as Code Editor':
615
- # Show each record in a code editor with navigation
616
  total_docs = len(documents)
617
  doc = documents[st.session_state.current_index]
618
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
@@ -642,7 +569,7 @@ def main():
642
  st.error(f"Invalid JSON: {str(e)} 🚫")
643
 
644
  elif selected_view == 'Show as Edit and Save':
645
- # Show as Edit and Save in columns
646
  st.markdown("#### Edit the document fields below:")
647
 
648
  # Create columns for each document
@@ -680,8 +607,8 @@ def main():
680
  search_glossary(json.dumps(editable_doc, indent=2))
681
 
682
  elif selected_view == 'Clone Document':
683
- # Clone Document per record
684
- st.markdown("#### Clone a document:")
685
  for idx, doc in enumerate(documents_to_display):
686
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
687
  if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
@@ -712,10 +639,10 @@ def main():
712
  st.error(f"Invalid JSON: {str(e)} 🚫")
713
 
714
  elif selected_view == 'New Record':
715
- # New Record
716
  st.markdown("#### Create a new document:")
717
  if st.button("πŸ€– Insert Auto-Generated Record"):
718
- success, message = insert_auto_generated_record(container)
719
  if success:
720
  st.success(message)
721
  st.rerun()
@@ -742,7 +669,7 @@ def main():
742
  else:
743
  st.sidebar.info("No documents found in this container. πŸ“­")
744
 
745
- # Main content area
746
  st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
747
  if st.session_state.selected_container:
748
  if documents_to_display:
@@ -751,7 +678,7 @@ def main():
751
  else:
752
  st.info("No documents to display. 🧐")
753
 
754
- # GitHub section
755
  st.subheader("πŸ™ GitHub Operations")
756
  github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
757
  source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
@@ -777,7 +704,7 @@ def main():
777
  os.remove(zip_filename)
778
  else:
779
  st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
780
-
781
  with col2:
782
  if st.button("πŸ“€ Push to New Repository"):
783
  if github_token and source_repo:
@@ -796,7 +723,7 @@ def main():
796
  else:
797
  st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
798
 
799
- # Chat with Claude
800
  st.subheader("πŸ’¬ Chat with Claude")
801
  user_input = st.text_area("Message πŸ“¨:", height=100)
802
 
@@ -818,7 +745,7 @@ def main():
818
  st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
819
 
820
  # Save to Cosmos DB
821
- save_or_clone_to_cosmos_db(container=st.session_state.cosmos_container, query=user_input, response=response.content[0].text, clone_id=None)
822
 
823
  # Display Chat History
824
  st.subheader("Past Conversations πŸ“œ")
@@ -873,20 +800,7 @@ def main():
873
  except Exception as e:
874
  st.error(f"An unexpected error occurred: {str(e)} 😱")
875
 
876
-
877
- # βš™οΈ q= Run ArXiv search from query parameters
878
- try:
879
- query_params = st.query_params
880
- query = query_params.get('q') or query_params.get('query') or ''
881
- if query:
882
- # πŸ•΅οΈβ€β™‚οΈ We have a query! Let's process it!
883
- process_text(query)
884
- #st.stop() # Stop further execution
885
- except Exception as e:
886
- st.markdown(' ')
887
-
888
-
889
- # Logout button
890
  if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
891
  st.session_state.logged_in = False
892
  st.session_state.selected_records.clear()
 
18
  import re
19
  from PIL import Image
20
  import zipfile
21
+ import hashlib
22
  import time
23
 
24
+ # 🎭 App Configuration - Because every app needs a good costume!
25
  Site_Name = 'πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent'
26
  title = "πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent"
27
  helpURL = 'https://huggingface.co/awacke1'
 
40
  }
41
  )
42
 
43
+ # 🌌 Cosmos DB configuration - Where data goes to party!
44
  ENDPOINT = "https://acae-afd.documents.azure.com:443/"
45
  DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
46
  CONTAINER_NAME = os.environ.get("COSMOS_CONTAINER_NAME")
47
  Key = os.environ.get("Key")
48
 
49
+ # 🌐 Your local app URL - Home sweet home
50
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
51
 
52
+ # πŸ€– Anthropic configuration - Teaching machines to be more human (and funnier)
53
  client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
54
 
55
+ # 🧠 Initialize session state - Because even apps need a good memory
56
  if "chat_history" not in st.session_state:
57
  st.session_state.chat_history = []
58
 
59
+ # πŸ› οΈ Helper Functions - The unsung heroes of our code
60
+
61
+ # πŸ“Ž Get a file download link - Making file sharing as easy as stealing candy from a baby
62
  def get_download_link(file_path):
63
  with open(file_path, "rb") as file:
64
  contents = file.read()
 
66
  file_name = os.path.basename(file_path)
67
  return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}πŸ“‚</a>'
68
 
69
+ # 🎲 Generate a unique ID - Because being unique is important (just ask your mother)
70
  def generate_unique_id():
71
+ timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')
72
+ unique_uuid = str(uuid.uuid4())
73
+ return f"{timestamp}-{unique_uuid}"
 
 
74
 
75
+ # πŸ“ Generate a filename - Naming files like a pro (or a very confused librarian)
76
  def generate_filename(prompt, file_type):
77
  central = pytz.timezone('US/Central')
78
  safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
79
  safe_prompt = re.sub(r'\W+', '', prompt)[:90]
80
  return f"{safe_date_time}{safe_prompt}.{file_type}"
81
 
82
+ # πŸ’Ύ Create and save a file - Because data hoarding is a legitimate hobby
83
  def create_file(filename, prompt, response, should_save=True):
84
  if not should_save:
85
  return
86
  with open(filename, 'w', encoding='utf-8') as file:
87
  file.write(prompt + "\n\n" + response)
88
 
89
+ # πŸ“– Load file content - Bringing words back from the digital grave
90
  def load_file(file_name):
91
  with open(file_name, "r", encoding='utf-8') as file:
92
  content = file.read()
93
  return content
94
 
95
+ # πŸ” Display glossary entity - Making search fun again (as if it ever was)
96
  def display_glossary_entity(k):
97
  search_urls = {
98
  "πŸš€πŸŒŒArXiv": lambda k: f"/?q={quote(k)}",
 
103
  links_md = ' '.join([f"<a href='{url(k)}' target='_blank'>{emoji}</a>" for emoji, url in search_urls.items()])
104
  st.markdown(f"{k} {links_md}", unsafe_allow_html=True)
105
 
106
+ # πŸ—œοΈ Create zip of files - Squeezing files together like sardines in a can
107
  def create_zip_of_files(files):
108
  zip_name = "all_files.zip"
109
  with zipfile.ZipFile(zip_name, 'w') as zipf:
 
111
  zipf.write(file)
112
  return zip_name
113
 
114
+ # 🎬 Get video HTML - Making videos play nice (or at least trying to)
115
  def get_video_html(video_path, width="100%"):
116
  video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
117
  return f'''
 
121
  </video>
122
  '''
123
 
124
+ # 🎡 Get audio HTML - Let the music play (and hope it's not Baby Shark)
125
  def get_audio_html(audio_path, width="100%"):
126
  audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}"
127
  return f'''
 
131
  </audio>
132
  '''
133
 
134
+ # 🌌 Cosmos DB functions - Where data goes to live its best life
135
+
136
+ # πŸ“š Get databases - Collecting databases like Pokemon cards
137
  def get_databases(client):
138
  return [db['id'] for db in client.list_databases()]
139
 
140
+ # πŸ“¦ Get containers - Finding where all the good stuff is hidden
141
  def get_containers(database):
142
  return [container['id'] for container in database.list_containers()]
143
 
144
+ # πŸ“„ Get documents - Retrieving the sacred texts (or just some JSON)
145
  def get_documents(container, limit=None):
146
  query = "SELECT * FROM c ORDER BY c._ts DESC"
147
  items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
148
  return items
149
 
150
+ # πŸ“₯ Insert record - Adding new data (and crossing fingers it doesn't break anything)
151
  def insert_record(container, record):
152
  try:
153
  container.create_item(body=record)
 
157
  except Exception as e:
158
  return False, f"An unexpected error occurred: {str(e)} 😱"
159
 
160
+ # πŸ”„ Update record - Giving data a makeover
161
  def update_record(container, updated_record):
162
  try:
163
  container.upsert_item(body=updated_record)
 
167
  except Exception as e:
168
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
169
 
170
+ # πŸ—‘οΈ Delete record - Saying goodbye to data (it's not you, it's me)
171
  def delete_record(container, name, id):
172
  try:
173
  container.delete_item(item=id, partition_key=id)
 
179
  except Exception as e:
180
  return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
181
 
182
+ # πŸ’Ύ Save to Cosmos DB - Preserving data for future generations (or just until the next update)
183
+ def save_to_cosmos_db(container, query, response1, response2):
184
+ try:
185
+ if container:
186
+ record = {
187
+ "id": generate_unique_id(),
188
+ "query": query,
189
+ "response1": response1,
190
+ "response2": response2,
191
+ "timestamp": datetime.utcnow().isoformat()
192
+ }
193
+ try:
194
+ container.create_item(body=record)
195
+ st.success(f"Record saved successfully with ID: {record['id']}")
196
+ # Refresh the documents display
197
+ st.session_state.documents = get_documents(container)
198
+ except exceptions.CosmosHttpResponseError as e:
199
+ st.error(f"Error saving record to Cosmos DB: {e}")
200
+ else:
201
+ st.error("Cosmos DB container is not initialized.")
202
+ except Exception as e:
203
+ st.error(f"An unexpected error occurred: {str(e)}")
204
 
205
+ # πŸ™ GitHub functions - Where code goes to socialize
206
+
207
+ # πŸ“₯ Download GitHub repo - Cloning repos like it's going out of style
208
+ def download_github_repo(url, local_path):
209
+ if os.path.exists(local_path):
210
+ shutil.rmtree(local_path)
211
+ Repo.clone_from(url, local_path)
212
+
213
+ # πŸ—œοΈ Create zip file - Squeezing files tighter than your budget
214
+ def create_zip_file(source_dir, output_filename):
215
+ shutil.make_archive(output_filename, 'zip', source_dir)
216
+
217
+ # πŸ—οΈ Create repo - Building digital homes for lonely code
218
+ def create_repo(g, repo_name):
219
+ user = g.get_user()
220
+ return user.create_repo(repo_name)
221
+
222
+ # πŸš€ Push to GitHub - Sending code to the cloud (hopefully not the rainy kind)
223
+ def push_to_github(local_path, repo, github_token):
224
+ repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
225
+ local_repo = Repo(local_path)
226
+
227
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
228
+ origin = local_repo.remote('origin')
229
+ origin.set_url(repo_url)
230
+ else:
231
+ origin = local_repo.create_remote('origin', repo_url)
232
+
233
+ if not local_repo.heads:
234
+ local_repo.git.checkout('-b', 'main')
235
+ current_branch = 'main'
236
+ else:
237
+ current_branch = local_repo.active_branch.name
238
+
239
+ local_repo.git.add(A=True)
240
+
241
+ if local_repo.is_dirty():
242
+ local_repo.git.commit('-m', 'Initial commit')
243
+
244
+ origin.push(refspec=f'{current_branch}:{current_branch}')
245
+
246
+ # πŸ’Ύ Save or clone to Cosmos DB - Because every document deserves a twin
247
  def save_or_clone_to_cosmos_db(container, query=None, response=None, clone_id=None):
248
  try:
249
  if not container:
 
292
  except Exception as e:
293
  st.error(f"An unexpected error occurred: {str(e)}")
294
 
295
+ # πŸ“¦ Archive current container - Packing up data like you're moving to a new digital house
296
+ def archive_current_container(database_name, container_name, client):
297
+ try:
298
+ base_dir = "./cosmos_archive_current_container"
299
+ if os.path.exists(base_dir):
300
+ shutil.rmtree(base_dir)
301
+ os.makedirs(base_dir)
302
+
303
+ db_client = client.get_database_client(database_name)
304
+ container_client = db_client.get_container_client(container_name)
305
+ items = list(container_client.read_all_items())
306
+
307
+ container_dir = os.path.join(base_dir, container_name)
308
+ os.makedirs(container_dir)
309
+
310
+ for item in items:
311
+ item_id = item.get('id', f"unknown_{datetime.now().strftime('%Y%m%d%H%M%S')}")
312
+ with open(os.path.join(container_dir, f"{item_id}.json"), 'w') as f:
313
+ json.dump(item, f, indent=2)
314
+
315
+ archive_name = f"{container_name}_archive_{datetime.now().strftime('%Y%m%d%H%M%S')}"
316
+ shutil.make_archive(archive_name, 'zip', base_dir)
317
+
318
+ return get_download_link(f"{archive_name}.zip")
319
+ except Exception as e:
320
+ return f"An error occurred while archiving data: {str(e)} 😒"
321
 
322
+ # πŸ” Search glossary - Finding needles in digital haystacks
323
  def search_glossary(query):
324
+ st.markdown(f"### πŸ” SearchGlossary for: {query}")
325
+
326
  # Dropdown for model selection
327
  model_options = ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None']
328
  model_choice = st.selectbox('🧠 Select LLM Model', options=model_options, index=1)
329
+
330
  # Dropdown for database selection
331
  database_options = ['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)']
332
  database_choice = st.selectbox('πŸ“š Select Database', options=database_options, index=0)
333
 
 
 
 
 
 
334
  # πŸ•΅οΈβ€β™‚οΈ Searching the glossary for: query
335
  all_results = ""
336
  st.markdown(f"- {query}")
337
 
338
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM
 
 
339
  client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
340
 
 
341
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
342
  result = client.predict(
343
  prompt=query,
 
347
  )
348
  st.markdown(result)
349
  st.code(result, language="python", line_numbers=True)
350
+
351
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
352
  result2 = client.predict(
353
  prompt=query,
 
368
  st.markdown(result3)
369
  st.code(result3, language="python", line_numbers=True)
370
 
 
371
  # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /update_with_rag_md
372
  response2 = client.predict(
373
  message=query, # str in 'parameter_13' Textbox component
 
375
  database_choice="Semantic Search",
376
  llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
377
  api_name="/update_with_rag_md"
378
+ )
379
 
380
  st.markdown(response2[0])
381
  st.code(response2[0], language="python", line_numbers=True, wrap_lines=True)
382
+
383
  st.markdown(response2[1])
384
  st.code(response2[1], language="python", line_numbers=True, wrap_lines=True)
385
 
386
+ return result, result2, result3, response2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
388
+ # 🎭 Main function - Where the magic happens (and occasionally breaks)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  def main():
390
  st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
391
 
392
+ # 🚦 Initialize session state
393
+ if 'logged_in' not in st.session_state:
394
+ st.session_state.logged_in = False
395
+ if 'selected_records' not in st.session_state:
396
+ st.session_state.selected_records = []
397
  if 'client' not in st.session_state:
398
  st.session_state.client = None
399
  if 'selected_database' not in st.session_state:
 
404
  st.session_state.selected_document_id = None
405
  if 'current_index' not in st.session_state:
406
  st.session_state.current_index = 0
407
+ if 'cloned_doc' not in st.session_state:
408
+ st.session_state.cloned_doc = None
 
 
409
 
410
+ # βš™οΈ q= Run ArXiv search from query parameters
411
+ try:
412
+ query_params = st.query_params
413
+ query = query_params.get('q') or query_params.get('query') or ''
414
+ if query:
415
+ # πŸ•΅οΈβ€β™‚οΈ We have a query! Let's process it!
416
+ result, result2, result3, response2 = search_glossary(query)
417
+ # When saving results, pass the container
418
+ try:
419
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result, result)
420
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result2, result2)
421
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result3, result3)
422
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[0], response2[0])
423
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[1], response2[1])
424
+ except exceptions.CosmosHttpResponseError as e:
425
+ st.error(f"HTTP error occurred: {str(e)} 🚨")
426
+ except Exception as e:
427
+ st.error(f"An unexpected error occurred: {str(e)} 😱")
428
+
429
+ st.stop() # Stop further execution
430
+ except Exception as e:
431
+ st.markdown(' ')
432
 
433
+ # πŸ” Automatic Login
434
  if Key:
435
  st.session_state.primary_key = Key
436
  st.session_state.logged_in = True
437
  else:
438
  st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
439
+ return # Can't proceed without a key
440
 
441
  if st.session_state.logged_in:
442
+ # 🌌 Initialize Cosmos DB client
443
  try:
444
  if st.session_state.client is None:
445
  st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
446
 
447
+ # πŸ—„οΈ Sidebar for database, container, and document selection
448
  st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
449
 
450
  databases = get_databases(st.session_state.client)
 
470
 
471
  if st.session_state.selected_container:
472
  container = database.get_container_client(st.session_state.selected_container)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
 
474
+ # πŸ“¦ Add Export button
475
  if st.button("πŸ“¦ Export Container Data"):
476
  download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
477
  if download_link.startswith('<a'):
 
482
  # Fetch documents
483
  documents = get_documents(container)
484
  total_docs = len(documents)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
 
486
  if total_docs > 5:
487
  documents_to_display = documents[:5]
 
491
  st.info(f"Showing all {len(documents_to_display)} documents.")
492
 
493
  if documents_to_display:
494
+ # 🎨 Add Viewer/Editor selection
495
  view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
496
  selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
497
 
498
  if selected_view == 'Show as Markdown':
499
+ # πŸ–ŒοΈ Show each record as Markdown with navigation
500
  total_docs = len(documents)
501
  doc = documents[st.session_state.current_index]
502
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
503
 
504
+ # πŸ•΅οΈβ€β™‚οΈ Let's extract values from the JSON that have at least one space
505
  values_with_space = []
506
  def extract_values(obj):
507
  if isinstance(obj, dict):
 
516
 
517
  extract_values(doc)
518
 
519
+ # πŸ”— Let's create a list of links for these values
520
  st.markdown("#### πŸ”— Links for Extracted Texts")
521
  for term in values_with_space:
522
  display_glossary_entity(term)
 
539
  st.rerun()
540
 
541
  elif selected_view == 'Show as Code Editor':
542
+ # πŸ’» Show each record in a code editor with navigation
543
  total_docs = len(documents)
544
  doc = documents[st.session_state.current_index]
545
  st.markdown(f"#### Document ID: {doc.get('id', '')}")
 
569
  st.error(f"Invalid JSON: {str(e)} 🚫")
570
 
571
  elif selected_view == 'Show as Edit and Save':
572
+ # ✏️ Show as Edit and Save in columns
573
  st.markdown("#### Edit the document fields below:")
574
 
575
  # Create columns for each document
 
607
  search_glossary(json.dumps(editable_doc, indent=2))
608
 
609
  elif selected_view == 'Clone Document':
610
+ # 🧬 Clone Document per record
611
+ st.markdownst.markdown("#### Clone a document:")
612
  for idx, doc in enumerate(documents_to_display):
613
  st.markdown(f"##### Document ID: {doc.get('id', '')}")
614
  if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
 
639
  st.error(f"Invalid JSON: {str(e)} 🚫")
640
 
641
  elif selected_view == 'New Record':
642
+ # πŸ†• New Record
643
  st.markdown("#### Create a new document:")
644
  if st.button("πŸ€– Insert Auto-Generated Record"):
645
+ success, message = save_or_clone_to_cosmos_db(container, query="Auto-generated", response="This is an auto-generated record.")
646
  if success:
647
  st.success(message)
648
  st.rerun()
 
669
  else:
670
  st.sidebar.info("No documents found in this container. πŸ“­")
671
 
672
+ # πŸŽ‰ Main content area
673
  st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
674
  if st.session_state.selected_container:
675
  if documents_to_display:
 
678
  else:
679
  st.info("No documents to display. 🧐")
680
 
681
+ # πŸ™ GitHub section
682
  st.subheader("πŸ™ GitHub Operations")
683
  github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
684
  source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
 
704
  os.remove(zip_filename)
705
  else:
706
  st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
707
+
708
  with col2:
709
  if st.button("πŸ“€ Push to New Repository"):
710
  if github_token and source_repo:
 
723
  else:
724
  st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
725
 
726
+ # πŸ’¬ Chat with Claude
727
  st.subheader("πŸ’¬ Chat with Claude")
728
  user_input = st.text_area("Message πŸ“¨:", height=100)
729
 
 
745
  st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
746
 
747
  # Save to Cosmos DB
748
+ save_to_cosmos_db(container, user_input, response.content[0].text, "")
749
 
750
  # Display Chat History
751
  st.subheader("Past Conversations πŸ“œ")
 
800
  except Exception as e:
801
  st.error(f"An unexpected error occurred: {str(e)} 😱")
802
 
803
+ # πŸšͺ Logout button
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
805
  st.session_state.logged_in = False
806
  st.session_state.selected_records.clear()