awacke1 commited on
Commit
f8257f5
β€’
1 Parent(s): 88838c0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +278 -552
app.py CHANGED
@@ -1,49 +1,40 @@
1
- # CosmicApp.py
2
  import streamlit as st
3
- from azure.cosmos import CosmosClient, exceptions
4
  import os
5
  import pandas as pd
6
- import json
7
- from datetime import datetime
8
  import shutil
 
9
  from github import Github
10
  from git import Repo
 
11
  import base64
12
- from dotenv import load_dotenv
13
 
14
- # Load environment variables
15
- load_dotenv()
16
 
17
  # Cosmos DB configuration
18
- ENDPOINT = os.getenv("ENDPOINT")
19
- PRIMARY_KEY = os.getenv("PRIMARY_KEY")
 
 
20
  Key = os.environ.get("Key")
21
 
22
  # GitHub configuration
23
- GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
24
-
25
- # 🌟 Helper Functions Galore 🌟
26
-
27
  def download_github_repo(url, local_path):
28
- """
29
- πŸŒ€ Clone a GitHub repo faster than a swirling vortex!
30
- """
31
  if os.path.exists(local_path):
32
  shutil.rmtree(local_path)
33
  Repo.clone_from(url, local_path)
34
 
35
- def create_repo(github_token, repo_name):
36
- """
37
- 🐣 Hatch a new GitHub repo like a pro!
38
- """
39
- g = Github(github_token)
40
  user = g.get_user()
41
  return user.create_repo(repo_name)
42
 
43
  def push_to_github(local_path, repo, github_token):
44
- """
45
- πŸš€ Push your changes to GitHub at warp speed!
46
- """
47
  repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
48
  local_repo = Repo(local_path)
49
 
@@ -53,100 +44,84 @@ def push_to_github(local_path, repo, github_token):
53
  else:
54
  origin = local_repo.create_remote('origin', repo_url)
55
 
 
 
 
 
 
 
56
  local_repo.git.add(A=True)
 
57
  if local_repo.is_dirty():
58
  local_repo.git.commit('-m', 'Initial commit')
59
 
60
- origin.push(refspec=f"{local_repo.active_branch.name}:{local_repo.active_branch.name}")
61
 
62
  def get_base64_download_link(file_path, file_name):
63
- """
64
- πŸ”— Get a base64 download link for instant gratification!
65
- """
66
  with open(file_path, "rb") as file:
67
  contents = file.read()
68
  base64_encoded = base64.b64encode(contents).decode()
69
- return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">πŸ›Έ Download {file_name} πŸ›Έ</a>'
70
-
71
- def fetch_db_structure(client):
72
- """
73
- πŸ“‚ Fetch the cosmic database structureβ€”no telescope needed!
74
- """
75
- structure = {}
76
- for database in client.list_databases():
77
- db_name = database['id']
78
- structure[db_name] = []
79
- db_client = client.get_database_client(db_name)
80
- for container in db_client.list_containers():
81
- structure[db_name].append(container['id'])
82
- return structure
83
-
84
- def fetch_items(client, db_name, container_name):
85
- """
86
- πŸ›°οΈ Fetch items from a containerβ€”beep boop!
87
- """
88
- container = client.get_database_client(db_name).get_container_client(container_name)
89
- items = list(container.read_all_items())
90
- return items
91
-
92
- def create_item(client, db_name, container_name):
93
- """
94
- 🌱 Create a new cosmic itemβ€”let it grow!
95
- """
96
- st.subheader("🌱 Create New Item")
97
- item_id = st.text_input("πŸ†” Item ID")
98
- item_data = st.text_area("πŸ“ Item Data (in JSON format)")
99
-
100
- if st.button("πŸ’Ύ Save New Item"):
101
- try:
102
- container = client.get_database_client(db_name).get_container_client(container_name)
103
- json_data = json.loads(item_data)
104
- json_data['id'] = item_id
105
- container.create_item(body=json_data)
106
- st.success("πŸŽ‰ New item created successfully!")
107
- st.json(json_data)
108
- st.rerun()
109
- except Exception as e:
110
- st.error(f"🚨 Error creating item: {str(e)}")
111
-
112
- def edit_item(client, db_name, container_name, item_id):
113
- """
114
- ✏️ Edit an existing itemβ€”because change is the only constant!
115
- """
116
- container = client.get_database_client(db_name).get_container_client(container_name)
117
- item = container.read_item(item=item_id, partition_key=item_id)
118
-
119
- st.subheader(f"✏️ Editing Item: {item_id}")
120
- edited_item = st.text_area("πŸ“ Edit Item Data (in JSON format)", value=json.dumps(item, indent=2))
121
-
122
- if st.button("πŸ’Ύ Save Changes"):
123
- try:
124
- json_data = json.loads(edited_item)
125
- container.upsert_item(body=json_data)
126
- st.success("✨ Item updated successfully!")
127
- st.json(json_data)
128
- st.rerun()
129
- except Exception as e:
130
- st.error(f"🚨 Error updating item: {str(e)}")
131
-
132
- def delete_item(client, db_name, container_name, item_id):
133
- """
134
- πŸ—‘οΈ Delete an itemβ€”because sometimes less is more!
135
- """
136
- st.subheader(f"πŸ—‘οΈ Delete Item: {item_id}")
137
- if st.button("⚠️ Confirm Delete"):
138
- try:
139
- container = client.get_database_client(db_name).get_container_client(container_name)
140
- container.delete_item(item=item_id, partition_key=item_id)
141
- st.success(f"πŸ”₯ Item {item_id} deleted successfully!")
142
- st.rerun()
143
- except Exception as e:
144
- st.error(f"🚨 Error deleting item: {str(e)}")
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  def archive_all_data(client):
147
- """
148
- πŸ“¦ Archive all your dataβ€”pack it up, pack it in!
149
- """
150
  try:
