awacke1 commited on
Commit
76434fc
Β·
verified Β·
1 Parent(s): fd64b34

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +135 -38
app.py CHANGED
@@ -15,7 +15,7 @@ import traceback
15
  import uuid
16
  import zipfile
17
  from PIL import Image
18
- from azure.cosmos import CosmosClient, exceptions
19
  from datetime import datetime
20
  from git import Repo
21
  from github import Github
@@ -187,42 +187,23 @@ def update_record(container, updated_record):
187
 
188
  # πŸ—‘οΈ Delete a record from Cosmos DB using /id as partition key
189
  def delete_record(container, record):
190
- """
191
- Delete a record from Cosmos DB using its 'id' field as both the item ID and partition key.
192
-
193
- Args:
194
- container: Cosmos DB container client
195
- record: Dictionary containing at least 'id'
196
-
197
- Returns:
198
- tuple: (success: bool, message: str)
199
- """
200
  try:
201
- # Ensure record has an ID
202
  if "id" not in record:
203
  return False, "Record must contain an 'id' field. πŸ›‘"
204
-
205
  doc_id = record["id"]
206
-
207
- # Log the document being deleted (persistent in session state)
208
  if "delete_log" not in st.session_state:
209
  st.session_state.delete_log = []
210
  st.session_state.delete_log.append(f"Attempting to delete document: {json.dumps(record, indent=2)}")
211
-
212
- # Use 'id' as the partition key since container is partitioned on /id
213
  partition_key_value = doc_id
214
  st.session_state.delete_log.append(f"Using ID and Partition Key: {partition_key_value}")
215
-
216
- # Perform the deletion
217
  container.delete_item(item=doc_id, partition_key=partition_key_value)
218
  success_msg = f"Record {doc_id} successfully deleted from Cosmos DB. πŸ—‘οΈ"
219
  st.session_state.delete_log.append(success_msg)
220
  return True, success_msg
221
-
222
  except exceptions.CosmosResourceNotFoundError:
223
  success_msg = f"Record {doc_id} not found in Cosmos DB (already deleted or never existed). πŸ—‘οΈ"
224
  st.session_state.delete_log.append(success_msg)
225
- return True, success_msg # Treat as success since the goal is removal
226
  except exceptions.CosmosHttpResponseError as e:
227
  error_msg = f"HTTP error deleting {doc_id}: {str(e)}. 🚨"
228
  st.session_state.delete_log.append(error_msg)
@@ -279,23 +260,75 @@ def archive_current_container(database_name, container_name, client):
279
  except Exception as e:
280
  return f"Archive error: {str(e)} 😒"
281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  # %% ───────────── GITHUB FUNCTIONS ─────────────
283
- # πŸ“₯ Clone a GitHub repository locally
284
  def download_github_repo(url, local_path):
285
  if os.path.exists(local_path):
286
  shutil.rmtree(local_path)
287
  Repo.clone_from(url, local_path)
288
 
289
- # πŸ—œοΈ Zip a directory
290
  def create_zip_file(source_dir, output_filename):
291
  shutil.make_archive(output_filename, 'zip', source_dir)
292
 
293
- # πŸ—οΈ Create a new GitHub repo via API
294
  def create_repo(g, repo_name):
295
  user = g.get_user()
296
  return user.create_repo(repo_name)
297
 
298
- # πŸš€ Push local repo changes to GitHub
299
  def push_to_github(local_path, repo, github_token):
300
  repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
301
  local_repo = Repo(local_path)
@@ -315,7 +348,6 @@ def push_to_github(local_path, repo, github_token):
315
  origin.push(refspec=f'{current_branch}:{current_branch}')
316
 
317
  # %% ───────────── FILE & MEDIA MANAGEMENT FUNCTIONS ─────────────
318
- # πŸ“‚ List saved Markdown files in sidebar with actions
319
  def display_saved_files_in_sidebar():
320
  all_files = sorted([f for f in glob.glob("*.md") if not f.lower().startswith('readme')], reverse=True)
