awacke1 commited on
Commit
734c984
β€’
1 Parent(s): d3ee196

Create backup8.ColumbusBurnedtheShips.py

Browse files
Files changed (1) hide show
  1. backup8.ColumbusBurnedtheShips.py +861 -0
backup8.ColumbusBurnedtheShips.py ADDED
@@ -0,0 +1,861 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
13
+ from urllib.parse import quote
14
+ from gradio_client import Client
15
+ import anthropic
16
+ import glob
17
+ 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'
27
+ bugURL = 'https://huggingface.co/spaces/awacke1'
28
+ icons = 'πŸ™πŸŒŒπŸ’«'
29
+
30
+ st.set_page_config(
31
+ page_title=title,
32
+ page_icon=icons,
33
+ layout="wide",
34
+ initial_sidebar_state="auto",
35
+ menu_items={
36
+ 'Get Help': helpURL,
37
+ 'Report a bug': bugURL,
38
+ 'About': title
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()
62
+ b64 = base64.b64encode(contents).decode()
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)}",
93
+ "πŸ“–": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
94
+ "πŸ”": lambda k: f"https://www.google.com/search?q={quote(k)}",
95
+ "πŸŽ₯": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
96
+ }
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:
103
+ for file in 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'''
110
+ <video width="{width}" controls autoplay loop>
111
+ <source src="{video_url}" type="video/mp4">
112
+ Your browser does not support the video tag.
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'''
119
+ <audio controls style="width:{width}">
120
+ <source src="{audio_url}" type="audio/mpeg">
121
+ Your browser does not support the audio element.
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)
140
+ return True, "Record inserted successfully! πŸŽ‰"
141
+ except exceptions.CosmosHttpResponseError as e:
142
+ return False, f"HTTP error occurred: {str(e)} 🚨"
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)
149
+ return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΏ½οΏ½οΏ½"
150
+ except exceptions.CosmosHttpResponseError as e:
151
+ return False, f"HTTP error occurred: {str(e)} 🚨"
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)
158
+ return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
159
+ except exceptions.CosmosResourceNotFoundError:
160
+ return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
161
+ except exceptions.CosmosHttpResponseError as e:
162
+ return False, f"HTTP error occurred: {str(e)} 🚨"
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
+
172
+ def save_to_cosmos_db(container, query, response1, response2):
173
+ max_retries = 5
174
+ base_wait_time = 0.1 # 100 ms
175
+
176
+ def generate_unique_id():
177
+ timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')
178
+ unique_uuid = str(uuid.uuid4())
179
+ return f"{timestamp}-{unique_uuid}"
180
+
181
+ for attempt in range(max_retries):
182
+ try:
183
+ if container:
184
+ base_id = generate_unique_id()
185
+ record = {
186
+ "id": base_id,
187
+ "query": query,
188
+ "response1": response1,
189
+ "response2": response2,
190
+ "timestamp": datetime.utcnow().isoformat()
191
+ }
192
+
193
+ # Check if document with this ID exists
194
+ try:
195
+ existing_doc = container.read_item(item=base_id, partition_key=base_id)
196
+ # If it exists, append a random string to the ID
197
+ record["id"] = f"{base_id}-{str(uuid.uuid4())[:8]}"
198
+ except exceptions.CosmosResourceNotFoundError:
199
+ # If it doesn't exist, we can use the original ID
200
+ pass
201
+
202
+ container.upsert_item(body=record)
203
+ st.success(f"Record saved successfully with ID: {record['id']}")
204
+ st.session_state.documents = container.query_items(
205
+ query="SELECT * FROM c ORDER BY c._ts DESC",
206
+ enable_cross_partition_query=True
207
+ )
208
+ return
209
+ else:
210
+ st.error("Cosmos DB container is not initialized.")
211
+ return
212
+ except exceptions.CosmosHttpResponseError as e:
213
+ if e.status_code == 409: # Conflict error
214
+ wait_time = (2 ** attempt) * base_wait_time
215
+ st.warning(f"ID conflict occurred. Retrying in {wait_time:.2f} seconds... (Attempt {attempt + 1})")
216
+ time.sleep(wait_time)
217
+ else:
218
+ st.error(f"Error saving record to Cosmos DB: {e}")
219
+ return
220
+ except Exception as e:
221
+ st.error(f"An unexpected error occurred: {str(e)}")
222
+ return
223
+
224
+ st.error("Failed to save record after maximum retries.")
225
+
226
+
227
+
228
+ # Add dropdowns for model and database choices
229
+ def search_glossary(query):
230
+ st.markdown(f"### πŸ” Search Glossary for: `{query}`")
231
+
232
+ # Dropdown for model selection
233
+ model_options = ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'mistralai/Mistral-7B-Instruct-v0.2', 'google/gemma-7b-it', 'None']
234
+ model_choice = st.selectbox('🧠 Select LLM Model', options=model_options, index=1)
235
+
236
+ # Dropdown for database selection
237
+ database_options = ['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)']
238
+ database_choice = st.selectbox('πŸ“š Select Database', options=database_options, index=0)
239
+
240
+
241
+
242
+ # Run Button with Emoji
243
+ #if st.button("πŸš€ Run"):
244
+
245
+ # πŸ•΅οΈβ€β™‚οΈ Searching the glossary for: query
246
+ all_results = ""
247
+ st.markdown(f"- {query}")
248
+
249
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM
250
+ #database_choice Literal['Semantic Search', 'Arxiv Search - Latest - (EXPERIMENTAL)'] Default: "Semantic Search"
251
+ #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"
252
+ client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
253
+
254
+
255
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
256
+ result = client.predict(
257
+ prompt=query,
258
+ llm_model_picked="mistralai/Mixtral-8x7B-Instruct-v0.1",
259
+ stream_outputs=True,
260
+ api_name="/ask_llm"
261
+ )
262
+ st.markdown(result)
263
+ st.code(result, language="python", line_numbers=True)
264
+
265
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
266
+ result2 = client.predict(
267
+ prompt=query,
268
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
269
+ stream_outputs=True,
270
+ api_name="/ask_llm"
271
+ )
272
+ st.markdown(result2)
273
+ st.code(result2, language="python", line_numbers=True)
274
+
275
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /ask_llm
276
+ result3 = client.predict(
277
+ prompt=query,
278
+ llm_model_picked="google/gemma-7b-it",
279
+ stream_outputs=True,
280
+ api_name="/ask_llm"
281
+ )
282
+ st.markdown(result3)
283
+ st.code(result3, language="python", line_numbers=True)
284
+
285
+
286
+ # πŸ” ArXiv RAG researcher expert ~-<>-~ Paper Summary & Ask LLM - api_name: /update_with_rag_md
287
+ response2 = client.predict(
288
+ message=query, # str in 'parameter_13' Textbox component
289
+ llm_results_use=10,
290
+ database_choice="Semantic Search",
291
+ llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
292
+ api_name="/update_with_rag_md"
293
+ ) # update_with_rag_md Returns tuple of 2 elements [0] str The output value that appears in the "value_14" Markdown component. [1] str
294
+
295
+ st.markdown(response2[0])
296
+ st.code(response2[0], language="python", line_numbers=True, wrap_lines=True)
297
+
298
+ st.markdown(response2[1])
299
+ st.code(response2[1], language="python", line_numbers=True, wrap_lines=True)
300
+
301
+ # When saving results, pass the container
302
+ try:
303
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result, result)
304
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result2, result2)
305
+ save_to_cosmos_db(st.session_state.cosmos_container, query, result3, result3)
306
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[0], response2[0])
307
+ save_to_cosmos_db(st.session_state.cosmos_container, query, response2[1], response2[1])
308
+ except exceptions.CosmosHttpResponseError as e:
309
+ return False, f"HTTP error occurred: {str(e)} 🚨"
310
+ except Exception as e:
311
+ return False, f"An unexpected error occurred: {str(e)} 😱"
312
+
313
+
314
+ try:
315
+ # Aggregate hyperlinks and show with emojis
316
+ hyperlinks = extract_hyperlinks([response1, response2])
317
+ st.markdown("### πŸ”— Aggregated Hyperlinks")
318
+ for link in hyperlinks:
319
+ st.markdown(f"πŸ”— [{link}]({link})")
320
+
321
+ # Show responses in a code format with line numbers
322
+ st.markdown("### πŸ“œ Response Outputs with Line Numbers")
323
+ st.code(f"Response 1: \n{format_with_line_numbers(response1)}\n\nResponse 2: \n{format_with_line_numbers(response2)}", language="json")
324
+ except exceptions.CosmosHttpResponseError as e:
325
+ return False, f"HTTP error occurred: {str(e)} 🚨"
326
+ except Exception as e:
327
+ return False, f"An unexpected error occurred: {str(e)} 😱"
328
+
329
+
330
+
331
+ # 🎀 Function to process text input
332
+ def process_text(text_input):
333
+ # 🎀 Processing text inputβ€”translating human words into cosmic signals! πŸ“‘
334
+ if text_input:
335
+ if 'messages' not in st.session_state:
336
+ st.session_state.messages = []
337
+
338
+ st.session_state.messages.append({"role": "user", "content": text_input})
339
+
340
+ with st.chat_message("user"):
341
+ st.markdown(text_input)
342
+
343
+ with st.chat_message("assistant"):
344
+ search_glossary(text_input)
345
+
346
+ # πŸ“ Function to generate a filename
347
+ def generate_filename(text, file_type):
348
+ # πŸ“ Generate a filename based on the text input
349
+ safe_text = "".join(c if c.isalnum() or c in (' ', '.', '_') else '_' for c in text)
350
+ safe_text = "_".join(safe_text.strip().split())
351
+ filename = f"{safe_text}.{file_type}"
352
+ return filename
353
+
354
+ # πŸ•΅οΈβ€β™€οΈ Function to extract markdown title
355
+ def extract_markdown_title(content):
356
+ # πŸ•΅οΈβ€β™€οΈ Extracting markdown titleβ€”finding the headline in the cosmic news! πŸ“°
357
+ lines = content.splitlines()
358
+ for line in lines:
359
+ if line.startswith('#'):
360
+ return line.lstrip('#').strip()
361
+ return None
362
+
363
+ # πŸ’Ύ Function to create and save a file
364
+ def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
365
+ # πŸ’Ύ Creating and saving a fileβ€”capturing cosmic wisdom! πŸ“
366
+ if not should_save:
367
+ return None
368
+
369
+ # Step 1: Generate filename based on the prompt or content
370
+ filename = generate_filename(prompt if prompt else content, file_type)
371
+
372
+ # Step 2: If it's a markdown file, check if it has a title
373
+ if file_type == "md":
374
+ title_from_content = extract_markdown_title(content)
375
+ if title_from_content:
376
+ filename = generate_filename(title_from_content, file_type)
377
+
378
+ # Step 3: Save the file
379
+ with open(filename, "w", encoding="utf-8") as f:
380
+ if is_image:
381
+ f.write(content)
382
+ else:
383
+ f.write(prompt + "\n\n" + content)
384
+
385
+ return filename
386
+
387
+ # πŸ€– Function to insert an auto-generated record
388
+ def insert_auto_generated_record(container):
389
+ # πŸ€– Automatically generating a record and inserting it into Cosmos DB!
390
+ try:
391
+ # Generate a unique id
392
+ new_id = generate_unique_id()
393
+ # Create a sample JSON document
394
+ new_doc = {
395
+ 'id': new_id,
396
+ 'name': f'Sample Name {new_id[:8]}',
397
+ 'description': 'This is a sample auto-generated description.',
398
+ 'timestamp': datetime.utcnow().isoformat()
399
+ }
400
+ # Insert the document
401
+ container.create_item(body=new_doc)
402
+ return True, f"Record inserted successfully with id: {new_id} πŸŽ‰"
403
+ except exceptions.CosmosHttpResponseError as e:
404
+ return False, f"HTTP error occurred: {str(e)} 🚨"
405
+ except Exception as e:
406
+ return False, f"An unexpected error occurred: {str(e)} 😱"
407
+
408
+
409
+
410
+ # GitHub functions
411
+ def download_github_repo(url, local_path):
412
+ if os.path.exists(local_path):
413
+ shutil.rmtree(local_path)
414
+ Repo.clone_from(url, local_path)
415
+
416
+ def create_zip_file(source_dir, output_filename):
417
+ shutil.make_archive(output_filename, 'zip', source_dir)
418
+
419
+ def create_repo(g, repo_name):
420
+ user = g.get_user()
421
+ return user.create_repo(repo_name)
422
+
423
+ def push_to_github(local_path, repo, github_token):
424
+ repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
425
+ local_repo = Repo(local_path)
426
+
427
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
428
+ origin = local_repo.remote('origin')
429
+ origin.set_url(repo_url)
430
+ else:
431
+ origin = local_repo.create_remote('origin', repo_url)
432
+
433
+ if not local_repo.heads:
434
+ local_repo.git.checkout('-b', 'main')
435
+ current_branch = 'main'
436
+ else:
437
+ current_branch = local_repo.active_branch.name
438
+
439
+ local_repo.git.add(A=True)
440
+
441
+ if local_repo.is_dirty():
442
+ local_repo.git.commit('-m', 'Initial commit')
443
+
444
+ origin.push(refspec=f'{current_branch}:{current_branch}')
445
+
446
+ # Main function
447
+ def main():
448
+ st.title("πŸ™Git🌌CosmosπŸ’« - Azure Cosmos DB and Github Agent")
449
+
450
+ # Initialize session state
451
+ if 'logged_in' not in st.session_state:
452
+ st.session_state.logged_in = False
453
+ if 'selected_records' not in st.session_state:
454
+ st.session_state.selected_records = []
455
+ if 'client' not in st.session_state:
456
+ st.session_state.client = None
457
+ if 'selected_database' not in st.session_state:
458
+ st.session_state.selected_database = None
459
+ if 'selected_container' not in st.session_state:
460
+ st.session_state.selected_container = None
461
+ if 'selected_document_id' not in st.session_state:
462
+ st.session_state.selected_document_id = None
463
+ if 'current_index' not in st.session_state:
464
+ st.session_state.current_index = 0
465
+ if 'cloned_doc' not in st.session_state:
466
+ st.session_state.cloned_doc = None
467
+
468
+ # βš™οΈ q= Run ArXiv search from query parameters
469
+ try:
470
+ query_params = st.query_params
471
+ query = query_params.get('q') or query_params.get('query') or ''
472
+ if query:
473
+ # πŸ•΅οΈβ€β™‚οΈ We have a query! Let's process it!
474
+ process_text(query)
475
+ st.stop() # Stop further execution
476
+ except Exception as e:
477
+ st.markdown(' ')
478
+
479
+ # Automatic Login
480
+ if Key:
481
+ st.session_state.primary_key = Key
482
+ st.session_state.logged_in = True
483
+ else:
484
+ st.error("Cosmos DB Key is not set in environment variables. πŸ”‘βŒ")
485
+ return
486
+
487
+ if st.session_state.logged_in:
488
+ # Initialize Cosmos DB client
489
+ try:
490
+ if st.session_state.client is None:
491
+ st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
492
+
493
+ # Sidebar for database, container, and document selection
494
+ st.sidebar.title("πŸ™Git🌌CosmosπŸ’«πŸ—„οΈNavigator")
495
+
496
+ databases = get_databases(st.session_state.client)
497
+ selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
498
+
499
+ if selected_db != st.session_state.selected_database:
500
+ st.session_state.selected_database = selected_db
501
+ st.session_state.selected_container = None
502
+ st.session_state.selected_document_id = None
503
+ st.session_state.current_index = 0
504
+ st.rerun()
505
+
506
+ if st.session_state.selected_database:
507
+ database = st.session_state.client.get_database_client(st.session_state.selected_database)
508
+ containers = get_containers(database)
509
+ selected_container = st.sidebar.selectbox("πŸ“ Select Container", containers)
510
+
511
+ if selected_container != st.session_state.selected_container:
512
+ st.session_state.selected_container = selected_container
513
+ st.session_state.selected_document_id = None
514
+ st.session_state.current_index = 0
515
+ st.rerun()
516
+
517
+ if st.session_state.selected_container:
518
+ container = database.get_container_client(st.session_state.selected_container)
519
+
520
+ # Add Export button
521
+ if st.button("πŸ“¦ Export Container Data"):
522
+ download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
523
+ if download_link.startswith('<a'):
524
+ st.markdown(download_link, unsafe_allow_html=True)
525
+ else:
526
+ st.error(download_link)
527
+
528
+ # Fetch documents
529
+ documents = get_documents(container)
530
+ total_docs = len(documents)
531
+
532
+ if total_docs > 5:
533
+ documents_to_display = documents[:5]
534
+ st.info("Showing top 5 most recent documents.")
535
+ else:
536
+ documents_to_display = documents
537
+ st.info(f"Showing all {len(documents_to_display)} documents.")
538
+
539
+ if documents_to_display:
540
+ # Add Viewer/Editor selection
541
+ view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
542
+ selected_view = st.selectbox("Select Viewer/Editor", view_options, index=2)
543
+
544
+ if selected_view == 'Show as Markdown':
545
+ # Show each record as Markdown with navigation
546
+ total_docs = len(documents)
547
+ doc = documents[st.session_state.current_index]
548
+ st.markdown(f"#### Document ID: {doc.get('id', '')}")
549
+
550
+ # Extract values from the JSON that have at least one space
551
+ values_with_space = []
552
+ def extract_values(obj):
553
+ if isinstance(obj, dict):
554
+ for k, v in obj.items():
555
+ extract_values(v)
556
+ elif isinstance(obj, list):
557
+ for item in obj:
558
+ extract_values(item)
559
+ elif isinstance(obj, str):
560
+ if ' ' in obj:
561
+ values_with_space.append(obj)
562
+
563
+ extract_values(doc)
564
+
565
+ # Create a list of links for these values
566
+ st.markdown("#### πŸ”— Links for Extracted Texts")
567
+ for term in values_with_space:
568
+ display_glossary_entity(term)
569
+
570
+ # Show the document content as markdown
571
+ content = json.dumps(doc, indent=2)
572
+ st.markdown(f"```json\n{content}\n```")
573
+
574
+ # Navigation buttons
575
+ col_prev, col_next = st.columns([1, 1])
576
+ with col_prev:
577
+ if st.button("⬅️ Previous", key='prev_markdown'):
578
+ if st.session_state.current_index > 0:
579
+ st.session_state.current_index -= 1
580
+ st.rerun()
581
+ with col_next:
582
+ if st.button("➑️ Next", key='next_markdown'):
583
+ if st.session_state.current_index < total_docs - 1:
584
+ st.session_state.current_index += 1
585
+ st.rerun()
586
+
587
+ elif selected_view == 'Show as Code Editor':
588
+ # Show each record in a code editor with navigation
589
+ total_docs = len(documents)
590
+ doc = documents[st.session_state.current_index]
591
+ st.markdown(f"#### Document ID: {doc.get('id', '')}")
592
+ doc_str = st.text_area("Edit Document", value=json.dumps(doc, indent=2), height=300, key=f'code_editor_{st.session_state.current_index}')
593
+ col_prev, col_next = st.columns([1, 1])
594
+ with col_prev:
595
+ if st.button("⬅️ Previous", key='prev_code'):
596
+ if st.session_state.current_index > 0:
597
+ st.session_state.current_index -= 1
598
+ st.rerun()
599
+ with col_next:
600
+ if st.button("➑️ Next", key='next_code'):
601
+ if st.session_state.current_index < total_docs - 1:
602
+ st.session_state.current_index += 1
603
+ st.rerun()
604
+ if st.button("πŸ’Ύ Save Changes", key=f'save_button_{st.session_state.current_index}'):
605
+ try:
606
+ updated_doc = json.loads(doc_str)
607
+ success, message = update_record(container, updated_doc)
608
+ if success:
609
+ st.success(f"Document {updated_doc['id']} saved successfully.")
610
+ st.session_state.selected_document_id = updated_doc['id']
611
+ st.rerun()
612
+ else:
613
+ st.error(message)
614
+ except json.JSONDecodeError as e:
615
+ st.error(f"Invalid JSON: {str(e)} 🚫")
616
+
617
+ elif selected_view == 'Show as Edit and Save':
618
+ # Show as Edit and Save in columns
619
+ st.markdown("#### Edit the document fields below:")
620
+
621
+ # Create columns for each document
622
+ num_cols = len(documents_to_display)
623
+ cols = st.columns(num_cols)
624
+
625
+ for idx, (col, doc) in enumerate(zip(cols, documents_to_display)):
626
+ with col:
627
+ st.markdown(f"##### Document ID: {doc.get('id', '')}")
628
+ editable_id = st.text_input("ID", value=doc.get('id', ''), key=f'edit_id_{idx}')
629
+ # Remove 'id' from the document for editing other fields
630
+ editable_doc = doc.copy()
631
+ editable_doc.pop('id', None)
632
+ doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300, key=f'doc_str_{idx}')
633
+
634
+ # Add the "Run With AI" button next to "Save Changes"
635
+ col_save, col_ai = st.columns(2)
636
+ with col_save:
637
+ if st.button("πŸ’Ύ Save Changes", key=f'save_button_{idx}'):
638
+ try:
639
+ updated_doc = json.loads(doc_str)
640
+ updated_doc['id'] = editable_id # Include the possibly edited ID
641
+ success, message = update_record(container, updated_doc)
642
+ if success:
643
+ st.success(f"Document {updated_doc['id']} saved successfully.")
644
+ st.session_state.selected_document_id = updated_doc['id']
645
+ st.rerun()
646
+ else:
647
+ st.error(message)
648
+ except json.JSONDecodeError as e:
649
+ st.error(f"Invalid JSON: {str(e)} 🚫")
650
+ with col_ai:
651
+ if st.button("πŸ€– Run With AI", key=f'run_with_ai_button_{idx}'):
652
+ # Use the entire document as input
653
+ search_glossary(json.dumps(editable_doc, indent=2))
654
+
655
+ elif selected_view == 'Clone Document':
656
+ # Clone Document per record
657
+ st.markdown("#### Clone a document:")
658
+ for idx, doc in enumerate(documents_to_display):
659
+ st.markdown(f"##### Document ID: {doc.get('id', '')}")
660
+ if st.button("πŸ“„ Clone Document", key=f'clone_button_{idx}'):
661
+ cloned_doc = doc.copy()
662
+ # Generate a unique ID
663
+ cloned_doc['id'] = generate_unique_id()
664
+ st.session_state.cloned_doc = cloned_doc
665
+ st.session_state.cloned_doc_str = json.dumps(cloned_doc, indent=2)
666
+ st.session_state.clone_mode = True
667
+ st.rerun()
668
+ if st.session_state.get('clone_mode', False):
669
+ st.markdown("#### Edit Cloned Document:")
670
+ cloned_doc_str = st.text_area("Cloned Document Content (in JSON format)", value=st.session_state.cloned_doc_str, height=300)
671
+ if st.button("πŸ’Ύ Save Cloned Document"):
672
+ try:
673
+ new_doc = json.loads(cloned_doc_str)
674
+ success, message = insert_record(container, new_doc)
675
+ if success:
676
+ st.success(f"Cloned document saved with id: {new_doc['id']} πŸŽ‰")
677
+ st.session_state.selected_document_id = new_doc['id']
678
+ st.session_state.clone_mode = False
679
+ st.session_state.cloned_doc = None
680
+ st.session_state.cloned_doc_str = ''
681
+ st.rerun()
682
+ else:
683
+ st.error(message)
684
+ except json.JSONDecodeError as e:
685
+ st.error(f"Invalid JSON: {str(e)} 🚫")
686
+
687
+ elif selected_view == 'New Record':
688
+ # New Record
689
+ st.markdown("#### Create a new document:")
690
+ if st.button("πŸ€– Insert Auto-Generated Record"):
691
+ success, message = insert_auto_generated_record(container)
692
+ if success:
693
+ st.success(message)
694
+ st.rerun()
695
+ else:
696
+ st.error(message)
697
+ else:
698
+ new_id = st.text_input("ID", value=generate_unique_id(), key='new_id')
699
+ new_doc_str = st.text_area("Document Content (in JSON format)", value='{}', height=300)
700
+ if st.button("βž• Create New Document"):
701
+ try:
702
+ new_doc = json.loads(new_doc_str)
703
+ new_doc['id'] = new_id # Use the provided ID
704
+ success, message = insert_record(container, new_doc)
705
+ if success:
706
+ st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
707
+ st.session_state.selected_document_id = new_doc['id']
708
+ # Switch to 'Show as Edit and Save' mode
709
+ st.rerun()
710
+ else:
711
+ st.error(message)
712
+ except json.JSONDecodeError as e:
713
+ st.error(f"Invalid JSON: {str(e)} 🚫")
714
+
715
+ else:
716
+ st.sidebar.info("No documents found in this container. πŸ“­")
717
+
718
+ # Main content area
719
+ st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
720
+ if st.session_state.selected_container:
721
+ if documents_to_display:
722
+ df = pd.DataFrame(documents_to_display)
723
+ st.dataframe(df)
724
+ else:
725
+ st.info("No documents to display. 🧐")
726
+
727
+ # GitHub section
728
+ st.subheader("πŸ™ GitHub Operations")
729
+ github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
730
+ source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
731
+ new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
732
+
733
+ col1, col2 = st.columns(2)
734
+ with col1:
735
+ if st.button("πŸ“₯ Clone Repository"):
736
+ if github_token and source_repo:
737
+ try:
738
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d%H%M%S')}"
739
+ download_github_repo(source_repo, local_path)
740
+ zip_filename = f"{new_repo_name}.zip"
741
+ create_zip_file(local_path, zip_filename[:-4])
742
+ st.markdown(get_download_link(zip_filename), unsafe_allow_html=True)
743
+ st.success("Repository cloned successfully! πŸŽ‰")
744
+ except Exception as e:
745
+ st.error(f"An error occurred: {str(e)} 😒")
746
+ finally:
747
+ if os.path.exists(local_path):
748
+ shutil.rmtree(local_path)
749
+ if os.path.exists(zip_filename):
750
+ os.remove(zip_filename)
751
+ else:
752
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
753
+
754
+ with col2:
755
+ if st.button("πŸ“€ Push to New Repository"):
756
+ if github_token and source_repo:
757
+ try:
758
+ g = Github(github_token)
759
+ new_repo = create_repo(g, new_repo_name)
760
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d%H%M%S')}"
761
+ download_github_repo(source_repo, local_path)
762
+ push_to_github(local_path, new_repo, github_token)
763
+ st.success(f"Repository pushed successfully to {new_repo.html_url} πŸš€")
764
+ except Exception as e:
765
+ st.error(f"An error occurred: {str(e)} 😒")
766
+ finally:
767
+ if os.path.exists(local_path):
768
+ shutil.rmtree(local_path)
769
+ else:
770
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
771
+
772
+ # Chat with Claude
773
+ st.subheader("πŸ’¬ Chat with Claude")
774
+ user_input = st.text_area("Message πŸ“¨:", height=100)
775
+
776
+ if st.button("Send πŸ“¨"):
777
+ if user_input:
778
+ response = client.messages.create(
779
+ model="claude-3-sonnet-20240229",
780
+ max_tokens=1000,
781
+ messages=[
782
+ {"role": "user", "content": user_input}
783
+ ]
784
+ )
785
+ st.write("Claude's reply 🧠:")
786
+ st.write(response.content[0].text)
787
+
788
+ filename = generate_filename(user_input, "md")
789
+ create_file(filename, user_input, response.content[0].text)
790
+
791
+ st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
792
+
793
+ # Save to Cosmos DB
794
+ save_to_cosmos_db(container, user_input, response.content[0].text, "")
795
+
796
+ # Display Chat History
797
+ st.subheader("Past Conversations πŸ“œ")
798
+ for chat in st.session_state.chat_history:
799
+ st.text_area("You said πŸ’¬:", chat["user"], height=100, disabled=True)
800
+ st.text_area("Claude replied πŸ€–:", chat["claude"], height=200, disabled=True)
801
+ st.markdown("---")
802
+
803
+ # File Editor
804
+ if hasattr(st.session_state, 'current_file'):
805
+ st.subheader(f"Editing: {st.session_state.current_file} πŸ› ")
806
+ new_content = st.text_area("File Content ✏️:", st.session_state.file_content, height=300)
807
+ if st.button("Save Changes πŸ’Ύ"):
808
+ with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
809
+ file.write(new_content)
810
+ st.success("File updated successfully! πŸŽ‰")
811
+
812
+ # File Management
813
+ st.sidebar.title("πŸ“ File Management")
814
+
815
+ all_files = glob.glob("*.md")
816
+ all_files.sort(reverse=True)
817
+
818
+ if st.sidebar.button("πŸ—‘ Delete All Files"):
819
+ for file in all_files:
820
+ os.remove(file)
821
+ st.rerun()
822
+
823
+ if st.sidebar.button("⬇️ Download All Files"):
824
+ zip_file = create_zip_of_files(all_files)
825
+ st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
826
+
827
+ for file in all_files:
828
+ col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
829
+ with col1:
830
+ if st.button("🌐", key="view_"+file):
831
+ st.session_state.current_file = file
832
+ st.session_state.file_content = load_file(file)
833
+ with col2:
834
+ st.markdown(get_download_link(file), unsafe_allow_html=True)
835
+ with col3:
836
+ if st.button("πŸ“‚", key="edit_"+file):
837
+ st.session_state.current_file = file
838
+ st.session_state.file_content = load_file(file)
839
+ with col4:
840
+ if st.button("πŸ—‘", key="delete_"+file):
841
+ os.remove(file)
842
+ st.rerun()
843
+
844
+ except exceptions.CosmosHttpResponseError as e:
845
+ st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)} 🚨")
846
+ except Exception as e:
847
+ st.error(f"An unexpected error occurred: {str(e)} 😱")
848
+
849
+ # Logout button
850
+ if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
851
+ st.session_state.logged_in = False
852
+ st.session_state.selected_records.clear()
853
+ st.session_state.client = None
854
+ st.session_state.selected_database = None
855
+ st.session_state.selected_container = None
856
+ st.session_state.selected_document_id = None
857
+ st.session_state.current_index = 0
858
+ st.rerun()
859
+
860
+ if __name__ == "__main__":
861
+ main()