151
  base_dir = "./cosmos_archive"
152
  if os.path.exists(base_dir):
@@ -175,457 +150,208 @@ def archive_all_data(client):
175
 
176
  return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
177
  except Exception as e:
178
- st.error(f"🚨 An error occurred while archiving data: {str(e)}")
179
-
180
- def download_all_code():
181
- """
182
- πŸ’Ύ Download all the codeβ€”because sharing is caring!
183
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  try:
185
- base_dir = "."
186
- exclude_dirs = ['.git', '__pycache__', 'cosmos_archive']
187
- exclude_files = ['.env', '.gitignore', 'cosmos_archive.zip']
188
-
189
- zip_filename = f"CosmosDBAICode_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
190
- shutil.make_archive(zip_filename[:-4], 'zip', base_dir)
191
- return get_base64_download_link(zip_filename, zip_filename)
192
  except Exception as e:
193
- st.error(f"🚨 An error occurred while creating the code archive: {str(e)}")
194
-
195
- def render_sidebar(client, structure):
196
- """
197
- πŸŽ›οΈ Render the cosmic sidebarβ€”control your destiny!
198
- """
199
- st.sidebar.title("🌌 Cosmic Control Panel")
200
-
201
- # 🚦 Navigation
202
- app_mode = st.sidebar.radio("πŸš€ Choose Your Adventure", ["App Mode 🌟", "Tutorial Mode πŸ“–"])
203
-
204
- if app_mode == "App Mode 🌟":
205
- # πŸ—„οΈ Database and Container selection
206
- selected_db = st.sidebar.selectbox("πŸ—„οΈ Select Database", list(structure.keys()))
207
- selected_container = st.sidebar.selectbox("πŸ“¦ Select Container", structure[selected_db])
208
-
209
- # πŸ“ Fetch items for the selected container
210
- items = fetch_items(client, selected_db, selected_container)
211
-
212
- # πŸ“„ Item selection
213
- item_ids = [item['id'] for item in items]
214
- selected_item = st.sidebar.selectbox("πŸ“„ Select Item", ["Create New Item"] + item_ids)
215
-
216
- # 🎬 Action buttons
217
- if selected_item != "Create New Item":
218
- if st.sidebar.button("✏️ Edit Item"):
219
- st.session_state.action = "edit"
220
- st.session_state.selected_item = selected_item
221
- if st.sidebar.button("πŸ—‘οΈ Delete Item"):
222
- st.session_state.action = "delete"
223
- st.session_state.selected_item = selected_item
224
- else:
225
- if st.sidebar.button("🌱 Create New Item"):
226
- st.session_state.action = "create"
227
-
228
- # πŸ™ GitHub Operations
229
- st.sidebar.subheader("πŸ™ GitHub Operations")
230
- source_repo = st.sidebar.text_input("πŸ”— Source Repo URL")
231
- new_repo_name = st.sidebar.text_input("πŸ†• New Repo Name", value=f"Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
232
-
233
- if st.sidebar.button("πŸ“₯ Clone Repository"):
234
- clone_github_repo(source_repo, new_repo_name)
235
-
236
- if st.sidebar.button("πŸ“€ Push to New Repository"):
237
- push_to_new_repo(source_repo, new_repo_name)
238
-
239
- # πŸ“¦ Archive data button
240
- if st.sidebar.button("πŸ“¦ Archive All Data"):
241
- download_link = archive_all_data(client)
242
- st.sidebar.markdown(download_link, unsafe_allow_html=True)
243
-
244
- # πŸ’Ύ Download All Code button
245
- if st.sidebar.button("πŸ’Ύ Download All Code"):
246
- download_link = download_all_code()
247
- st.sidebar.markdown(download_link, unsafe_allow_html=True)
248
-
249
- # πŸšͺ Logout button
250
- if st.sidebar.button("πŸšͺ Logout"):
251
- st.session_state.logged_in = False
252
- st.session_state.action = None
253
- st.session_state.selected_item = None
254
- st.rerun()
255
-
256
- return selected_db, selected_container, selected_item, app_mode
257
- else:
258
- # For tutorial mode
259
- return None, None, None, app_mode
260
-
261
- def clone_github_repo(source_repo, new_repo_name):
262
- """
263
- πŸ“₯ Clone a GitHub repoβ€”it's like magic!
264
- """
265
- if GITHUB_TOKEN and source_repo:
266
- try:
267
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
268
- download_github_repo(source_repo, local_path)
269
- zip_filename = f"{new_repo_name}.zip"
270
- shutil.make_archive(zip_filename[:-4], 'zip', local_path)
271
- st.sidebar.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
272
- st.sidebar.success("πŸŽ‰ Repository cloned successfully!")
273
- except Exception as e:
274
- st.sidebar.error(f"🚨 An error occurred: {str(e)}")
275
- finally:
276
- if os.path.exists(local_path):
277
- shutil.rmtree(local_path)
278
- if os.path.exists(zip_filename):
279
- os.remove(zip_filename)
280
- else:
281
- st.sidebar.error("🚨 Please ensure GitHub token is set and source repository URL is provided.")
282
-
283
- def push_to_new_repo(source_repo, new_repo_name):
284
- """
285
- πŸ“€ Push to a new GitHub repoβ€”reach for the stars!
286
- """
287
- if GITHUB_TOKEN and source_repo:
288
- try:
289
- new_repo = create_repo(GITHUB_TOKEN, new_repo_name)
290
- local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
291
- download_github_repo(source_repo, local_path)
292
- push_to_github(local_path, new_repo, GITHUB_TOKEN)
293
- st.sidebar.success(f"πŸš€ Repository pushed successfully to {new_repo.html_url}")
294
- except Exception as e:
295
- st.sidebar.error(f"🚨 An error occurred: {str(e)}")
296
- finally:
297
- if os.path.exists(local_path):
298
- shutil.rmtree(local_path)
299
- else:
300
- st.sidebar.error("🚨 Please ensure GitHub token is set and source repository URL is provided.")
301
-
302
- def main():
303
- """
304
- πŸ›Έ Main functionβ€”where all the magic happens!
305
- """
306
- st.set_page_config(layout="wide")
307
- st.title("πŸš€ Cosmos DB & GitHub Integration App with Streamlit πŸŽ‰")
308
-
309
- # Initialize session state
310
- if 'logged_in' not in st.session_state:
311
- st.session_state.logged_in = False
312
- if 'action' not in st.session_state:
313
- st.session_state.action = None
314
- if 'selected_item' not in st.session_state:
315
- st.session_state.selected_item = None
316
-
317
- # Login section
318
- if not st.session_state.logged_in:
319
- st.subheader("πŸ” Login to Your Cosmic Account")
320
- if st.button("πŸš€ Launch"):
321
- if Key:
322
-
323
- st.session_state.primary_key = Key
324
- st.session_state.logged_in = True
325
- st.rerun()
326
- else:
327
- st.error("🚨 Invalid key. Please check your environment variables.")
328
- else:
329
- # Initialize Cosmos DB client
330
- try:
331
- client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
332
- # Fetch database structure
333
- structure = fetch_db_structure(client)
334
- # Render sidebar and get selections
335
- selected_db, selected_container, selected_item, app_mode = render_sidebar(client, structure)
336
-
337
- if app_mode == "App Mode 🌟":
338
- # Main area
339
- if st.session_state.action == "create":
340
- create_item(client, selected_db, selected_container)
341
- elif st.session_state.action == "edit":
342
- edit_item(client, selected_db, selected_container, st.session_state.selected_item)
343
- elif st.session_state.action == "delete":
344
- delete_item(client, selected_db, selected_container, st.session_state.selected_item)
345
- else:
346
- st.write("🌟 Select an action from the sidebar to get started.")
347
- elif app_mode == "Tutorial Mode πŸ“–":
348
- display_tutorial()
349
- except exceptions.CosmosHttpResponseError as e:
350
- st.error(f"🚨 Failed to connect to Cosmos DB: {str(e)}")
351
- except Exception as e:
352
- st.error(f"🚨 An unexpected error occurred: {str(e)}")
353
-
354
- def display_tutorial():
355
- """
356
- πŸ“– Display the in-app tutorialβ€”knowledge is power!
357
- """
358
- st.header("πŸ“– Welcome to the Cosmic Tutorial!")
359
-
360
- st.markdown("""
361
- ### πŸš€ Introduction
362
-
363
- **Greetings, Earthling!** πŸ‘½ Ready to embark on a cosmic journey through the universe of Azure Cosmos DB and GitHub? Buckle up! This tutorial is not just informativeβ€”it's a blast! πŸŽ†
364
-
365
- **What You'll Learn:**
366
-
367
- - 🌌 Connecting to **Azure Cosmos DB** using Pythonβ€”no rocket science degree required!
368
- - πŸ› οΈ Performing **CRUD operations** on Cosmos DB containersβ€”because you can!
369
- - πŸ™ Integrating **GitHub functionalities** within the appβ€”unleash the octopus!
370
- - 🎨 Building an interactive UI with **Streamlit**β€”your canvas awaits!
371
-
372
- ---
373
-
374
- ### 🌟 Prerequisites
375
-
376
- Before we launch into space, make sure you've got:
377
-
378
- - πŸ›°οΈ An **Azure Cosmos DB** accountβ€”your mission control.
379
- - πŸ™ A **GitHub** account with a personal access tokenβ€”tentacles not included.
380
- - 🐍 **Python 3.7+** installedβ€”because snakes are cool.
381
- - 🧠 Basic knowledge of Python and Streamlitβ€”you've got this!
382
-
383
- ---
384
 
