awacke1 commited on
Commit
3c0588e
Β·
verified Β·
1 Parent(s): 95cfa21

Delete backup7.app.py

Browse files
Files changed (1) hide show
  1. backup7.app.py +0 -734
backup7.app.py DELETED
@@ -1,734 +0,0 @@
1
- import streamlit as st
2
- from azure.cosmos import CosmosClient, PartitionKey, exceptions
3
- import os
4
- import pandas as pd
5
- import traceback
6
- import requests
7
- import shutil
8
- import zipfile
9
- from github import Github
10
- from git import Repo
11
- from datetime import datetime
12
- import base64
13
- import json
14
-
15
- # πŸŽ‰ Welcome to our fun-filled Cosmos DB and GitHub Integration app!
16
- st.set_page_config(layout="wide")
17
-
18
- # 🌌 Cosmos DB configuration
19
- ENDPOINT = "https://acae-afd.documents.azure.com:443/"
20
- SUBSCRIPTION_ID = "003fba60-5b3f-48f4-ab36-3ed11bc40816"
21
- DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
22
- CONTAINER_NAME = os.environ.get("COSMOS_CONTAINER_NAME")
23
- Key = os.environ.get("Key") # πŸ”‘ Don't forget your key!
24
-
25
- # πŸ™ GitHub configuration
26
- def download_github_repo(url, local_path):
27
- # 🚚 Let's download that GitHub repo!
28
- if os.path.exists(local_path):
29
- shutil.rmtree(local_path)
30
- Repo.clone_from(url, local_path)
31
-
32
- def create_zip_file(source_dir, output_filename):
33
- # πŸ“¦ Zipping up files like a pro!
34
- shutil.make_archive(output_filename, 'zip', source_dir)
35
-
36
- def create_repo(g, repo_name):
37
- # πŸ› οΈ Creating a new GitHub repo. Magic!
38
- user = g.get_user()
39
- return user.create_repo(repo_name)
40
-
41
- def push_to_github(local_path, repo, github_token):
42
- # πŸš€ Pushing code to GitHub. Hold on tight!
43
- repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
44
- local_repo = Repo(local_path)
45
-
46
- if 'origin' in [remote.name for remote in local_repo.remotes]:
47
- origin = local_repo.remote('origin')
48
- origin.set_url(repo_url)
49
- else:
50
- origin = local_repo.create_remote('origin', repo_url)
51
-
52
- if not local_repo.heads:
53
- local_repo.git.checkout('-b', 'main')
54
- current_branch = 'main'
55
- else:
56
- current_branch = local_repo.active_branch.name
57
-
58
- local_repo.git.add(A=True)
59
-
60
- if local_repo.is_dirty():
61
- local_repo.git.commit('-m', 'Initial commit')
62
-
63
- origin.push(refspec=f'{current_branch}:{current_branch}')
64
-
65
- def get_base64_download_link(file_path, file_name):
66
- # πŸ§™β€β™‚οΈ Generating a magical download link!
67
- with open(file_path, "rb") as file:
68
- contents = file.read()
69
- base64_encoded = base64.b64encode(contents).decode()
70
- return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">⬇️ Download {file_name}</a>'
71
-
72
-
73
- # 🧭 New functions for dynamic sidebar navigation
74
- def get_databases(client):
75
- # πŸ“š Fetching list of databases. So many options!
76
- return [db['id'] for db in client.list_databases()]
77
-
78
- def get_containers(database):
79
- # πŸ“‚ Getting containers. Containers within containers!
80
- return [container['id'] for container in database.list_containers()]
81
-
82
- def get_documents(container, limit=1000):
83
- # πŸ“ Retrieving documents. Shhh, don't tell anyone!
84
- query = "SELECT * FROM c"
85
- items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
86
- return items
87
-
88
-
89
- # 🌟 Cosmos DB functions
90
- def insert_record(container, record):
91
- try:
92
- container.create_item(body=record)
93
- return True, "Record inserted successfully! πŸŽ‰"
94
- except exceptions.CosmosHttpResponseError as e:
95
- return False, f"HTTP error occurred: {str(e)} 🚨"
96
- except Exception as e:
97
- return False, f"An unexpected error occurred: {str(e)} 😱"
98
-
99
- def update_record(container, updated_record):
100
- try:
101
- container.upsert_item(body=updated_record)
102
- return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΈ"
103
- except exceptions.CosmosHttpResponseError as e:
104
- return False, f"HTTP error occurred: {str(e)} 🚨"
105
- except Exception as e:
106
- return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
107
-
108
- def delete_record(container, name, id):
109
- try:
110
- container.delete_item(item=id, partition_key=id)
111
- return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
112
- except exceptions.CosmosResourceNotFoundError:
113
- return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
114
- except exceptions.CosmosHttpResponseError as e:
115
- return False, f"HTTP error occurred: {str(e)} 🚨"
116
- except Exception as e:
117
- return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
118
-
119
- # πŸ•’ Function to generate a unique ID based on timestamp
120
- def generate_timestamp_id():
121
- # ⏰ Time waits for no one, but IDs can!
122
- return datetime.now().strftime('%Y%m%d%H%M%S%f')
123
-
124
- # πŸ“¦ Function to archive current container
125
- def archive_current_container(database_name, container_name, client):
126
- try:
127
- base_dir = "./cosmos_archive_current_container"
128
- if os.path.exists(base_dir):
129
- shutil.rmtree(base_dir)
130
- os.makedirs(base_dir)
131
-
132
- db_client = client.get_database_client(database_name)
133
- container_client = db_client.get_container_client(container_name)
134
- items = list(container_client.read_all_items())
135
-
136
- container_dir = os.path.join(base_dir, container_name)
137
- os.makedirs(container_dir)
138
-
139
- for item in items:
140
- item_id = item.get('id', f"unknown_{datetime.now().strftime('%Y%m%d%H%M%S')}")
141
- with open(os.path.join(container_dir, f"{item_id}.json"), 'w') as f:
142
- json.dump(item, f, indent=2)
143
-
144
- archive_name = f"{container_name}_archive_{datetime.now().strftime('%Y%m%d%H%M%S')}"
145
- shutil.make_archive(archive_name, 'zip', base_dir)
146
-
147
- return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
148
- except Exception as e:
149
- return f"An error occurred while archiving data: {str(e)} 😒"
150
-
151
-
152
- # 🎈 Let's modify the main app to be more fun!
153
- def main():
154
- st.title("🌟 Cosmos DB and GitHub Integration")
155
-
156
- # 🚦 Initialize session state
157
- if 'logged_in' not in st.session_state:
158
- st.session_state.logged_in = False
159
- if 'selected_records' not in st.session_state:
160
- st.session_state.selected_records = []
161
- if 'client' not in st.session_state:
162
- st.session_state.client = None
163
- if 'selected_database' not in st.session_state:
164
- st.session_state.selected_database = None
165
- if 'selected_container' not in st.session_state:
166
- st.session_state.selected_container = None
167
-
168
- # πŸ” Login section
169
- if not st.session_state.logged_in:
170
- st.subheader("πŸ” Login")
171
- # Let's be sneaky and use the Key from environment variables! πŸ•΅οΈβ€β™‚οΈ
172
- input_key = Key
173
-
174
- # πŸš€ Time to blast off!
175
- if st.button("πŸš€ Login"):
176
- if input_key:
177
- st.session_state.primary_key = input_key
178
- st.session_state.logged_in = True
179
- st.rerun()
180
- else:
181
- st.error("Invalid key. Please check your input. πŸ”‘βŒ")
182
- else:
183
- # 🌌 Initialize Cosmos DB client
184
- try:
185
- if st.session_state.client is None:
186
- st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
187
-
188
- # πŸ—„οΈ Sidebar for database, container, and document selection
189
- st.sidebar.title("πŸ—„οΈ Cosmos DB Navigator")
190
-
191
- databases = get_databases(st.session_state.client)
192
- selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
193
-
194
- if selected_db != st.session_state.selected_database:
195
- st.session_state.selected_database = selected_db
196
- st.session_state.selected_container = None
197
- st.rerun()
198
-
199
- if st.session_state.selected_database:
200
- database = st.session_state.client.get_database_client(st.session_state.selected_database)
201
- containers = get_containers(database)
202
- selected_container = st.sidebar.selectbox("πŸ“ Select Container", containers)
203
-
204
- if selected_container != st.session_state.selected_container:
205
- st.session_state.selected_container = selected_container
206
- st.rerun()
207
-
208
- if st.session_state.selected_container:
209
- container = database.get_container_client(st.session_state.selected_container)
210
-
211
- # πŸ“¦ Add Export button
212
- if st.button("πŸ“¦ Export Container Data"):
213
- download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
214
- if download_link.startswith('<a'):
215
- st.markdown(download_link, unsafe_allow_html=True)
216
- else:
217
- st.error(download_link)
218
-
219
- limit_to_1000 = st.sidebar.checkbox("πŸ”’ Limit to top 1000 documents", value=True)
220
- documents = get_documents(container, limit=1000 if limit_to_1000 else None)
221
-
222
- if documents:
223
- document_ids = [doc.get('id', 'Unknown') for doc in documents]
224
- selected_document = st.sidebar.selectbox("πŸ“„ Select Document", document_ids)
225
-
226
- if selected_document:
227
- st.subheader(f"πŸ“„ Document Details: {selected_document}")
228
- selected_doc = next((doc for doc in documents if doc.get('id') == selected_document), None)
229
- if selected_doc:
230
- # 🎨 Add Viewer/Editor selection
231
- view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
232
- selected_view = st.selectbox("Select Viewer/Editor", view_options)
233
-
234
- if selected_view == 'Show as Markdown':
235
- # πŸ–ŒοΈ Show as Markdown
236
- items = get_documents(container)
237
- for item in items:
238
- st.markdown(f"### **πŸ†” ID: {item.get('id', 'Unknown')}**")
239
- content = item.get('content', '')
240
- if isinstance(content, dict) or isinstance(content, list):
241
- content = json.dumps(content, indent=2)
242
- st.markdown(content)
243
- elif selected_view == 'Show as Code Editor':
244
- # πŸ’» Show as Code Editor
245
- items = get_documents(container)
246
- for item in items:
247
- st.markdown(f"### **πŸ†” ID: {item.get('id', 'Unknown')}**")
248
- st.code(json.dumps(item, indent=2), language='python')
249
- elif selected_view == 'Show as Edit and Save':
250
- # ✏️ Show as Edit and Save
251
- st.markdown("#### Edit the document fields below:")
252
- editable_id = st.text_input("ID", value=selected_doc.get('id', ''), key='edit_id')
253
- # Remove 'id' from the document for editing other fields
254
- editable_doc = selected_doc.copy()
255
- editable_doc.pop('id', None)
256
- doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300)
257
- if st.button("πŸ’Ύ Save Changes"):
258
- try:
259
- updated_doc = json.loads(doc_str)
260
- updated_doc['id'] = editable_id # Include the possibly edited ID
261
- success, message = update_record(container, updated_doc)
262
- if success:
263
- st.success(message)
264
- else:
265
- st.error(message)
266
- except json.JSONDecodeError as e:
267
- st.error(f"Invalid JSON: {str(e)} 🚫")
268
- elif selected_view == 'Clone Document':
269
- # 🧬 Clone Document
270
- if st.button("πŸ“„ Clone Document"):
271
- cloned_doc = selected_doc.copy()
272
- # Generate a unique ID based on timestamp
273
- cloned_doc['id'] = generate_timestamp_id()
274
- success, message = insert_record(container, cloned_doc)
275
- if success:
276
- st.success(f"Document cloned with new id: {cloned_doc['id']} πŸŽ‰")
277
- else:
278
- st.error(message)
279
- elif selected_view == 'New Record':
280
- # πŸ†• New Record
281
- st.markdown("#### Create a new document:")
282
- new_id = st.text_input("ID", value=generate_timestamp_id(), key='new_id')
283
- new_doc_str = st.text_area("Document Content (in JSON format)", value='{}', height=300)
284
- if st.button("βž• Create New Document"):
285
- try:
286
- new_doc = json.loads(new_doc_str)
287
- new_doc['id'] = new_id # Use the provided ID
288
- success, message = insert_record(container, new_doc)
289
- if success:
290
- st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
291
- else:
292
- st.error(message)
293
- except json.JSONDecodeError as e:
294
- st.error(f"Invalid JSON: {str(e)} 🚫")
295
- else:
296
- st.sidebar.info("No documents found in this container. πŸ“­")
297
-
298
- # πŸŽ‰ Main content area
299
- st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
300
- if st.session_state.selected_container:
301
- if documents:
302
- df = pd.DataFrame(documents)
303
- st.dataframe(df)
304
- else:
305
- st.info("No documents to display. 🧐")
306
-
307
- # πŸ™ GitHub section
308
- st.subheader("πŸ™ GitHub Operations")
309
- github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
310
- source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
311
- new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
312
-
313
- col1, col2 = st.columns(2)
314
- with col1:
315
- if st.button("πŸ“₯ Clone Repository"):
316
- if github_token and source_repo:
317
- try:
318
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
319
- download_github_repo(source_repo, local_path)
320
- zip_filename = f"{new_repo_name}.zip"
321
- create_zip_file(local_path, zip_filename[:-4])
322
- st.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
323
- st.success("Repository cloned successfully! πŸŽ‰")
324
- except Exception as e:
325
- st.error(f"An error occurred: {str(e)} 😒")
326
- finally:
327
- if os.path.exists(local_path):
328
- shutil.rmtree(local_path)
329
- if os.path.exists(zip_filename):
330
- os.remove(zip_filename)
331
- else:
332
- st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
333
-
334
- with col2:
335
- if st.button("πŸ“€ Push to New Repository"):
336
- if github_token and source_repo:
337
- try:
338
- g = Github(github_token)
339
- new_repo = create_repo(g, new_repo_name)
340
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
341
- download_github_repo(source_repo, local_path)
342
- push_to_github(local_path, new_repo, github_token)
343
- st.success(f"Repository pushed successfully to {new_repo.html_url} πŸš€")
344
- except Exception as e:
345
- st.error(f"An error occurred: {str(e)} 😒")
346
- finally:
347
- if os.path.exists(local_path):
348
- shutil.rmtree(local_path)
349
- else:
350
- st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
351
-
352
- except exceptions.CosmosHttpResponseError as e:
353
- st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)} 🚨")
354
- except Exception as e:
355
- st.error(f"An unexpected error occurred: {str(e)} 😱")
356
-
357
- # πŸšͺ Logout button
358
- if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
359
- st.session_state.logged_in = False
360
- st.session_state.selected_records.clear()
361
- st.session_state.client = None
362
- st.session_state.selected_database = None
363
- st.session_state.selected_container = None
364
- st.rerun()
365
-
366
- if __name__ == "__main__":
367
- main()
368
- import streamlit as st
369
- from azure.cosmos import CosmosClient, PartitionKey, exceptions
370
- import os
371
- import pandas as pd
372
- import traceback
373
- import requests
374
- import shutil
375
- import zipfile
376
- from github import Github
377
- from git import Repo
378
- from datetime import datetime
379
- import base64
380
- import json
381
-
382
- # πŸŽ‰ Welcome to our fun-filled Cosmos DB and GitHub Integration app!
383
- st.set_page_config(layout="wide")
384
-
385
- # 🌌 Cosmos DB configuration
386
- ENDPOINT = "https://acae-afd.documents.azure.com:443/"
387
- SUBSCRIPTION_ID = "003fba60-5b3f-48f4-ab36-3ed11bc40816"
388
- DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
389
- CONTAINER_NAME = os.environ.get("COSMOS_CONTAINER_NAME")
390
- Key = os.environ.get("Key") # πŸ”‘ Don't forget your key!
391
-
392
- # πŸ™ GitHub configuration
393
- def download_github_repo(url, local_path):
394
- # 🚚 Let's download that GitHub repo!
395
- if os.path.exists(local_path):
396
- shutil.rmtree(local_path)
397
- Repo.clone_from(url, local_path)
398
-
399
- def create_zip_file(source_dir, output_filename):
400
- # πŸ“¦ Zipping up files like a pro!
401
- shutil.make_archive(output_filename, 'zip', source_dir)
402
-
403
- def create_repo(g, repo_name):
404
- # πŸ› οΈ Creating a new GitHub repo. Magic!
405
- user = g.get_user()
406
- return user.create_repo(repo_name)
407
-
408
- def push_to_github(local_path, repo, github_token):
409
- # πŸš€ Pushing code to GitHub. Hold on tight!
410
- repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
411
- local_repo = Repo(local_path)
412
-
413
- if 'origin' in [remote.name for remote in local_repo.remotes]:
414
- origin = local_repo.remote('origin')
415
- origin.set_url(repo_url)
416
- else:
417
- origin = local_repo.create_remote('origin', repo_url)
418
-
419
- if not local_repo.heads:
420
- local_repo.git.checkout('-b', 'main')
421
- current_branch = 'main'
422
- else:
423
- current_branch = local_repo.active_branch.name
424
-
425
- local_repo.git.add(A=True)
426
-
427
- if local_repo.is_dirty():
428
- local_repo.git.commit('-m', 'Initial commit')
429
-
430
- origin.push(refspec=f'{current_branch}:{current_branch}')
431
-
432
- def get_base64_download_link(file_path, file_name):
433
- # πŸ§™β€β™‚οΈ Generating a magical download link!
434
- with open(file_path, "rb") as file:
435
- contents = file.read()
436
- base64_encoded = base64.b64encode(contents).decode()
437
- return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">⬇️ Download {file_name}</a>'
438
-
439
-
440
- # 🧭 New functions for dynamic sidebar navigation
441
- def get_databases(client):
442
- # πŸ“š Fetching list of databases. So many options!
443
- return [db['id'] for db in client.list_databases()]
444
-
445
- def get_containers(database):
446
- # πŸ“‚ Getting containers. Containers within containers!
447
- return [container['id'] for container in database.list_containers()]
448
-
449
- def get_documents(container, limit=1000):
450
- # πŸ“ Retrieving documents. Shhh, don't tell anyone!
451
- query = "SELECT * FROM c"
452
- items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
453
- return items
454
-
455
-
456
- # 🌟 Cosmos DB functions
457
- def insert_record(container, record):
458
- try:
459
- container.create_item(body=record)
460
- return True, "Record inserted successfully! πŸŽ‰"
461
- except exceptions.CosmosHttpResponseError as e:
462
- return False, f"HTTP error occurred: {str(e)} 🚨"
463
- except Exception as e:
464
- return False, f"An unexpected error occurred: {str(e)} 😱"
465
-
466
- def update_record(container, updated_record):
467
- try:
468
- container.upsert_item(body=updated_record)
469
- return True, f"Record with id {updated_record['id']} successfully updated. πŸ› οΈ"
470
- except exceptions.CosmosHttpResponseError as e:
471
- return False, f"HTTP error occurred: {str(e)} 🚨"
472
- except Exception as e:
473
- return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
474
-
475
- def delete_record(container, name, id):
476
- try:
477
- container.delete_item(item=id, partition_key=id)
478
- return True, f"Successfully deleted record with name: {name} and id: {id} πŸ—‘οΈ"
479
- except exceptions.CosmosResourceNotFoundError:
480
- return False, f"Record with id {id} not found. It may have been already deleted. πŸ•΅οΈβ€β™‚οΈ"
481
- except exceptions.CosmosHttpResponseError as e:
482
- return False, f"HTTP error occurred: {str(e)} 🚨"
483
- except Exception as e:
484
- return False, f"An unexpected error occurred: {traceback.format_exc()} 😱"
485
-
486
- # πŸ•’ Function to generate a unique ID based on timestamp
487
- def generate_timestamp_id():
488
- # ⏰ Time waits for no one, but IDs can!
489
- return datetime.now().strftime('%Y%m%d%H%M%S%f')
490
-
491
- # πŸ“¦ Function to archive current container
492
- def archive_current_container(database_name, container_name, client):
493
- try:
494
- base_dir = "./cosmos_archive_current_container"
495
- if os.path.exists(base_dir):
496
- shutil.rmtree(base_dir)
497
- os.makedirs(base_dir)
498
-
499
- db_client = client.get_database_client(database_name)
500
- container_client = db_client.get_container_client(container_name)
501
- items = list(container_client.read_all_items())
502
-
503
- container_dir = os.path.join(base_dir, container_name)
504
- os.makedirs(container_dir)
505
-
506
- for item in items:
507
- item_id = item.get('id', f"unknown_{datetime.now().strftime('%Y%m%d%H%M%S')}")
508
- with open(os.path.join(container_dir, f"{item_id}.json"), 'w') as f:
509
- json.dump(item, f, indent=2)
510
-
511
- archive_name = f"{container_name}_archive_{datetime.now().strftime('%Y%m%d%H%M%S')}"
512
- shutil.make_archive(archive_name, 'zip', base_dir)
513
-
514
- return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
515
- except Exception as e:
516
- return f"An error occurred while archiving data: {str(e)} 😒"
517
-
518
-
519
- # 🎈 Let's modify the main app to be more fun!
520
- def main():
521
- st.title("🌟 Cosmos DB and GitHub Integration")
522
-
523
- # 🚦 Initialize session state
524
- if 'logged_in' not in st.session_state:
525
- st.session_state.logged_in = False
526
- if 'selected_records' not in st.session_state:
527
- st.session_state.selected_records = []
528
- if 'client' not in st.session_state:
529
- st.session_state.client = None
530
- if 'selected_database' not in st.session_state:
531
- st.session_state.selected_database = None
532
- if 'selected_container' not in st.session_state:
533
- st.session_state.selected_container = None
534
-
535
- # πŸ” Login section
536
- if not st.session_state.logged_in:
537
- st.subheader("πŸ” Login")
538
- # Let's be sneaky and use the Key from environment variables! πŸ•΅οΈβ€β™‚οΈ
539
- input_key = Key
540
-
541
- # πŸš€ Time to blast off!
542
- if st.button("πŸš€ Login"):
543
- if input_key:
544
- st.session_state.primary_key = input_key
545
- st.session_state.logged_in = True
546
- st.rerun()
547
- else:
548
- st.error("Invalid key. Please check your input. πŸ”‘βŒ")
549
- else:
550
- # 🌌 Initialize Cosmos DB client
551
- try:
552
- if st.session_state.client is None:
553
- st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
554
-
555
- # πŸ—„οΈ Sidebar for database, container, and document selection
556
- st.sidebar.title("πŸ—„οΈ Cosmos DB Navigator")
557
-
558
- databases = get_databases(st.session_state.client)
559
- selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
560
-
561
- if selected_db != st.session_state.selected_database:
562
- st.session_state.selected_database = selected_db
563
- st.session_state.selected_container = None
564
- st.rerun()
565
-
566
- if st.session_state.selected_database:
567
- database = st.session_state.client.get_database_client(st.session_state.selected_database)
568
- containers = get_containers(database)
569
- selected_container = st.sidebar.selectbox("πŸ“ Select Container", containers)
570
-
571
- if selected_container != st.session_state.selected_container:
572
- st.session_state.selected_container = selected_container
573
- st.rerun()
574
-
575
- if st.session_state.selected_container:
576
- container = database.get_container_client(st.session_state.selected_container)
577
-
578
- # πŸ“¦ Add Export button
579
- if st.button("πŸ“¦ Export Container Data"):
580
- download_link = archive_current_container(st.session_state.selected_database, st.session_state.selected_container, st.session_state.client)
581
- if download_link.startswith('<a'):
582
- st.markdown(download_link, unsafe_allow_html=True)
583
- else:
584
- st.error(download_link)
585
-
586
- limit_to_1000 = st.sidebar.checkbox("πŸ”’ Limit to top 1000 documents", value=True)
587
- documents = get_documents(container, limit=1000 if limit_to_1000 else None)
588
-
589
- if documents:
590
- document_ids = [doc.get('id', 'Unknown') for doc in documents]
591
- selected_document = st.sidebar.selectbox("πŸ“„ Select Document", document_ids)
592
-
593
- if selected_document:
594
- st.subheader(f"πŸ“„ Document Details: {selected_document}")
595
- selected_doc = next((doc for doc in documents if doc.get('id') == selected_document), None)
596
- if selected_doc:
597
- # 🎨 Add Viewer/Editor selection
598
- view_options = ['Show as Markdown', 'Show as Code Editor', 'Show as Edit and Save', 'Clone Document', 'New Record']
599
- selected_view = st.selectbox("Select Viewer/Editor", view_options)
600
-
601
- if selected_view == 'Show as Markdown':
602
- # πŸ–ŒοΈ Show as Markdown
603
- items = get_documents(container)
604
- for item in items:
605
- st.markdown(f"### **πŸ†” ID: {item.get('id', 'Unknown')}**")
606
- content = item.get('content', '')
607
- if isinstance(content, dict) or isinstance(content, list):
608
- content = json.dumps(content, indent=2)
609
- st.markdown(content)
610
- elif selected_view == 'Show as Code Editor':
611
- # πŸ’» Show as Code Editor
612
- items = get_documents(container)
613
- for item in items:
614
- st.markdown(f"### **πŸ†” ID: {item.get('id', 'Unknown')}**")
615
- st.code(json.dumps(item, indent=2), language='python')
616
- elif selected_view == 'Show as Edit and Save':
617
- # ✏️ Show as Edit and Save
618
- st.markdown("#### Edit the document fields below:")
619
- editable_id = st.text_input("ID", value=selected_doc.get('id', ''), key='edit_id')
620
- # Remove 'id' from the document for editing other fields
621
- editable_doc = selected_doc.copy()
622
- editable_doc.pop('id', None)
623
- doc_str = st.text_area("Document Content (in JSON format)", value=json.dumps(editable_doc, indent=2), height=300)
624
- if st.button("πŸ’Ύ Save Changes"):
625
- try:
626
- updated_doc = json.loads(doc_str)
627
- updated_doc['id'] = editable_id # Include the possibly edited ID
628
- success, message = update_record(container, updated_doc)
629
- if success:
630
- st.success(message)
631
- else:
632
- st.error(message)
633
- except json.JSONDecodeError as e:
634
- st.error(f"Invalid JSON: {str(e)} 🚫")
635
- elif selected_view == 'Clone Document':
636
- # 🧬 Clone Document
637
- if st.button("πŸ“„ Clone Document"):
638
- cloned_doc = selected_doc.copy()
639
- # Generate a unique ID based on timestamp
640
- cloned_doc['id'] = generate_timestamp_id()
641
- success, message = insert_record(container, cloned_doc)
642
- if success:
643
- st.success(f"Document cloned with new id: {cloned_doc['id']} πŸŽ‰")
644
- else:
645
- st.error(message)
646
- elif selected_view == 'New Record':
647
- # πŸ†• New Record
648
- st.markdown("#### Create a new document:")
649
- new_id = st.text_input("ID", value=generate_timestamp_id(), key='new_id')
650
- new_doc_str = st.text_area("Document Content (in JSON format)", value='{}', height=300)
651
- if st.button("βž• Create New Document"):
652
- try:
653
- new_doc = json.loads(new_doc_str)
654
- new_doc['id'] = new_id # Use the provided ID
655
- success, message = insert_record(container, new_doc)
656
- if success:
657
- st.success(f"New document created with id: {new_doc['id']} πŸŽ‰")
658
- else:
659
- st.error(message)
660
- except json.JSONDecodeError as e:
661
- st.error(f"Invalid JSON: {str(e)} 🚫")
662
- else:
663
- st.sidebar.info("No documents found in this container. πŸ“­")
664
-
665
- # πŸŽ‰ Main content area
666
- st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
667
- if st.session_state.selected_container:
668
- if documents:
669
- df = pd.DataFrame(documents)
670
- st.dataframe(df)
671
- else:
672
- st.info("No documents to display. 🧐")
673
-
674
- # πŸ™ GitHub section
675
- st.subheader("πŸ™ GitHub Operations")
676
- github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
677
- source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
678
- new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
679
-
680
- col1, col2 = st.columns(2)
681
- with col1:
682
- if st.button("πŸ“₯ Clone Repository"):
683
- if github_token and source_repo:
684
- try:
685
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
686
- download_github_repo(source_repo, local_path)
687
- zip_filename = f"{new_repo_name}.zip"
688
- create_zip_file(local_path, zip_filename[:-4])
689
- st.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
690
- st.success("Repository cloned successfully! πŸŽ‰")
691
- except Exception as e:
692
- st.error(f"An error occurred: {str(e)} 😒")
693
- finally:
694
- if os.path.exists(local_path):
695
- shutil.rmtree(local_path)
696
- if os.path.exists(zip_filename):
697
- os.remove(zip_filename)
698
- else:
699
- st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
700
-
701
- with col2:
702
- if st.button("πŸ“€ Push to New Repository"):
703
- if github_token and source_repo:
704
- try:
705
- g = Github(github_token)
706
- new_repo = create_repo(g, new_repo_name)
707
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
708
- download_github_repo(source_repo, local_path)
709
- push_to_github(local_path, new_repo, github_token)
710
- st.success(f"Repository pushed successfully to {new_repo.html_url} πŸš€")
711
- except Exception as e:
712
- st.error(f"An error occurred: {str(e)} 😒")
713
- finally:
714
- if os.path.exists(local_path):
715
- shutil.rmtree(local_path)
716
- else:
717
- st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided. πŸ”‘β“")
718
-
719
- except exceptions.CosmosHttpResponseError as e:
720
- st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)} 🚨")
721
- except Exception as e:
722
- st.error(f"An unexpected error occurred: {str(e)} 😱")
723
-
724
- # πŸšͺ Logout button
725
- if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
726
- st.session_state.logged_in = False
727
- st.session_state.selected_records.clear()
728
- st.session_state.client = None
729
- st.session_state.selected_database = None
730
- st.session_state.selected_container = None
731
- st.rerun()
732
-
733
- if __name__ == "__main__":
734
- main()