awacke1 commited on
Commit
2cfb6b7
β€’
1 Parent(s): a06efbb

Create backup6.app.py

Browse files
Files changed (1) hide show
  1. backup6.app.py +311 -0
backup6.app.py ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
41
+ if 'origin' in [remote.name for remote in local_repo.remotes]:
42
+ origin = local_repo.remote('origin')
43
+ origin.set_url(repo_url)
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
+
67
+ # New functions for dynamic sidebar
68
+ def get_databases(client):
69
+ return [db['id'] for db in client.list_databases()]
70
+
71
+ def get_containers(database):
72
+ return [container['id'] for container in database.list_containers()]
73
+
74
+ def get_documents(container, limit=1000):
75
+ query = "SELECT * FROM c"
76
+ items = list(container.query_items(query=query, enable_cross_partition_query=True, max_item_count=limit))
77
+ return items
78
+
79
+
80
+ # Cosmos DB functions
81
+ def insert_record(record):
82
+ try:
83
+ response = container.create_item(body=record)
84
+ return True, response
85
+ except exceptions.CosmosHttpResponseError as e:
86
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
87
+ except Exception as e:
88
+ return False, f"An unexpected error occurred: {str(e)}"
89
+
90
+ def call_stored_procedure(record):
91
+ try:
92
+ response = container.scripts.execute_stored_procedure(
93
+ sproc="processPrompt",
94
+ params=[record],
95
+ partition_key=record['id']
96
+ )
97
+ return True, response
98
+ except exceptions.CosmosHttpResponseError as e:
99
+ error_message = f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
100
+ return False, error_message
101
+ except Exception as e:
102
+ error_message = f"An unexpected error occurred: {str(e)}"
103
+ return False, error_message
104
+
105
+ def fetch_all_records():
106
+ try:
107
+ query = "SELECT * FROM c"
108
+ items = list(container.query_items(query=query, enable_cross_partition_query=True))
109
+ return pd.DataFrame(items)
110
+ except exceptions.CosmosHttpResponseError as e:
111
+ st.error(f"HTTP error occurred while fetching records: {str(e)}. Status code: {e.status_code}")
112
+ return pd.DataFrame()
113
+ except Exception as e:
114
+ st.error(f"An unexpected error occurred while fetching records: {str(e)}")
115
+ return pd.DataFrame()
116
+
117
+ def update_record(updated_record):
118
+ try:
119
+ container.upsert_item(body=updated_record)
120
+ return True, f"Record with id {updated_record['id']} successfully updated."
121
+ except exceptions.CosmosHttpResponseError as e:
122
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
123
+ except Exception as e:
124
+ return False, f"An unexpected error occurred: {traceback.format_exc()}"
125
+
126
+ def delete_record(name, id):
127
+ try:
128
+ container.delete_item(item=id, partition_key=id)
129
+ return True, f"Successfully deleted record with name: {name} and id: {id}"
130
+ except exceptions.CosmosResourceNotFoundError:
131
+ return False, f"Record with id {id} not found. It may have been already deleted."
132
+ except exceptions.CosmosHttpResponseError as e:
133
+ return False, f"HTTP error occurred: {str(e)}. Status code: {e.status_code}"
134
+ except Exception as e:
135
+ return False, f"An unexpected error occurred: {traceback.format_exc()}"
136
+
137
+ # New function to archive all databases and containers
138
+ def archive_all_data(client):
139
+ try:
140
+ base_dir = "./cosmos_archive"
141
+ if os.path.exists(base_dir):
142
+ shutil.rmtree(base_dir)
143
+ os.makedirs(base_dir)
144
+
145
+ for database in client.list_databases():
146
+ db_name = database['id']
147
+ db_dir = os.path.join(base_dir, db_name)
148
+ os.makedirs(db_dir)
149
+
150
+ db_client = client.get_database_client(db_name)
151
+ for container in db_client.list_containers():
152
+ container_name = container['id']
153
+ container_dir = os.path.join(db_dir, container_name)
154
+ os.makedirs(container_dir)
155
+
156
+ container_client = db_client.get_container_client(container_name)
157
+ items = list(container_client.read_all_items())
158
+
159
+ with open(os.path.join(container_dir, f"{container_name}.json"), 'w') as f:
160
+ json.dump(items, f, indent=2)
161
+
162
+ archive_name = f"cosmos_archive_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
163
+ shutil.make_archive(archive_name, 'zip', base_dir)
164
+
165
+ return get_base64_download_link(f"{archive_name}.zip", f"{archive_name}.zip")
166
+ except Exception as e:
167
+ return f"An error occurred while archiving data: {str(e)}"
168
+
169
+
170
+ # Modify the main app
171
+ def main():
172
+ st.title("🌟 Cosmos DB and GitHub Integration")
173
+
174
+ # Initialize session state
175
+ if 'logged_in' not in st.session_state:
176
+ st.session_state.logged_in = False
177
+ if 'selected_records' not in st.session_state:
178
+ st.session_state.selected_records = []
179
+ if 'client' not in st.session_state:
180
+ st.session_state.client = None
181
+ if 'selected_database' not in st.session_state:
182
+ st.session_state.selected_database = None
183
+ if 'selected_container' not in st.session_state:
184
+ st.session_state.selected_container = None
185
+
186
+ # Login section
187
+ if not st.session_state.logged_in:
188
+ st.subheader("πŸ” Login")
189
+ #input_key = st.text_input("Enter your Cosmos DB key", type="password")
190
+ input_key=Key
191
+
192
+ # Cosmos DB configuration
193
+ if st.button("πŸš€ Login"):
194
+ if input_key:
195
+ st.session_state.primary_key = input_key
196
+ st.session_state.logged_in = True
197
+ st.rerun()
198
+ else:
199
+ st.error("Invalid key. Please check your input.")
200
+ else:
201
+ # Initialize Cosmos DB client
202
+ try:
203
+ if st.session_state.client is None:
204
+ st.session_state.client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
205
+
206
+ # Sidebar for database, container, and document selection
207
+ st.sidebar.title("πŸ—„οΈ Cosmos DB Navigator")
208
+
209
+ databases = get_databases(st.session_state.client)
210
+ selected_db = st.sidebar.selectbox("πŸ—ƒοΈ Select Database", databases)
211
+
212
+ if selected_db != st.session_state.selected_database:
213
+ st.session_state.selected_database = selected_db
214
+ st.session_state.selected_container = None
215
+ st.rerun()
216
+
217
+ if st.session_state.selected_database:
218
+ database = st.session_state.client.get_database_client(st.session_state.selected_database)
219
+ containers = get_containers(database)
220
+ selected_container = st.sidebar.selectbox("πŸ“ Select Container", containers)
221
+
222
+ if selected_container != st.session_state.selected_container:
223
+ st.session_state.selected_container = selected_container
224
+ st.rerun()
225
+
226
+ if st.session_state.selected_container:
227
+ container = database.get_container_client(st.session_state.selected_container)
228
+
229
+ limit_to_1000 = st.sidebar.checkbox("πŸ”’ Limit to top 1000 documents", value=True)
230
+ documents = get_documents(container, limit=1000 if limit_to_1000 else None)
231
+
232
+ if documents:
233
+ document_ids = [doc.get('id', 'Unknown') for doc in documents]
234
+ selected_document = st.sidebar.selectbox("πŸ“„ Select Document", document_ids)
235
+
236
+ if selected_document:
237
+ st.subheader(f"πŸ“„ Document Details: {selected_document}")
238
+ selected_doc = next((doc for doc in documents if doc.get('id') == selected_document), None)
239
+ if selected_doc:
240
+ st.json(selected_doc)
241
+ else:
242
+ st.sidebar.info("No documents found in this container.")
243
+
244
+ # Main content area
245
+ st.subheader(f"πŸ“Š Container: {st.session_state.selected_container}")
246
+ if st.session_state.selected_container:
247
+ df = pd.DataFrame(documents)
248
+ st.dataframe(df)
249
+
250
+ # GitHub section
251
+ st.subheader("πŸ™ GitHub Operations")
252
+ github_token = os.environ.get("GITHUB") # Read GitHub token from environment variable
253
+ source_repo = st.text_input("Source GitHub Repository URL", value="https://github.com/AaronCWacker/AIExamples-8-24-Streamlit")
254
+ new_repo_name = st.text_input("New Repository Name (for cloning)", value=f"AIExample-Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
255
+
256
+ col1, col2 = st.columns(2)
257
+ with col1:
258
+ if st.button("πŸ“₯ Clone Repository"):
259
+ if github_token and source_repo:
260
+ try:
261
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
262
+ download_github_repo(source_repo, local_path)
263
+ zip_filename = f"{new_repo_name}.zip"
264
+ create_zip_file(local_path, zip_filename[:-4])
265
+ st.markdown(get_base64_download_link(zip_filename, zip_filename), unsafe_allow_html=True)
266
+ st.success("Repository cloned successfully!")
267
+ except Exception as e:
268
+ st.error(f"An error occurred: {str(e)}")
269
+ finally:
270
+ if os.path.exists(local_path):
271
+ shutil.rmtree(local_path)
272
+ if os.path.exists(zip_filename):
273
+ os.remove(zip_filename)
274
+ else:
275
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
276
+
277
+ with col2:
278
+ if st.button("πŸ“€ Push to New Repository"):
279
+ if github_token and source_repo:
280
+ try:
281
+ g = Github(github_token)
282
+ new_repo = create_repo(g, new_repo_name)
283
+ local_path = f"./temp_repo_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
284
+ download_github_repo(source_repo, local_path)
285
+ push_to_github(local_path, new_repo, github_token)
286
+ st.success(f"Repository pushed successfully to {new_repo.html_url}")
287
+ except Exception as e:
288
+ st.error(f"An error occurred: {str(e)}")
289
+ finally:
290
+ if os.path.exists(local_path):
291
+ shutil.rmtree(local_path)
292
+ else:
293
+ st.error("Please ensure GitHub token is set in environment variables and source repository URL is provided.")
294
+
295
+ except exceptions.CosmosHttpResponseError as e:
296
+ st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)}. Status code: {e.status_code}")
297
+ except Exception as e:
298
+ st.error(f"An unexpected error occurred: {str(e)}")
299
+
300
+ # Logout button
301
+ if st.session_state.logged_in and st.sidebar.button("πŸšͺ Logout"):
302
+ st.session_state.logged_in = False
303
+ st.session_state.selected_records.clear()
304
+ st.session_state.client = None
305
+ st.session_state.selected_database = None
306
+ st.session_state.selected_container = None
307
+ st.rerun()
308
+
309
+ if __name__ == "__main__":
310
+ main()
311
+