385
- ### πŸ› οΈ Setting Up the Environment
386
-
387
- **1. Clone the Repository**
388
-
389
- Open your terminal and run:
390
-
391
- """)
392
- st.code("""
393
- git clone https://github.com/yourusername/cosmosdb-streamlit-app.git
394
- cd cosmosdb-streamlit-app
395
- """, language='bash')
396
-
397
- st.markdown("""
398
- **2. Create a Virtual Environment**
399
-
400
- Let's keep things tidy:
401
-
402
- """)
403
- st.code("""
404
- python -m venv venv
405
- # On Windows
406
- venv\\Scripts\\activate
407
- # On macOS/Linux
408
- source venv/bin/activate
409
- """, language='bash')
410
-
411
- st.markdown("""
412
- **3. Install Dependencies**
413
-
414
- Time to get those packages:
415
-
416
- """)
417
- st.code("""
418
- pip install -r requirements.txt
419
- """, language='bash')
420
-
421
- st.markdown("""
422
- **4. Set Up Environment Variables**
423
-
424
- Create a `.env` file and add:
425
-
426
- """)
427
- st.code("""
428
- ENDPOINT=https://your-cosmos-db-account.documents.azure.com:443/
429
- PRIMARY_KEY=your_cosmos_db_primary_key
430
- GITHUB_TOKEN=your_github_personal_access_token
431
- """, language='text')
432
-
433
- st.warning("⚠️ **Note:** Keep your `.env` file secretβ€”just like your secret stash of cookies! πŸͺ")
434
-
435
- st.markdown("---")
436
-
437
- st.markdown("""
438
- ### πŸ”§ Application Architecture
439
-
440
- **Components:**
441
-
442
- - πŸ—„οΈ **Cosmos DB Operations**: Functions to connect and interact with Azure Cosmos DB.
443
- - πŸ™ **GitHub Integration**: Clone, create, and push repositories like a boss.
444
- - 🎨 **Streamlit Interface**: The front-end that brings it all together.
445
-
446
- **Data Flow:**
447
-
448
- 1. πŸŽ›οΈ **User Interaction**: Users make choices in the app.
449
- 2. πŸ—„οΈ **Database Operations**: App performs actions on Cosmos DB.
450
- 3. πŸ™ **GitHub Actions**: Clone and push repositories.
451
- 4. πŸ“¦ **Archiving Data**: Archive and download database contents.
452
-
453
- ---
454
-
455
- ### 🧩 Implementing the Application
456
-
457
- **Importing Libraries**
458
-
459
- """)
460
- st.code("""
461
- import streamlit as st
462
- from azure.cosmos import CosmosClient, exceptions
463
- import os
464
- import json
465
- from datetime import datetime
466
- import shutil
467
- from github import Github
468
- from git import Repo
469
- import base64
470
- from dotenv import load_dotenv
471
-
472
- load_dotenv()
473
- """, language='python')
474
-
475
- st.markdown("""
476
- **Configuring Cosmos DB and GitHub**
477
-
478
- """)
479
- st.code("""
480
- # Cosmos DB configuration
481
- ENDPOINT = os.getenv("ENDPOINT")
482
- PRIMARY_KEY = os.getenv("PRIMARY_KEY")
483
-
484
- # GitHub configuration
485
- GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
486
- """, language='python')
487
-
488
- st.markdown("""
489
- **Helper Functions**
490
-
491
- Here's where the magic happens! ✨
492
-
493
- *GitHub Operations*
494
-
495
- """)
496
- st.code("""
497
- def download_github_repo(url, local_path):
498
- # Function implementation
499
-
500
- def create_repo(github_token, repo_name):
501
- # Function implementation
502
-
503
- def push_to_github(local_path, repo, github_token):
504
- # Function implementation
505
- """, language='python')
506
-
507
- st.markdown("""
508
- *Base64 Download Link*
509
-
510
- """)
511
- st.code("""
512
- def get_base64_download_link(file_path, file_name):
513
- # Function implementation
514
- """, language='python')
515
-
516
- st.markdown("""
517
- **Cosmos DB Operations**
518
-
519
- *Fetching Database Structure*
520
-
521
- """)
522
- st.code("""
523
- def fetch_db_structure(client):
524
- # Function implementation
525
- """, language='python')
526
-
527
- st.markdown("""
528
- *CRUD Operations*
529
-
530
- **Create Item**
531
-
532
- """)
533
- st.code("""
534
- def create_item(client, db_name, container_name):
535
- # Function implementation
536
- """, language='python')
537
-
538
- st.markdown("""
539
- **Edit Item**
540
-
541
- """)
542
- st.code("""
543
- def edit_item(client, db_name, container_name, item_id):
544
- # Function implementation
545
- """, language='python')
546
-
547
- st.markdown("""
548
- **Delete Item**
549
-
550
- """)
551
- st.code("""
552
- def delete_item(client, db_name, container_name, item_id):
553
- # Function implementation
554
- """, language='python')
555
-
556
- st.markdown("""
557
- **Archiving Data**
558
-
559
- """)
560
- st.code("""
561
- def archive_all_data(client):
562
- # Function implementation
563
- """, language='python')
564
-
565
- st.markdown("""
566
- **Streamlit Interface**
567
-
568
- *Rendering the Sidebar*
569
-
570
- """)
571
- st.code("""
572
- def render_sidebar(client, structure):
573
- # Function implementation
574
- """, language='python')
575
-
576
- st.markdown("""
577
- *Main Function*
578
-
579
- """)
580
- st.code("""
581
- def main():
582
- # Function implementation
583
-
584
- if __name__ == "__main__":
585
- main()
586
- """, language='python')
587
-
588
- st.markdown("---")
589
-
590
- st.markdown("""
591
- ### πŸš€ Running the Application
592
-
593
- **Start the Streamlit App**
594
-
595
- """)
596
- st.code("""
597
- streamlit run CosmicApp.py
598
- """, language='bash')
599
-
600
- st.markdown("""
601
- **Login**
602
 
