awacke1 commited on
Commit
b05ef13
Β·
verified Β·
1 Parent(s): ef4656e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -0
app.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from azure.cosmos import CosmosClient, exceptions
3
+ import os
4
+ import pandas as pd
5
+ import json
6
+ from datetime import datetime
7
+ import shutil
8
+ from github import Github
9
+ from git import Repo
10
+ import base64
11
+
12
+ # Cosmos DB configuration
13
+ ENDPOINT = "https://acae-afd.documents.azure.com:443/"
14
+ SUBSCRIPTION_ID = "003fba60-5b3f-48f4-ab36-3ed11bc40816"
15
+ DATABASE_NAME = os.environ.get("COSMOS_DATABASE_NAME")
16
+ Key = os.environ.get("Key")
17
+
18
+ # GitHub configuration
19
+ def download_github_repo(url, local_path):
20
+ if os.path.exists(local_path):
21
+ shutil.rmtree(local_path)
22
+ Repo.clone_from(url, local_path)
23
+
24
+ def create_zip_file(source_dir, output_filename):
25
+ shutil.make_archive(output_filename, 'zip', source_dir)
26
+
27
+ def create_repo(g, repo_name):
28
+ user = g.get_user()
29
+ return user.create_repo(repo_name)
30
+
31
+ def push_to_github(local_path, repo, github_token):
32
+ repo_url = f"https://{github_token}@github.com/{repo.full_name}.git"
33
+ local_repo = Repo(local_path)
34
+
35
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
36
+ origin = local_repo.remote('origin')
37
+ origin.set_url(repo_url)
38
+ else:
39
+ origin = local_repo.create_remote('origin', repo_url)
40
+
41
+ if not local_repo.heads:
42
+ local_repo.git.checkout('-b', 'main')
43
+ current_branch = 'main'
44
+ else:
45
+ current_branch = local_repo.active_branch.name
46
+
47
+ local_repo.git.add(A=True)
48
+
49
+ if local_repo.is_dirty():
50
+ local_repo.git.commit('-m', 'Initial commit')
51
+
52
+ origin.push(refspec=f'{current_branch}:{current_branch}')
53
+
54
+ def get_base64_download_link(file_path, file_name):
55
+ with open(file_path, "rb") as file:
56
+ contents = file.read()
57
+ base64_encoded = base64.b64encode(contents).decode()
58
+ return f'<a href="data:application/zip;base64,{base64_encoded}" download="{file_name}">Download {file_name}</a>'
59
+
60
+ # Function to fetch all databases and containers
61
+ def fetch_db_structure(client):
62
+ structure = {}
63
+ for database in client.list_databases():
64
+ db_name = database['id']
65
+ structure[db_name] = []
66
+ db_client = client.get_database_client(db_name)
67
+ for container in db_client.list_containers():
68
+ structure[db_name].append(container['id'])
69
+ return structure
70
+
71
+ # Function to fetch items from a container
72
+ def fetch_items(client, db_name, container_name):
73
+ container = client.get_database_client(db_name).get_container_client(container_name)
74
+ items = list(container.read_all_items())
75
+ return items
76
+
77
+ # Function to render sidebar
78
+ def render_sidebar(client, structure):
79
+ st.sidebar.title("πŸ“ Cosmos DB Manager")
80
+
81
+ # Database and Container selection
82
+ selected_db = st.sidebar.selectbox("πŸ—„οΈ Select Database", list(structure.keys()))
83
+ selected_container = st.sidebar.selectbox("πŸ“¦ Select Container", structure[selected_db])
84
+
85
+ # Fetch items for the selected container
86
+ items = fetch_items(client, selected_db, selected_container)
87
+
88
+ # Item selection
89
+ item_ids = [item['id'] for item in items]
90
+ selected_item = st.sidebar.selectbox("πŸ“„ Select Item", ["Create New Item"] + item_ids)
91
+
92
+ # CRUD buttons
93
+ if selected_item != "Create New Item":
94
+ if st.sidebar.button("πŸ–ŠοΈ Edit Item"):
95
+ st.session_state.action = "edit"
96
+ st.session_state.selected_item = selected_item
97
+ if st.sidebar.button("πŸ—‘οΈ Delete Item"):
98
+ st.session_state.action = "delete"
99
+ st.session_state.selected_item = selected_item
100
+ else:
101
+ if st.sidebar.button("βž• Create New Item"):
102
+ st.session_state.action = "create"
103
+
104
+ # GitHub section
105
+ st.sidebar.subheader("πŸ™ GitHub Operations")
106
+ github_token = os.environ.get("GITHUB")
107
+ source_repo = st.sidebar.text_input("πŸ”— Source Repo URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
108
+ new_repo_name = st.sidebar.text_input("πŸ“ New Repo Name", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
109
+
110
+ if st.sidebar.button("πŸ“₯ Clone Repository"):
111
+ clone_github_repo(github_token, source_repo, new_repo_name)
112
+
113
+ if st.sidebar.button("πŸ“€ Push to New Repository"):
114
+ push_to_new_repo(github_token, source_repo, new_repo_name)
115
+
116
+ # Archive data button
117
+ if st.sidebar.button("πŸ“¦ Archive All Data"):
118
+ download_link = archive_all_data(client)
119
+ st.sidebar.markdown(download_link, unsafe_allow_html=True)
120
+
121
+ # Logout button
122
+ if st.sidebar.button("πŸšͺ Logout"):
123
+ st.session_state.logged_in = False
124
+ st.session_state.action = None
125
+ st.session_state.selected_item = None
126
+ st.rerun()
127
+
128
+ return selected_db, selected_container, selected_item
129
+
130
+ # GitHub operations
131
+ def clone_github_repo(github_token, source_repo, new_repo_name):
132
+ if github_token and source_repo:
133
+ try:
134
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
135
+ download_github_repo(source_repo, local_path)
136
+ zip_filename = f"{new_repo_name}.zip"
137
+ create_zip_file(local_path, zip_filename[:-4])
138
+ st.sidebar.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
139
+ st.sidebar.success("Repository cloned successfully!")
140
+ except Exception as e:
141
+ st.sidebar.error(f"An error occurred: {str(e)}")
142
+ finally:
143
+ if os.path.exists(local_path):
144
+ shutil.rmtree(local_path)
145
+ if os.path.exists(zip_filename):
146
+ os.remove(zip_filename)
147
+ else:
148
+ st.sidebar.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
149
+
150
+ def push_to_new_repo(github_token, source_repo, new_repo_name):
151
+ if github_token and source_repo:
152
+ try:
153
+ g = Github(github_token)
154
+ new_repo = create_repo(g, new_repo_name)
155
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
156
+ download_github_repo(source_repo, local_path)
157
+ push_to_github(local_path, new_repo, github_token)
158
+ st.sidebar.success(f"Repository pushed successfully to {new_repo.html_url}")
159
+ except Exception as e:
160
+ st.sidebar.error(f"An error occurred: {str(e)}")
161
+ finally:
162
+ if os.path.exists(local_path):
163
+ shutil.rmtree(local_path)
164
+ else:
165
+ st.sidebar.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
166
+
167
+ # Function to archive all data
168
+ def archive_all_data(client):
169
+ try:
170
+ base_dir = "./cosmos_archive"
171
+ if os.path.exists(base_dir):
172
+ shutil.rmtree(base_dir)
173
+ os.makedirs(base_dir)
174
+
175
+ for database in client.list_databases():
176
+ db_name = database['id']
177
+ db_dir = os.path.join(base_dir, db_name)
178
+ os.makedirs(db_dir)
179
+
180
+ db_client = client.get_database_client(db_name)
181
+ for container in db_client.list_containers():
182
+ container_name = container['id']
183
+ container_dir = os.path.join(db_dir, container_name)
184
+ os.makedirs(container_dir)
185
+
186
+ container_client = db_client.get_container_client(container_name)
187
+ items = list(container_client.read_all_items())
188
+
189
+ with open(os.path.join(container_dir, f"{container_name}.json"), 'w') as f:
190
+ json.dump(items, f, indent=2)
191
+
192
+ archive_name = f"cosmos_archive_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
193
+ shutil.make_archive(archive_name, 'zip', base_dir)
194
+
195
+ return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
196
+ except Exception as e:
197
+ return f"An error occurred while archiving data: {str(e)}"
198
+
199
+ # Main Streamlit app
200
+ def main():
201
+ st.set_page_config(layout="wide")
202
+ st.title("🌟 Cosmos DB and GitHub Integration")
203
+
204
+ # Initialize session state
205
+ if 'logged_in' not in st.session_state:
206
+ st.session_state.logged_in = False
207
+ if 'action' not in st.session_state:
208
+ st.session_state.action = None
209
+ if 'selected_item' not in st.session_state:
210
+ st.session_state.selected_item = None
211
+
212
+ # Login section
213
+ if not st.session_state.logged_in:
214
+ st.subheader("πŸ” Login")
215
+ input_key = st.text_input("Enter your Cosmos DB key", type="password")
216
+ if st.button("πŸš€ Login"):
217
+ if input_key:
218
+ st.session_state.primary_key = input_key
219
+ st.session_state.logged_in = True
220
+ st.rerun()
221
+ else:
222
+ st.error("Invalid key. Please enter a valid Cosmos DB key.")
223
+ else:
224
+ # Initialize Cosmos DB client
225
+ try:
226
+ client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
227
+
228
+ # Fetch database structure
229
+ structure = fetch_db_structure(client)
230
+
231
+ # Render sidebar and get selections
232
+ selected_db, selected_container, selected_item = render_sidebar(client, structure)
233
+
234
+ # Main area
235
+ if st.session_state.action == "create":
236
+ create_item(client, selected_db, selected_container)
237
+ elif st.session_state.action == "edit":
238
+ edit_item(client, selected_db, selected_container, st.session_state.selected_item)
239
+ elif st.session_state.action == "delete":
240
+ delete_item(client, selected_db, selected_container, st.session_state.selected_item)
241
+ else:
242
+ st.write("Select an action from the sidebar to get started.")
243
+
244
+ except exceptions.CosmosHttpResponseError as e:
245
+ st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)}. Status code: {e.status_code}")
246
+ except Exception as e:
247
+ st.error(f"An unexpected error occurred: {str(e)}")
248
+
249
+ if __name__ == "__main__":
250
+ main()