awacke1 commited on
Commit
104cda3
Β·
verified Β·
1 Parent(s): 5c982fc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +733 -36
app.py CHANGED
@@ -1,47 +1,20 @@
1
  import streamlit as st
2
- import anthropic
3
- import os
4
- import base64
5
- import glob
6
- import json
7
- import pytz
8
- from datetime import datetime
9
- from streamlit.components.v1 import html
10
- from PIL import Image
11
- import re
12
- #from urllib.parse import quote
13
-
14
  from azure.cosmos import CosmosClient, exceptions
 
15
  import pandas as pd
16
  import traceback
17
  import shutil
18
  from github import Github
19
  from git import Repo
 
 
 
20
  import uuid # 🎲 For generating unique IDs
21
-
22
  from urllib.parse import quote # πŸ”— For encoding URLs
23
  from gradio_client import Client # 🌐 For connecting to Gradio apps
24
 
25
  # πŸŽ‰ Welcome to our fun-filled Cosmos DB and GitHub Integration app!
26
- # 1. App Configuration
27
- Site_Name = 'πŸ€–πŸ§ Claude35πŸ“πŸ”¬'
28
- title="πŸ€–πŸ§ Claude35πŸ“πŸ”¬"
29
- helpURL='https://huggingface.co/awacke1'
30
- bugURL='https://huggingface.co/spaces/awacke1'
31
- icons='πŸ€–πŸ§ πŸ”¬πŸ“'
32
-
33
- st.set_page_config(
34
- page_title=title,
35
- page_icon=icons,
36
- layout="wide",
37
- initial_sidebar_state="auto",
38
- menu_items={
39
- 'Get Help': helpURL,
40
- 'Report a bug': bugURL,
41
- 'About': title
42
- }
43
- )
44
-
45
 
46
  # 🌌 Cosmos DB configuration
47
  ENDPOINT = "https://acae-afd.documents.azure.com:443/"
@@ -52,10 +25,6 @@ Key = os.environ.get("Key") # πŸ”‘ Don't forget your key!
52
  # 🏠 Your local app URL (Change this to your app's URL)
53
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
54
 
55
- # πŸ€– OpenAI configuration
56
- # openai.api_key = os.environ.get("OPENAI_API_KEY")
57
- # MODEL = "gpt-3.5-turbo" # Replace with your desired model
58
-
59
  # πŸ™ GitHub configuration
60
  def download_github_repo(url, local_path):
61
  # 🚚 Let's download that GitHub repo!
@@ -784,6 +753,734 @@ def main():
784
  st.session_state.current_index = 0
785
  st.rerun()
786
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
 
788
 
789
 
 
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
2
  from azure.cosmos import CosmosClient, exceptions
3
+ import os
4
  import pandas as pd
5
  import traceback
6
  import shutil
7
  from github import Github
8
  from git import Repo
9
+ from datetime import datetime
10
+ import base64
11
+ import json
12
  import uuid # 🎲 For generating unique IDs
 
13
  from urllib.parse import quote # πŸ”— For encoding URLs
14
  from gradio_client import Client # 🌐 For connecting to Gradio apps
15
 
16
  # πŸŽ‰ Welcome to our fun-filled Cosmos DB and GitHub Integration app!
17
+ st.set_page_config(layout="wide")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  # 🌌 Cosmos DB configuration
20
  ENDPOINT = "https://acae-afd.documents.azure.com:443/"
 
25
  # 🏠 Your local app URL (Change this to your app's URL)
26
  LOCAL_APP_URL = "https://huggingface.co/spaces/awacke1/AzureCosmosDBUI"
27
 
 
 
 
 
28
  # πŸ™ GitHub configuration
29
  def download_github_repo(url, local_path):
30
  # 🚚 Let's download that GitHub repo!
 
753
  st.session_state.current_index = 0
754
  st.rerun()
755
 