603
- - Open your browser and go to `http://localhost:8501`.
604
- - Click **Launch** to enter the app.
605
-
606
- **Using the App**
607
-
608
- - **Database Selection**: Choose your database and container from the sidebar.
609
- - **Item Operations**:
610
- - 🌱 **Create New Item**
611
- - ✏️ **Edit Item**
612
- - πŸ—‘οΈ **Delete Item**
613
- - **GitHub Operations**:
614
- - πŸ“₯ **Clone Repository**
615
- - πŸ“€ **Push to New Repository**
616
- - **Archive Data**: Click **πŸ“¦ Archive All Data** to download a ZIP file.
617
- - **Download Code**: Click **πŸ’Ύ Download All Code** to get the app's source code.
618
-
619
- ---
620
 
621
- ### 🌠 Conclusion
 
 
 
622
 
623
- You've reached the end of our cosmic tutorial! πŸš€ We hope you had a stellar time learning and exploring the universe of Cosmos DB and GitHub integration.
 
 
624
 
625
- **Keep Reaching for the Stars!** 🌟
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
 
627
- ---
628
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
 
630
- if __name__ == "__main__":
631
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ st.set_page_config(layout="wide")
 
16
 
17
  # Cosmos DB configuration
18
+ ENDPOINT = "https://acae-afd.documents.azure.com:443/"
19
+ SUBSCRIPTION_ID = "003fba60-5b3f-48f4-ab36-3ed11bc40816"
20
+ DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
21
+ CONTAINER_NAME = os.environ.get("COSMOS_CONTAINER_NAME")
22
  Key = os.environ.get("Key")