321
  st.sidebar.markdown("## πŸ“ Files")
@@ -334,7 +366,6 @@ def display_saved_files_in_sidebar():
334
  os.remove(file)
335
  st.rerun()
336
 
337
- # πŸ‘€ Display file viewer in main area
338
  def display_file_viewer(file_path):
339
  content = load_file(file_path)
340
  if content:
@@ -346,7 +377,6 @@ def display_file_viewer(file_path):
346
  st.markdown(content)
347
  st.download_button("⬇️", data=content, file_name=os.path.basename(file_path), mime="text/markdown")
348
 
349
- # ✏️ Display file editor (Markdown & Code)
350
  def display_file_editor(file_path):
351
  if 'file_content' not in st.session_state:
352
  st.session_state.file_content = {}
@@ -374,7 +404,6 @@ def display_file_editor(file_path):
374
  with col2:
375
  st.download_button("⬇️", data=new_content, file_name=os.path.basename(file_path), mime="text/markdown")
376
 
377
- # πŸ’Ύ Save content to a file (with error handling)
378
  def save_file_content(file_path, content):
379
  try:
380
  with open(file_path, 'w', encoding='utf-8') as file:
@@ -384,7 +413,6 @@ def save_file_content(file_path, content):
384
  st.error(f"Save error: {str(e)}")
385
  return False
386
 
387
- # πŸ—‚οΈ Update file management UI section (view, edit, delete)
388
  def update_file_management_section():
389
  if 'file_view_mode' not in st.session_state:
390
  st.session_state.file_view_mode = None
@@ -449,7 +477,6 @@ def update_file_management_section():
449
  display_file_editor(st.session_state.current_file)
450
 
451
  # %% ───────────── VIDEO & AUDIO UI FUNCTIONS ─────────────
452
- # πŸ–ΌοΈ Validate and preprocess an image for video generation
453
  def validate_and_preprocess_image(file_data, target_size=(576, 1024)):
454
  try:
455
  st.write("Preprocessing image...")
@@ -484,7 +511,6 @@ def validate_and_preprocess_image(file_data, target_size=(576, 1024)):
484
  st.error(f"Image error: {str(e)}")
485
  return None
486
 
487
- # ▢️ Add video generation UI with Gradio client
488
  def add_video_generation_ui(container):
489
  st.markdown("### πŸŽ₯ Video Gen")
490
  col1, col2 = st.columns([2, 1])
@@ -564,7 +590,6 @@ def add_video_generation_ui(container):
564
  st.error(f"Upload error: {str(e)}")
565
 
566
  # %% ───────────── MAIN FUNCTION ─────────────
567
- # πŸš€ Main app entry point
568
  def main():
569
  st.markdown("### πŸ™ GitCosmos - Cosmos & Git Hub")
570
  if "chat_history" not in st.session_state:
@@ -666,11 +691,9 @@ def main():
666
  st.error(message)
667
  except Exception as e:
668
  st.error(f"Delete err: {str(e)}")
669
-
670
- # Display delete log persistently
671
  if "delete_log" in st.session_state and st.session_state.delete_log:
672
  st.subheader("Delete Log")
673
- for log_entry in st.session_state.delete_log[-5:]: # Show last 5 entries
674
  st.write(log_entry)
675
  elif selected_view == 'Run AI':
676
  st.markdown("#### πŸ€– Run AI (stub)")
@@ -753,7 +776,82 @@ def main():
753
  st.dataframe(df)
754
  else:
755
  st.info("No docs.")
756
- # --- End of Document UI ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
  st.subheader("πŸ™ GitHub Ops")
758
  github_token = os.environ.get("GITHUB")