756
+ # πŸ™ GitHub configuration
757
+ def download_github_repo(url, local_path):
758
+ # 🚚 Let's download that GitHub repo!
759
+ if os.path.exists(local_path):
760
+ shutil.rmtree(local_path)
761
+ Repo.clone_from(url, local_path)
762
+
763
+ def create_zip_file(source_dir, output_filename):
764
+ # πŸ“¦ Zipping up files like a pro!
765
+ shutil.make_archive(output_filename, 'zip', source_dir)
766
+
767
+ def create_repo(g, repo_name):
768
+ # πŸ› οΈ Creating a new GitHub repo. Magic!
769
+ user = g.get_user()
770
+ return user.create_repo(repo_name)
771
+
772
+ def push_to_github(local_path, repo, github_token):
773
+ # πŸš€ Pushing code to GitHub. Hold on tight!
774
+ repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
775
+ local_repo = Repo(local_path)
776
+
777
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
778
+ origin = local_repo.remote('origin')
779
+ origin.set_url(repo_url)
780
+ else:
781
+ origin = local_repo.create_remote('origin', repo_url)
782
+
783
+ if not local_repo.heads:
784
+ local_repo.git.checkout('-b', 'main')
785
+ current_branch = 'main'
786
+ else:
787
+ current_branch = local_repo.active_branch.name
788
+
789
+ local_repo.git.add(A=True)
790
+
791
+ if local_repo.is_dirty():
792
+ local_repo.git.commit('-m', 'Initial commit')
793
+
794
+ origin.push(refspec=f'{current_branch}:{current_branch}')
795
+
796
+ def get_base64_download_link(file_path, file_name):
797
+ # πŸ§™β€β™‚οΈ Generating a magical download link!
798
+ with open(file_path, "rb") as file:
799
+ contents = file.read()
800
+ base64_encoded = base64.b64encode(contents).decode()
801
+ return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">⬇️ Download {file_name}</a>'
802
+
803
+
804
+ # 🧭 New functions for dynamic sidebar navigation
805
+ def get_databases(client):
806
+ # πŸ“š Fetching list of databases. So many options!
807
+ return [db['id'] for db in client.list_databases()]
808
+
809
+ def get_containers(database):
810
+ # πŸ“‚ Getting containers. Containers within containers!
811
+ return [container['id'] for container in database.list_containers()]
812
+
813
+ def get_documents(container, limit=None):
814
+ # πŸ“ Retrieving documents. Shhh, don't tell anyone!
815
+ query = "SELECT * FROM c ORDER BY c._ts DESC"
816
+ items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
817
+ return items
818
+
819
+
820
+ # 🌟 Cosmos DB functions
821
+ def insert_record(container, record):
822
+ # πŸ“₯ Inserting a record into the Cosmosβ€”hope we don't disturb any aliens! πŸ‘½
823
+ try:
824
+ container.create_item(body=record)
825
+ return True, "Record inserted successfully! πŸŽ‰"
826
+ except exceptions.CosmosHttpResponseError as e:
827
+ return False, f"HTTP error occurred: {str(e)} 🚨"
828
+ except Exception as e:
829
+ return False, f"An unexpected error occurred: {str(e)} 😱"
830
+
831
+ def update_record(container, updated_record):
832
+ # πŸ”„ Updating a recordβ€”giving it a cosmic makeover! ✨
833
+ try:
834
+ container.upsert_item(body=updated_record)
835
+ return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΈ"
836
+ except exceptions.CosmosHttpResponseError as e:
837
+ return False, f"HTTP error occurred: {str(e)} 🚨"
838
+ except Exception as e:
839
+ return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
840
+
841
+ def delete_record(container, name, id):
842
+ # πŸ—‘οΈ Deleting a recordβ€”sending it into the cosmic void! 🌌
843
+ try:
844
+ container.delete_item(item=id, partition_key=id)
845
+ return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
846
+ except exceptions.CosmosResourceNotFoundError:
847
+ return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
848
+ except exceptions.CosmosHttpResponseError as e:
849
+ return False, f"HTTP error occurred: {str(e)} 🚨"
850
+ except Exception as e:
851
+ return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
852
+
853
+ # 🎲 Function to generate a unique UUID
854
+ def generate_unique_id():
855
+ # πŸ§™β€β™‚οΈ Generating a unique UUID!
856
+ return str(uuid.uuid4())
857
+
858
+ # πŸ“¦ Function to archive current container
859
+ def archive_current_container(database_name, container_name, client):
860
+ # πŸ“¦ Archiving the entire containerβ€”time to pack up the stars! 🌠
861
+ try:
862
+ base_dir = "./cosmos_archive_current_container"
863
+ if os.path.exists(base_dir):
864
+ shutil.rmtree(base_dir)
865
+ os.makedirs(base_dir)
866
+
867
+ db_client = client.get_database_client(database_name)
868
+ container_client = db_client.get_container_client(container_name)
869
+ items = list(container_client.read_all_items())
870
+
871
+ container_dir = os.path.join(base_dir, container_name)
872
+ os.makedirs(container_dir)
873
+
874
+ for item in items:
875
+ item_id = item.get('id', f"unknown_{datetime.now().strftime('%Y%m%d%H%M%S')}")
876
+ with open(os.path.join(container_dir, f"{item_id}.json"), 'w') as f:
877
+ json.dump(item, f, indent=2)
878
+
879
+ archive_name = f"{container_name}_archive_{datetime.now().strftime('%Y%m%d%H%M%S')}"
880
+ shutil.make_archive(archive_name, 'zip', base_dir)
881
+
882
+ return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
883
+ except Exception as e:
884
+ return f"An error occurred while archiving data: {str(e)} 😒"
885
+
886
+
887
+ # πŸ”— Helper to extract hyperlinks
888
+ def extract_hyperlinks(responses):
889
+ # πŸ”— Extracting hyperlinksβ€”connecting the dots across the universe! πŸ•ΈοΈ
890
+ hyperlinks = []
891
+ for response in responses:
892
+ parsed_response = json.loads(response)
893
+ links = [value for key, value in parsed_response.items() if isinstance(value, str) and value.startswith("http")]
894
+ hyperlinks.extend(links)
895
+ return hyperlinks
896
+
897
+ # πŸ“‹ Helper to format text with line numbers
898
+ def format_with_line_numbers(text):
899
+ # πŸ“‹ Formatting text with line numbersβ€”organizing the cosmos one line at a time! πŸ“
900
+ lines = text.splitlines()
901
+ formatted_text = '\n'.join(f"{i+1}: {line}" for i, line in enumerate(lines))
902
+ return formatted_text
903
+
904
+
905
+ def generate_unique_id():
906
+ return str(uuid.uuid4())
907
+
908
+ def get_databases(client):
909
+ return [db['id'] for db in client.list_databases()]
910
+
911
+ def get_containers(database):
912
+ return [container['id'] for container in database.list_containers()]
913
+
914
+ def get_documents(container, limit=None):
915
+ query = "SELECT * FROM c ORDER BY c._ts DESC"
916
+ items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
917
+ return items
918
+
919
+ def save_to_cosmos_db(container, query, response1, response2):
920
+ try:
921
+ if container:
922
+ record = {
923
+ "id": generate_unique_id(),
924
+ "query": query,
925
+ "response1": response1,
926
+ "response2": response2
927
+ }
928
+ try:
929
+ container.create_item(body=record)
930
+ st.success(f"Record saved successfully with ID: {record['id']}")
931
+ # Refresh the documents display
932
+ st.session_state.documents = get_documents(container)
933
+ except exceptions.CosmosHttpResponseError as e:
934
+ st.error(f"Error saving record to Cosmos DB: {e}")
935
+ else:
936
+ st.error("Cosmos DB container is not initialized.")
937
+ except Exception as e:
938
+ st.error(f"An unexpected error occurred: {str(e)}")
939
+
940
+ # Add dropdowns for model and database choices
941
+ def search_glossary(query):
942
+ st.markdown(f"### πŸ” Search Glossary for: `{query}`")
943
+
944
+ # Dropdown for model selection
945
+ model_options = ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None']
946
+ model_choice = st.selectbox('🧠 Select LLM Model', options=model_options, index=1)
947
+
948
+ # Dropdown for database selection
949
+ database_options = ['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)']
950
+ database_choice = st.selectbox('πŸ“š Select Database', options=database_options, index=0)
951
+
952
+
953
+
954
+ # Run Button with Emoji
955
+ #if st.button("πŸš€ Run"):
956
+
957
+ # πŸ•΅οΈβ€β™‚οΈ Searching the glossary for: query
958
+ all_results = ""
959
+ st.markdown(f"- {query}")
960
+
961
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM
962
+ #database_choice Literal['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)'] Default: "Semantic Search"
963
+ #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"
964
+ client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
965
+
966
+
967
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
968
+ result = client.predict(
969
+ prompt=query,
970
+ llm_model_picked="mistralai/Mixtral-8x7B-Instruct-v0.1",
971
+ stream_outputs=True,
972
+ api_name="/ask_llm"
973
+ )
974
+ st.markdown(result)
975
+ st.code(result, language="python", line_numbers=True)
976
+
977
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
978
+ result2 = client.predict(
979
+ prompt=query,
980
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
981
+ stream_outputs=True,
982
+ api_name="/ask_llm"
983
+ )
984
+ st.markdown(result2)
985
+ st.code(result2, language="python", line_numbers=True)
986
+
987
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
988
+ result3 = client.predict(
989
+ prompt=query,
990
+ llm_model_picked="google/gemma-7b-it",
991
+ stream_outputs=True,
992
+ api_name="/ask_llm"
993
+ )
994
+ st.markdown(result3)
995
+ st.code(result3, language="python", line_numbers=True)
996
+
997
+
998
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /update_with_rag_md
999
+ response2 = client.predict(
1000
+ message=query, # str in 'parameter_13' Textbox component
1001
+ llm_results_use=10,
1002
+ database_choice="Semantic Search",
1003
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
1004
+ api_name="/update_with_rag_md"
1005
+ ) # update_with_rag_md Returns tuple of 2 elements [0] str The output value that appears in the "value_14" Markdown component. [1] str
1006
+
1007
+ st.markdown(response2[0])
1008
+ st.code(response2[0], language="python", line_numbers=True, wrap_lines=True)
1009
+
1010
+ st.markdown(response2[1])
1011
+ st.code(response2[1], language="python", line_numbers=True, wrap_lines=True)
1012
+
1013
+ # When saving results, pass the container
1014
+ try:
1015
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result, result)
1016
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result2, result2)
1017
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result3, result3)
1018
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[0], response2[0])
1019
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[1], response2[1])
1020
+ except exceptions.CosmosHttpResponseError as e:
1021
+ return False, f"HTTP error occurred: {str(e)} 🚨"
1022
+ except Exception as e:
1023
+ return False, f"An unexpected error occurred: {str(e)} 😱"
1024
+
1025
+
1026
+ try:
1027
+ # Aggregate hyperlinks and show with emojis
1028
+ hyperlinks = extract_hyperlinks([response1, response2])
1029
+ st.markdown("### πŸ”— Aggregated Hyperlinks")
1030
+ for link in hyperlinks:
1031
+ st.markdown(f"πŸ”— [{link}]({link})")
1032
+
1033
+ # Show responses in a code format with line numbers
1034
+ st.markdown("### πŸ“œ Response Outputs with Line Numbers")
1035
+ st.code(f"Response 1: \n{format_with_line_numbers(response1)}\n\nResponse 2: \n{format_with_line_numbers(response2)}", language="json")
1036
+ except exceptions.CosmosHttpResponseError as e:
1037
+ return False, f"HTTP error occurred: {str(e)} 🚨"
1038
+ except Exception as e:
1039
+ return False, f"An unexpected error occurred: {str(e)} 😱"
1040
+
1041
+
1042
+
1043
+
1044
+ # 🎀 Function to process text input
1045
+ def process_text(text_input):
1046
+ # 🎀 Processing text inputβ€”translating human words into cosmic signals! πŸ“‘
1047
+ if text_input:
1048
+ if 'messages' not in st.session_state:
1049
+ st.session_state.messages = []
1050
+
1051
+ st.session_state.messages.append({"role": "user", "content": text_input})
1052
+
1053
+ with st.chat_message("user"):
1054
+ st.markdown(text_input)
1055
+
1056
+ with st.chat_message("assistant"):
1057
+ search_glossary(text_input)
1058
+
1059
+ # πŸ“ Function to generate a filename
1060
+ def generate_filename(text, file_type):
1061
+ # πŸ“ Generate a filename based on the text input
1062
+ safe_text = "".join(c if c.isalnum() or c in (' ', '.', '_') else '_' for c in text)
1063
+ safe_text = "_".join(safe_text.strip().split())
1064
+ filename = f"{safe_text}.{file_type}"
1065
+ return filename
1066
+
1067
+ # πŸ•΅οΈβ€β™€οΈ Function to extract markdown title
1068
+ def extract_markdown_title(content):
1069
+ # πŸ•΅οΈβ€β™€οΈ Extracting markdown titleβ€”finding the headline in the cosmic news! πŸ“°
1070
+ lines = content.splitlines()
1071
+ for line in lines:
1072
+ if line.startswith('#'):
1073
+ return line.lstrip('#').strip()
1074
+ return None
1075
+
1076
+ # πŸ’Ύ Function to create and save a file
1077
+ def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
1078
+ # πŸ’Ύ Creating and saving a fileβ€”capturing cosmic wisdom! πŸ“
1079
+ if not should_save:
1080
+ return None
1081
+
1082
+ # Step 1: Generate filename based on the prompt or content
1083
+ filename = generate_filename(prompt if prompt else content, file_type)
1084
+
1085
+ # Step 2: If it's a markdown file, check if it has a title
1086
+ if file_type == "md":
1087
+ title_from_content = extract_markdown_title(content)
1088
+ if title_from_content:
1089
+ filename = generate_filename(title_from_content, file_type)
1090
+
1091
+ # Step 3: Save the file
1092
+ with open(filename, "w", encoding="utf-8") as f:
1093
+ if is_image:
1094
+ f.write(content)
1095
+ else:
1096
+ f.write(prompt + "\n\n" + content)
1097
+
1098
+ return filename
1099
+
1100
+ # πŸ€– Function to insert an auto-generated record
1101
+ def insert_auto_generated_record(container):
1102
+ # πŸ€– Automatically generating a record and inserting it into Cosmos DB!
1103
+ try:
1104
+ # Generate a unique id
1105
+ new_id = generate_unique_id()
1106
+ # Create a sample JSON document
1107
+ new_doc = {
1108
+ 'id': new_id,
1109
+ 'name': f'Sample Name {new_id[:8]}',
1110
+ 'description': 'This is a sample auto-generated description.',
1111
+ 'timestamp': datetime.utcnow().isoformat()
1112
+ }
1113
+ # Insert the document
1114
+ container.create_item(body=new_doc)
1115
+ return True, f"Record inserted successfully with id: {new_id} πŸŽ‰"
1116
+ except exceptions.CosmosHttpResponseError as e:
1117
+ return False, f"HTTP error occurred: {str(e)} 🚨"
1118
+ except Exception as e:
1119
+ return False, f"An unexpected error occurred: {str(e)} 😱"
1120
+
1121
+ # 🎈 Main function
1122
+ def main2():
1123
+ # 🎈 Let's modify the main app to be more fun!
1124
+ st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
1125
+
1126
+ # 🚦 Initialize session state
1127
+ if 'logged_in' not in st.session_state:
1128
+ st.session_state.logged_in = False
1129
+ if 'selected_records' not in st.session_state:
1130
+ st.session_state.selected_records = []
1131
+ if 'client' not in st.session_state:
1132
+ st.session_state.client = None
1133
+ if 'selected_database' not in st.session_state:
1134
+ st.session_state.selected_database = None
1135
+ if 'selected_container' not in st.session_state:
1136
+ st.session_state.selected_container = None
1137
+ if 'selected_document_id' not in st.session_state:
1138
+ st.session_state.selected_document_id = None
1139
+ if 'current_index' not in st.session_state:
1140
+ st.session_state.current_index = 0
1141
+ if 'cloned_doc' not in st.session_state:
1142
+ st.session_state.cloned_doc = None
1143
+
1144
+ # βš™οΈ q= Run ArXiv search from query parameters
1145
+ try:
1146
+ query_params = st.query_params
1147
+ query = query_params.get('q') or query_params.get('query') or ''
1148
+ if query:
1149
+ # πŸ•΅οΈβ€β™‚οΈ We have a query! Let's process it!
1150
+ process_text(query)
1151
+ st.stop() # Stop further execution
1152
+ except Exception as e:
1153
+ st.markdown(' ')
1154
+
1155
+ # πŸ” Automatic Login
1156
+ if Key:
1157
+ st.session_state.primary_key = Key
1158
+ st.session_state.logged_in = True
1159
+ else:
1160
+ st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
1161
+ return # Can't proceed without a key
1162
+
1163
+ if st.session_state.logged_in:
1164
+ # 🌌 Initialize Cosmos DB client
1165
+ try:
1166
+ if st.session_state.client is None:
1167
+ st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
1168
+
1169
+ # πŸ—„οΈ Sidebar for database, container, and document selection
1170
+ st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
1171
+
1172
+ databases = get_databases(st.session_state.client)
1173
+ selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
1174
+
1175
+ if selected_db != st.session_state.selected_database:
1176
+ st.session_state.selected_database = selected_db
1177
+ st.session_state.selected_container = None
1178
+ st.session_state.selected_document_id = None
1179
+ st.session_state.current_index = 0
1180
+ st.rerun()
1181
+
1182
+ if st.session_state.selected_database:
1183
+ database = st.session_state.client.get_database_client(st.session_state.selected_database)
1184
+ containers = get_containers(database)
1185
+ selected_container = st.sidebar.selectbox("πŸ“ Select Container", containers)
1186
+
1187
+ if selected_container != st.session_state.selected_container:
1188
+ st.session_state.selected_container = selected_container
1189
+ st.session_state.selected_document_id = None
1190
+ st.session_state.current_index = 0
1191
+ st.rerun()
1192
+
1193
+ if st.session_state.selected_container:
1194
+ container = database.get_container_client(st.session_state.selected_container)
1195
+
1196
+ # πŸ“¦ Add Export button
1197
+ if st.button("πŸ“¦ Export Container Data"):
1198
+ download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
1199
+ if download_link.startswith('<a'):
1200
+ st.markdown(download_link, unsafe_allow_html=True)
1201
+ else:
1202
+ st.error(download_link)
1203
+
1204
+ # Fetch documents
1205
+ documents = get_documents(container)
1206
+ total_docs = len(documents)
1207
+
1208
+ if total_docs > 5:
1209
+ documents_to_display = documents[:5]
1210
+ st.info("Showing top 5 most recent documents.")
1211
+ else:
1212
+ documents_to_display = documents
1213
+ st.info(f"Showing all {len(documents_to_display)} documents.")
1214
+
1215
+ if documents_to_display:
1216
+ # 🎨 Add Viewer/Editor selection
1217
+ view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
1218
+ selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
1219
+
1220
+ if selected_view == 'Show as Markdown':
1221
+ # πŸ–ŒοΈ Show each record as Markdown with navigation
1222
+ total_docs = len(documents)
1223
+ doc = documents[st.session_state.current_index]
1224
+ st.markdown(f"#### Document ID: {doc.get('id', '')}")
1225
+
1226
+ # πŸ•΅οΈβ€β™‚οΈ Let's extract values from the JSON that have at least one space
1227
+ values_with_space = []
1228
+ def extract_values(obj):
1229
+ if isinstance(obj, dict):
1230
+ for k, v in obj.items():
1231
+ extract_values(v)
1232
+ elif isinstance(obj, list):
1233
+ for item in obj:
1234
+ extract_values(item)
1235
+ elif isinstance(obj, str):
1236
+ if ' ' in obj:
1237
+ values_with_space.append(obj)
1238
+
1239
+ extract_values(doc)
1240
+
1241
+ # πŸ”— Let's create a list of links for these values
1242
+ search_urls = {
1243
+ "πŸš€πŸŒŒArXiv": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}",
1244
+ "πŸƒAnalyst": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix')}",
1245
+ "πŸ“šPyCoder": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix2')}",
1246
+ "πŸ”¬JSCoder": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}-{quote('PromptPrefix3')}",
1247
+ "🏠": lambda k: f"{LOCAL_APP_URL}/?q={quote(k)}",
1248
+ "πŸ“–": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
1249
+ "πŸ”": lambda k: f"https://www.google.com/search?q={quote(k)}",
1250
+ "▢️": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
1251
+ "πŸ”Ž": lambda k: f"https://www.bing.com/search?q={quote(k)}",
1252
+ "πŸŽ₯": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
1253
+ "🐦": lambda k: f"https://twitter.com/search?q={quote(k)}",
1254
+ }
1255
+
1256
+ st.markdown("#### πŸ”— Links for Extracted Texts")
1257
+ for term in values_with_space:
1258
+ links_md = ' '.join([f"[{emoji}]({url(term)})" for emoji, url in search_urls.items()])
1259
+ st.markdown(f"**{term}** <small>{links_md}</small>", unsafe_allow_html=True)
1260
+
1261
+ # Show the document content as markdown
1262
+ content = json.dumps(doc, indent=2)
1263
+ st.markdown(f"```json\n{content}\n```")
1264
+
1265
+ # Navigation buttons
1266
+ col_prev, col_next = st.columns([1, 1])
1267
+ with col_prev:
1268
+ if st.button("⬅️ Previous", key='prev_markdown'):
1269
+ if st.session_state.current_index > 0:
1270
+ st.session_state.current_index -= 1
1271
+ st.rerun()
1272
+ with col_next:
1273
+ if st.button("➑��� Next", key='next_markdown'):
1274
+ if st.session_state.current_index < total_docs - 1:
1275
+ st.session_state.current_index += 1
1276
+ st.rerun()
1277
+
1278
+ elif selected_view == 'Show as Code Editor':
1279
+ # πŸ’» Show each record in a code editor with navigation
1280
+ total_docs = len(documents)
1281
+ doc = documents[st.session_state.current_index]
1282
+ st.markdown(f"#### Document ID: {doc.get('id', '')}")
1283
+ doc_str = st.text_area("Edit Document", value=json.dumps(doc, indent=2), height=300, key=f'code_editor_{st.session_state.current_index}')
1284
+ col_prev, col_next = st.columns([1, 1])
1285
+ with col_prev:
1286
+ if st.button("⬅️ Previous", key='prev_code'):
1287
+ if st.session_state.current_index > 0:
1288
+ st.session_state.current_index -= 1
1289
+ st.rerun()
1290
+ with col_next:
1291
+ if st.button("➑️ Next", key='next_code'):
1292
+ if st.session_state.current_index < total_docs - 1:
1293
+ st.session_state.current_index += 1
1294
+ st.rerun()
1295
+ if st.button("πŸ’Ύ Save Changes", key=f'save_button_{st.session_state.current_index}'):
1296
+ try:
1297
+ updated_doc = json.loads(doc_str)
1298
+ success, message = update_record(container, updated_doc)
1299
+ if success:
1300
+ st.success(f"Document {updated_doc['id']} saved successfully.")
1301
+ st.session_state.selected_document_id = updated_doc['id']
1302
+ st.rerun()
1303
+ else:
1304
+ st.error(message)
1305
+ except json.JSONDecodeError as e:
1306
+ st.error(f"Invalid JSON: {str(e)} 🚫")
1307
+
1308
+ elif selected_view == 'Show as Edit and Save':
1309
+ # ✏️ Show as Edit and Save in columns
1310
+ st.markdown("#### Edit the document fields below:")
1311
+
1312
+ # Create columns for each document
1313
+ num_cols = len(documents_to_display)
1314
+ cols = st.columns(num_cols)
1315
+
1316
+
1317
+ for idx, (col, doc) in enumerate(zip(cols, documents_to_display)):
1318
+ with col:
1319
+ st.markdown(f"##### Document ID: {doc.get('id', '')}")
1320
+ editable_id = st.text_input("ID", value=doc.get('id', ''), key=f'edit_id_{idx}')
1321
+ # Remove 'id' from the document for editing other fields
1322
+ editable_doc = doc.copy()
1323
+ editable_doc.pop('id', None)
1324
+ doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300, key=f'doc_str_{idx}')
1325
+
1326
+ # Add the "Run With AI" button next to "Save Changes"
1327
+ col_save, col_ai = st.columns(2)
1328
+ with col_save:
1329
+ if st.button("πŸ’Ύ Save Changes", key=f'save_button_{idx}'):
1330
+ try:
1331
+ updated_doc = json.loads(doc_str)
1332
+ updated_doc['id'] = editable_id # Include the possibly edited ID
1333
+ success, message = update_record(container, updated_doc)
1334
+ if success:
1335
+ st.success(f"Document {updated_doc['id']} saved successfully.")
1336
+ st.session_state.selected_document_id = updated_doc['id']
1337
+ st.rerun()
1338
+ else:
1339
+ st.error(message)
1340
+ except json.JSONDecodeError as e:
1341
+ st.error(f"Invalid JSON: {str(e)} 🚫")
1342
+ with col_ai:
1343
+ if st.button("οΏ½οΏ½οΏ½ Run With AI", key=f'run_with_ai_button_{idx}'):
1344
+ # Use the entire document as input
1345
+ search_glossary(json.dumps(editable_doc, indent=2))
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+ elif selected_view == 'Clone Document':
1352
+ # 🧬 Clone Document per record
1353
+ st.markdown("#### Clone a document:")
1354
+ for idx, doc in enumerate(documents_to_display):
1355
+ st.markdown(f"##### Document ID: {doc.get('id', '')}")
1356
+ if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
1357
+ cloned_doc = doc.copy()
1358
+ # Generate a unique ID
1359
+ cloned_doc['id'] = generate_unique_id()
1360
+ st.session_state.cloned_doc = cloned_doc
1361
+ st.session_state.cloned_doc_str = json.dumps(cloned_doc, indent=2)
1362
+ st.session_state.clone_mode = True
1363
+ st.rerun()
1364
+ if st.session_state.get('clone_mode', False):
1365
+ st.markdown("#### Edit Cloned Document:")
1366
+ cloned_doc_str = st.text_area("Cloned Document Content (in JSON format)", value=st.session_state.cloned_doc_str, height=300)
1367
+ if st.button("πŸ’Ύ Save Cloned Document"):
1368
+ try:
1369
+ new_doc = json.loads(cloned_doc_str)
1370
+ success, message = insert_record(container, new_doc)
1371
+ if success:
1372
+ st.success(f"Cloned document saved with id: {new_doc['id']} πŸŽ‰")
1373
+ st.session_state.selected_document_id = new_doc['id']
1374
+ st.session_state.clone_mode = False
1375
+ st.session_state.cloned_doc = None
1376
+ st.session_state.cloned_doc_str = ''
1377
+ st.rerun()
1378
+ else:
1379
+ st.error(message)
1380
+ except json.JSONDecodeError as e:
1381
+ st.error(f"Invalid JSON: {str(e)} 🚫")
1382
+
1383
+ elif selected_view == 'New Record':
1384
+ # πŸ†• New Record
1385
+ st.markdown("#### Create a new document:")
1386
+ if st.button("πŸ€– Insert Auto-Generated Record"):
1387
+ success, message = insert_auto_generated_record(container)
1388
+ if success:
1389
+ st.success(message)
1390
+ st.rerun()
1391
+ else:
1392
+ st.error(message)
1393
+ else:
1394
+ new_id = st.text_input("ID", value=generate_unique_id(), key='new_id')
1395
+ new_doc_str = st.text_area("Document Content (in JSON format)", value='{}', height=300)
1396
+ if st.button("βž• Create New Document"):
1397
+ try:
1398
+ new_doc = json.loads(new_doc_str)
1399
+ new_doc['id'] = new_id # Use the provided ID
1400
+ success, message = insert_record(container, new_doc)
1401
+ if success:
1402
+ st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
1403
+ st.session_state.selected_document_id = new_doc['id']
1404
+ # Switch to 'Show as Edit and Save' mode
1405
+ st.rerun()
1406
+ else:
1407
+ st.error(message)
1408
+ except json.JSONDecodeError as e:
1409
+ st.error(f"Invalid JSON: {str(e)} 🚫")
1410
+
1411
+ else:
1412
+ st.sidebar.info("No documents found in this container. πŸ“­")
1413
+
1414
+ # πŸŽ‰ Main content area
1415
+ st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
1416
+ if st.session_state.selected_container:
1417
+ if documents_to_display:
1418
+ df = pd.DataFrame(documents_to_display)
1419
+ st.dataframe(df)
1420
+ else:
1421
+ st.info("No documents to display. 🧐")
1422
+
1423
+ # πŸ™ GitHub section
1424
+ st.subheader("πŸ™ GitHub Operations")
1425
+ github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
1426
+ source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
1427
+ new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
1428
+
1429
+ col1, col2 = st.columns(2)
1430
+ with col1:
1431
+ if st.button("πŸ“₯ Clone Repository"):
1432
+ if github_token and source_repo:
1433
+ try:
1434
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d%H%M%S')}"
1435
+ download_github_repo(source_repo, local_path)
1436
+ zip_filename = f"{new_repo_name}.zip"
1437
+ create_zip_file(local_path, zip_filename[:-4])
1438
+ st.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
1439
+ st.success("Repository cloned successfully! πŸŽ‰")
1440
+ except Exception as e:
1441
+ st.error(f"An error occurred: {str(e)} 😒")
1442
+ finally:
1443
+ if os.path.exists(local_path):
1444
+ shutil.rmtree(local_path)
1445
+ if os.path.exists(zip_filename):
1446
+ os.remove(zip_filename)
1447
+ else:
1448
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
1449
+
1450
+ with col2:
1451
+ if st.button("πŸ“€ Push to New Repository"):
1452
+ if github_token and source_repo:
1453
+ try:
1454
+ g = Github(github_token)
1455
+ new_repo = create_repo(g, new_repo_name)
1456
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d%H%M%S')}"
1457
+ download_github_repo(source_repo, local_path)
1458
+ push_to_github(local_path, new_repo, github_token)
1459
+ st.success(f"Repository pushed successfully to {new_repo.html_url} πŸš€")
1460
+ except Exception as e:
1461
+ st.error(f"An error occurred: {str(e)} 😒")
1462
+ finally:
1463
+ if os.path.exists(local_path):
1464
+ shutil.rmtree(local_path)
1465
+ else:
1466
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
1467
+
1468
+ except exceptions.CosmosHttpResponseError as e:
1469
+ st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)} 🚨")
1470
+ except Exception as e:
1471
+ st.error(f"An unexpected error occurred: {str(e)} 😱")
1472
+
1473
+ # πŸšͺ Logout button
1474
+ if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
1475
+ st.session_state.logged_in = False
1476
+ st.session_state.selected_records.clear()
1477
+ st.session_state.client = None
1478
+ st.session_state.selected_database = None
1479
+ st.session_state.selected_container = None
1480
+ st.session_state.selected_document_id = None
1481
+ st.session_state.current_index = 0
1482
+ st.rerun()
1483
+
1484
 
1485
 
1486