23
 
24
  # GitHub configuration
 
 
 
 
25
  def download_github_repo(url, local_path):
 
 
 
26
  if os.path.exists(local_path):
27
  shutil.rmtree(local_path)
28
  Repo.clone_from(url, local_path)
29
 
30
+ def create_zip_file(source_dir, output_filename):
31
+ shutil.make_archive(output_filename, 'zip', source_dir)
32
+
33
+ def create_repo(g, repo_name):
 
34
  user = g.get_user()
35
  return user.create_repo(repo_name)
36
 
37
  def push_to_github(local_path, repo, github_token):
 
 
 
38
  repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
39
  local_repo = Repo(local_path)
40
 
 
44
  else:
45
  origin = local_repo.create_remote('origin', repo_url)
46
 
47
+ if not local_repo.heads:
48
+ local_repo.git.checkout('-b', 'main')
49
+ current_branch = 'main'
50
+ else:
51
+ current_branch = local_repo.active_branch.name
52
+
53
  local_repo.git.add(A=True)
54
+
55
  if local_repo.is_dirty():
56
  local_repo.git.commit('-m', 'Initial commit')
57
 
58
+ origin.push(refspec=f'{current_branch}:{current_branch}')
59
 
60
  def get_base64_download_link(file_path, file_name):
 
 
 