759
  source_repo = st.text_input("Source Repo URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
@@ -795,7 +893,6 @@ def main():
795
  shutil.rmtree(local_path)
796
  else:
797
  st.error("Missing token or URL πŸ”‘β“")
798
- # --- File Management Section ---
799
  update_file_management_section()
800
  except exceptions.CosmosHttpResponseError as e:
801
  st.error(f"Cosmos error: {str(e)} 🚨")
 
15
  import uuid
16
  import zipfile
17
  from PIL import Image
18
+ from azure.cosmos import CosmosClient, PartitionKey, exceptions
19
  from datetime import datetime
20
  from git import Repo
21
  from github import Github
 
187
 
188
  # πŸ—‘οΈ Delete a record from Cosmos DB using /id as partition key
189
  def delete_record(container, record):
 
 
 
 
 
 
 
 
 
 
190
  try:
 
191
  if "id" not in record:
192
  return False, "Record must contain an 'id' field. πŸ›‘"
 
193
  doc_id = record["id"]
 
 
194
  if "delete_log" not in st.session_state:
195
  st.session_state.delete_log = []
196
  st.session_state.delete_log.append(f"Attempting to delete document: {json.dumps(record, indent=2)}")
 
 
197
  partition_key_value = doc_id
198
  st.session_state.delete_log.append(f"Using ID and Partition Key: {partition_key_value}")
 
 
199
  container.delete_item(item=doc_id, partition_key=partition_key_value)
200
  success_msg = f"Record {doc_id} successfully deleted from Cosmos DB. πŸ—‘οΈ"
201
  st.session_state.delete_log.append(success_msg)
202
  return True, success_msg
 
203
  except exceptions.CosmosResourceNotFoundError:
204
  success_msg = f"Record {doc_id} not found in Cosmos DB (already deleted or never existed). πŸ—‘οΈ"
205
  st.session_state.delete_log.append(success_msg)
206
+ return True, success_msg
207
  except exceptions.CosmosHttpResponseError as e:
208
  error_msg = f"HTTP error deleting {doc_id}: {str(e)}. 🚨"
209
  st.session_state.delete_log.append(error_msg)
 
260
  except Exception as e:
261
  return f"Archive error: {str(e)} 😒"
262
 
263
+ # %% ───────────── ADVANCED COSMOS FUNCTIONS ─────────────
264
+ def create_new_container(database, container_id, partition_key_path,
265
+ analytical_storage_ttl=None, indexing_policy=None, vector_embedding_policy=None):
266
+ try:
267
+ if analytical_storage_ttl is not None:
268
+ container = database.create_container(
269
+ id=container_id,
270
+ partition_key=PartitionKey(path=partition_key_path),
271
+ analytical_storage_ttl=analytical_storage_ttl,
272
+ indexing_policy=indexing_policy,
273
+ vector_embedding_policy=vector_embedding_policy
274
+ )
275
+ else:
276
+ container = database.create_container(
277
+ id=container_id,
278
+ partition_key=PartitionKey(path=partition_key_path),
279
+ indexing_policy=indexing_policy,
280
+ vector_embedding_policy=vector_embedding_policy
281
+ )
282
+ except exceptions.CosmosResourceExistsError:
283
+ container = database.get_container_client(container_id)
284
+ except exceptions.CosmosHttpResponseError as e:
285
+ st.error(f"Error creating container: {str(e)}")
286
+ return None
287
+ return container
288
+
289
+ def advanced_insert_item(container, item):
290
+ try:
291
+ container.upsert_item(item)
292
+ return True, f"Item {item.get('id', '')} inserted. βž•"
293
+ except Exception as e:
294
+ return False, str(e)
295
+
296
+ def advanced_update_item(container, item):
297
+ try:
298
+ container.upsert_item(item)
299
+ return True, f"Item {item.get('id', '')} updated. ✏️"
300
+ except Exception as e:
301
+ return False, str(e)
302
+
303
+ def advanced_delete_item(container, item_id, partition_key_value):
304
+ try:
305
+ container.delete_item(item=item_id, partition_key=partition_key_value)
306
+ return True, f"Item {item_id} deleted. πŸ—‘οΈ"
307
+ except Exception as e:
308
+ return False, str(e)
309
+
310
+ def vector_search(container, query_vector, vector_field, top=10, exact_search=False):
311
+ # Convert the vector list to a JSON string
312
+ query_vector_str = json.dumps(query_vector)
313
+ query = f"""SELECT TOP {top} c.id, VectorDistance(c.{vector_field}, {query_vector_str}, {str(exact_search).lower()},
314
+ {{'dataType':'float32','distanceFunction':'cosine'}}) AS SimilarityScore
315
+ FROM c ORDER BY SimilarityScore"""
316
+ results = list(container.query_items(query=query, enable_cross_partition_query=True))
317
+ return results
318
+
319
  # %% ───────────── GITHUB FUNCTIONS ─────────────
 
320
  def download_github_repo(url, local_path):
321
  if os.path.exists(local_path):
322
  shutil.rmtree(local_path)
323
  Repo.clone_from(url, local_path)
324
 
 
325
  def create_zip_file(source_dir, output_filename):
326
  shutil.make_archive(output_filename, 'zip', source_dir)
327
 
 
328
  def create_repo(g, repo_name):
329
  user = g.get_user()
330
  return user.create_repo(repo_name)
331
 
 
332
  def push_to_github(local_path, repo, github_token):
333
  repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
334
  local_repo = Repo(local_path)
 
348
  origin.push(refspec=f'{current_branch}:{current_branch}')
349
 
350
  # %% ───────────── FILE & MEDIA MANAGEMENT FUNCTIONS ─────────────
 
351
  def display_saved_files_in_sidebar():
352
  all_files = sorted([f for f in glob.glob("*.md") if not f.lower().startswith('readme')], reverse=True)
353
  st.sidebar.markdown("## πŸ“ Files")
 
366
  os.remove(file)
367
  st.rerun()
368
 
 
369
  def display_file_viewer(file_path):
370
  content = load_file(file_path)
371
  if content:
 
377
  st.markdown(content)
378
  st.download_button("⬇️", data=content, file_name=os.path.basename(file_path), mime="text/markdown")
379
 
 
380
  def display_file_editor(file_path):
381
  if 'file_content' not in st.session_state:
382
  st.session_state.file_content = {}
 
404
  with col2:
405
  st.download_button("⬇️", data=new_content, file_name=os.path.basename(file_path), mime="text/markdown")
406
 
 
407
  def save_file_content(file_path, content):
408
  try:
409
  with open(file_path, 'w', encoding='utf-8') as file:
 
413
  st.error(f"Save error: {str(e)}")
414
  return False
415
 
 
416
  def update_file_management_section():
417
  if 'file_view_mode' not in st.session_state:
418
  st.session_state.file_view_mode = None
 
477
  display_file_editor(st.session_state.current_file)
478
 
479
  # %% ───────────── VIDEO & AUDIO UI FUNCTIONS ─────────────
 
480
  def validate_and_preprocess_image(file_data, target_size=(576, 1024)):
481
  try:
482
  st.write("Preprocessing image...")
 
511
  st.error(f"Image error: {str(e)}")
512
  return None
513
 
 
514
  def add_video_generation_ui(container):
515
  st.markdown("### πŸŽ₯ Video Gen")
516
  col1, col2 = st.columns([2, 1])
 
590
  st.error(f"Upload error: {str(e)}")
591
 
592
  # %% ───────────── MAIN FUNCTION ─────────────
 
593
  def main():
594
  st.markdown("### πŸ™ GitCosmos - Cosmos & Git Hub")
595
  if "chat_history" not in st.session_state:
 
691
  st.error(message)
692
  except Exception as e:
693
  st.error(f"Delete err: {str(e)}")
 
 
694
  if "delete_log" in st.session_state and st.session_state.delete_log:
695
  st.subheader("Delete Log")
696
+ for log_entry in st.session_state.delete_log[-5:]:
697
  st.write(log_entry)
698
  elif selected_view == 'Run AI':
699
  st.markdown("#### πŸ€– Run AI (stub)")
 
776
  st.dataframe(df)
777
  else:
778
  st.info("No docs.")
779
+
780
+ # ───── Advanced Cosmos Ops ─────
781
+ with st.sidebar.expander("Advanced Cosmos Ops"):
782
+ st.markdown("### Advanced Cosmos Operations")
783
+ # Create Container
784
+ with st.form("create_container_form"):
785
+ container_id = st.text_input("Container ID", value="newContainer")
786
+ partition_key_path = st.text_input("Partition Key Path", value="/id")
787
+ analytical = st.checkbox("Enable Analytical Store", value=False)
788
+ submitted = st.form_submit_button("πŸ†• Create Container")
789
+ if submitted:
790
+ analytical_ttl = -1 if analytical else None
791
+ new_container = create_new_container(database, container_id, partition_key_path,
792
+ analytical_storage_ttl=analytical_ttl)
793
+ if new_container:
794
+ st.success(f"Container '{container_id}' created.")
795
+ else:
796
+ st.error("Container creation failed.")
797
+
798
+ # Insert Item
799
+ with st.form("insert_item_form"):
800
+ item_json = st.text_area("Item JSON", value='{"id": "itemX", "productName": "Widget", "productModel": "Model X"}')
801
+ submitted = st.form_submit_button("βž• Insert Item")
802
+ if submitted:
803
+ try:
804
+ item = json.loads(item_json)
805
+ success, msg = advanced_insert_item(container, item)
806
+ if success:
807
+ st.success(msg)
808
+ else:
809
+ st.error(msg)
810
+ except Exception as e:
811
+ st.error(str(e))
812
+
813
+ # Update Item
814
+ with st.form("update_item_form"):
815
+ update_json = st.text_area("Update Item JSON", value='{"id": "itemX", "productName": "Widget", "productModel": "Updated Model"}')
816
+ submitted = st.form_submit_button("✏️ Update Item")
817
+ if submitted:
818
+ try:
819
+ item = json.loads(update_json)
820
+ success, msg = advanced_update_item(container, item)
821
+ if success:
822
+ st.success(msg)
823
+ else:
824
+ st.error(msg)
825
+ except Exception as e:
826
+ st.error(str(e))
827
+
828
+ # Delete Item
829
+ with st.form("delete_item_form"):
830
+ del_item_id = st.text_input("Item ID to delete", value="itemX")
831
+ del_partition = st.text_input("Partition Key Value", value="Widget")
832
+ submitted = st.form_submit_button("πŸ—‘οΈ Delete Item")
833
+ if submitted:
834
+ success, msg = advanced_delete_item(container, del_item_id, del_partition)
835
+ if success:
836
+ st.success(msg)
837
+ else:
838
+ st.error(msg)
839
+
840
+ # Vector Search
841
+ with st.form("vector_search_form"):
842
+ vector_str = st.text_input("Query Vector (comma separated)", value="0.1, 0.2, 0.3, 0.4")
843
+ top_n = st.number_input("Top N Results", min_value=1, max_value=100, value=10)
844
+ vector_field = st.text_input("Vector Field", value="vector")
845
+ submitted = st.form_submit_button("πŸ”Ž Vector Search")
846
+ if submitted:
847
+ try:
848
+ query_vector = [float(x.strip()) for x in vector_str.split(",") if x.strip()]
849
+ results = vector_search(container, query_vector, vector_field, top=top_n)
850
+ st.write(results)
851
+ except Exception as e:
852
+ st.error(str(e))
853
+
854
+ # ───── End Advanced Ops ─────
855
  st.subheader("πŸ™ GitHub Ops")
856
  github_token = os.environ.get("GITHUB")
857
  source_repo = st.text_input("Source Repo URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
 
893
  shutil.rmtree(local_path)
894
  else:
895
  st.error("Missing token or URL πŸ”‘β“")
 
896
  update_file_management_section()
897
  except exceptions.CosmosHttpResponseError as e:
898
  st.error(f"Cosmos error: {str(e)} 🚨")