61
  with open(file_path, "rb") as file:
62
  contents = file.read()
63
  base64_encoded = base64.b64encode(contents).decode()
64
+ return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">Download {file_name}</a>'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ # Cosmos DB functions
67
+ def insert_record(record):
68
+ try:
69
+ response = container.create_item(body=record)
70
+ return True, response
71
+ except exceptions.CosmosHttpResponseError as e:
72
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
73
+ except Exception as e:
74
+ return False, f"An unexpected error occurred: {str(e)}"
75
+
76
+ def call_stored_procedure(record):
77
+ try:
78
+ response = container.scripts.execute_stored_procedure(
79
+ sproc="processPrompt",
80
+ params=[record],
81
+ partition_key=record['id']
82
+ )
83
+ return True, response
84
+ except exceptions.CosmosHttpResponseError as e:
85
+ error_message = f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
86
+ return False, error_message
87
+ except Exception as e:
88
+ error_message = f"An unexpected error occurred: {str(e)}"
89
+ return False, error_message
90
+
91
+ def fetch_all_records():
92
+ try:
93
+ query = "SELECT * FROM c"
94
+ items = list(container.query_items(query=query, enable_cross_partition_query=True))
95
+ return pd.DataFrame(items)
96
+ except exceptions.CosmosHttpResponseError as e:
97
+ st.error(f"HTTP error occurred while fetching records: {str(e)}. Status code: {e.status_code}")
98
+ return pd.DataFrame()
99
+ except Exception as e:
100
+ st.error(f"An unexpected error occurred while fetching records: {str(e)}")
101
+ return pd.DataFrame()
102
+
103
+ def update_record(updated_record):
104
+ try:
105
+ container.upsert_item(body=updated_record)
106
+ return True, f"Record with id {updated_record['id']} successfully updated."
107
+ except exceptions.CosmosHttpResponseError as e:
108
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
109
+ except Exception as e:
110
+ return False, f"An unexpected error occurred: {traceback.format_exc()}"
111
+
112
+ def delete_record(name, id):
113
+ try:
114
+ container.delete_item(item=id, partition_key=id)
115
+ return True, f"Successfully deleted record with name: {name} and id: {id}"
116
+ except exceptions.CosmosResourceNotFoundError:
117
+ return False, f"Record with id {id} not found. It may have been already deleted."
118
+ except exceptions.CosmosHttpResponseError as e:
119
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
120
+ except Exception as e:
121
+ return False, f"An unexpected error occurred: {traceback.format_exc()}"
122
+
123
+ # New function to archive all databases and containers
124
  def archive_all_data(client):
 
 
 
125
  try:
126
  base_dir = "./cosmos_archive"
127
  if os.path.exists(base_dir):
 
150
 
151
  return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
152
  except Exception as e:
153
+ return f"An error occurred while archiving data: {str(e)}"
154
+
155
+ # Streamlit app
156
+ st.title("🌟 Cosmos DB and GitHub Integration")
157
+
158
+ # Initialize session state
159
+ if 'logged_in' not in st.session_state:
160
+ st.session_state.logged_in = False
161
+ if 'selected_records' not in st.session_state:
162
+ st.session_state.selected_records = []
163
+
164
+ # Login section
165
+ if not st.session_state.logged_in:
166
+ st.subheader("πŸ” Login")
167
+ input_key = Key
168
+ if st.button("πŸš€ Login"):
169
+ if input_key:
170
+ st.session_state.primary_key = input_key
171
+ st.session_state.logged_in = True
172
+ st.rerun()
173
+ else:
174
+ st.error("Invalid key. Please check your environment variables.")
175
+ else:
176
+ # Initialize Cosmos DB client
177
  try:
178
+ client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
179
+ database = client.get_database_client(DATABASE_NAME)
180
+ container = database.get_container_client(CONTAINER_NAME)
181
+ except exceptions.CosmosHttpResponseError as e:
182
+ st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)}. Status code: {e.status_code}")
183
+ st.stop()
 
184
  except Exception as e:
185
+ st.error(f"An unexpected error occurred while connecting to Cosmos DB: {str(e)}")
186
+ st.stop()
187
+
188
+ # GitHub section
189
+ st.subheader("πŸ™ GitHub Operations")
190
+ github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
191
+ source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
192
+ new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
+ col1, col2 = st.columns(2)
195
+ with col1:
196
+ if st.button("πŸ“₯ Clone Repository"):
197
+ if github_token and source_repo:
198
+ try:
199
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
200
+ download_github_repo(source_repo, local_path)
201
+ zip_filename = f"{new_repo_name}.zip"
202
+ create_zip_file(local_path, zip_filename[:-4])
203
+ st.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
204
+ st.success("Repository cloned successfully!")
205
+ except Exception as e:
206
+ st.error(f"An error occurred: {str(e)}")
207
+ finally:
208
+ if os.path.exists(local_path):
209
+ shutil.rmtree(local_path)
210
+ if os.path.exists(zip_filename):
211
+ os.remove(zip_filename)
212
+ else:
213
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
214
+
215
+ with col2:
216
+ if st.button("πŸ“€ Push to New Repository"):
217
+ if github_token and source_repo:
218
+ try:
219
+ g = Github(github_token)
220
+ new_repo = create_repo(g, new_repo_name)
221
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
222
+ download_github_repo(source_repo, local_path)
223
+ push_to_github(local_path, new_repo, github_token)
224
+ st.success(f"Repository pushed successfully to {new_repo.html_url}")
225
+ except Exception as e:
226
+ st.error(f"An error occurred: {str(e)}")
227
+ finally:
228
+ if os.path.exists(local_path):
229
+ shutil.rmtree(local_path)
230
+ else:
231
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
+ # Cosmos DB Operations
234
+ st.subheader("☁️ Cosmos DB Operations")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ # Archive all data
237
+ if st.button("πŸ“¦ Archive All Cosmos DB Data"):
238
+ download_link = archive_all_data(client)
239
+ st.markdown(download_link, unsafe_allow_html=True)
240
 
241
+ # Fetch and display all records
242
+ st.subheader("πŸ“Š All Records")
243
+ df = fetch_all_records()
244
 
245
+ if df.empty:
246
+ st.write("No records found in the database.")
247
+ else:
248
+ st.write("Records:")
249
+ for index, row in df.iterrows():
250
+ col1, col2, col3 = st.columns([5, 1, 1])
251
+
252
+ with col1:
253
+ st.write(f"ID: {row['id']}, Name: {row['name']}, Document: {row['document']}, "
254
+ f"Evaluation Text: {row['evaluationText']}, Evaluation Score: {row['evaluationScore']}")
255
+
256
+ with col2:
257
+ key = f"select_{row['id']}"
258
+ if st.button(f"πŸ‘‰ Select", key=key):
259
+ st.session_state.selected_record = row.to_dict()
260
+
261
+ with col3:
262
+ if st.button(f"πŸ—‘οΈ Delete", key=f"delete_{row['id']}"):
263
+ success, message = delete_record(row['name'], row['id'])
264
+ if success:
265
+ st.success(message)
266
+ st.rerun()
267
+ else:
268
+ st.error(message)
269
+
270
+ # Display selected record for editing
271
+ if 'selected_record' in st.session_state and st.session_state.selected_record:
272
+ selected_record = st.session_state.selected_record
273
+
274
+ st.subheader(f"Editing Record - ID: {selected_record['id']}")
275
+
276
+ updated_name = st.text_input("Name", value=selected_record['name'])
277
+ updated_document = st.text_area("Document", value=selected_record['document'])
278
+ updated_evaluation_text = st.text_area("Evaluation Text", value=selected_record['evaluationText'])
279
+ updated_evaluation_score = st.text_input("Evaluation Score", value=str(selected_record['evaluationScore']))
280
+
281
+ if st.button("πŸ’Ύ Save Changes"):
282
+ updated_record = {
283
+ "id": selected_record['id'],
284
+ "name": updated_name,
285
+ "document": updated_document,
286
+ "evaluationText": updated_evaluation_text,
287
+ "evaluationScore": updated_evaluation_score
288
+ }
289
+
290
+ success, message = update_record(updated_record)
291
+ if success:
292
+ st.success(message)
293
+ st.session_state.selected_record = updated_record
294
+ else:
295
+ st.error(message)
296
+
297
+ # Input fields for new record
298
+ st.subheader("πŸ“ Enter New Record Details")
299
+ new_id = st.text_input("ID")
300
+ new_name = st.text_input("Name")
301
+ new_document = st.text_area("Document")
302
+ new_evaluation_text = st.text_area("Evaluation Text")
303
+ new_evaluation_score = st.text_input("Evaluation Score")
304
+
305
+ col1, col2 = st.columns(2)
306
+
307
+ with col1:
308
+ if st.button("πŸ’Ύ Insert Record"):
309
+ record = {
310
+ "id": new_id,
311
+ "name": new_name,
312
+ "document": new_document,
313
+ "evaluationText": new_evaluation_text,
314
+ "evaluationScore": new_evaluation_score
315
+ }
316
+
317
+ success, response = insert_record(record)
318
+ if success:
319
+ st.success("βœ… Record inserted successfully!")
320
+ st.json(response)
321
+ else:
322
+ st.error(f"❌ Failed to insert record: {response}")
323
+ st.rerun()
324
 
325
+ with col2:
326
+ if st.button("πŸ”§ Call Procedure"):
327
+ record = {
328
+ "id": new_id,
329
+ "name": new_name,
330
+ "document": new_document,
331
+ "evaluationText": new_evaluation_text,
332
+ "evaluationScore": new_evaluation_score
333
+ }
334
+
335
+ success, response = call_stored_procedure(record)
336
+ if success:
337
+ st.success("βœ… Stored procedure executed successfully!")
338
+ st.json(response)
339
+ else:
340
+ st.error(f"❌ Failed to execute stored procedure: {response}")
341
 
342
+ # Logout button
343
+ if st.button("πŸšͺ Logout"):
344
+ st.session_state.logged_in = False
345
+ st.session_state.selected_records.clear()
346
+ st.session_state.selected_record = None
347
+ st.rerun()
348
+
349
+ # Display connection info
350
+ st.sidebar.subheader("πŸ”— Connection Information")
351
+ st.sidebar.text(f"Endpoint: {ENDPOINT}")
352
+ st.sidebar.text(f"Subscription ID: {SUBSCRIPTION_ID}")
353
+ st.sidebar.text(f"Database: {DATABASE_NAME}")
354
+ st.sidebar.text(f"Container: {CONTAINER_NAME}")
355
+
356
+ #if __name__ == "__main__":
357
+ # st.write("Application is running")