awacke1 commited on
Commit
88838c0
1 Parent(s): dce6762

Update backup4.app.py

Browse files
Files changed (1) hide show
  1. backup4.app.py +11 -314
backup4.app.py CHANGED
@@ -1,319 +1,16 @@
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
- # New function to convert text to JSON
200
- def text_to_json(text):
201
- lines = text.split('\n')
202
- json_data = {}
203
- for line in lines:
204
- if ':' in line:
205
- key, value = line.split(':', 1)
206
- json_data[key.strip()] = value.strip()
207
- else:
208
- # If there's no colon, use the whole line as a key with an empty string as value
209
- json_data[line.strip()] = ""
210
- return json_data
211
-
212
- # Cosmos DB operations
213
- def create_item(client, db_name, container_name):
214
- st.subheader("Create New Item")
215
- item_id = st.text_input("Item ID")
216
- item_data = st.text_area("Item Data (Text format)",
217
- value="🌟 Cosmos DB and GitHub Integration\nCreate New Item\nItem ID\nItem Data (Text format)\n💾 Save New Item")
218
-
219
- if st.button("💾 Save New Item"):
220
- try:
221
- container = client.get_database_client(db_name).get_container_client(container_name)
222
- json_data = text_to_json(item_data)
223
- new_item = {"id": item_id, "content": json_data}
224
- container.create_item(body=new_item)
225
- st.success("New item created successfully!")
226
- st.json(new_item) # Display the created item in JSON format
227
- st.rerun()
228
- except Exception as e:
229
- st.error(f"Error creating item: {str(e)}")
230
-
231
- def edit_item(client, db_name, container_name, item_id):
232
- container = client.get_database_client(db_name).get_container_client(container_name)
233
- item = container.read_item(item=item_id, partition_key=item_id)
234
-
235
- st.subheader(f"Editing Item: {item_id}")
236
- edited_item = {}
237
- for key, value in item.items():
238
- if key not in ['_rid', '_self', '_etag', '_attachments', '_ts']:
239
- if key == 'content':
240
- # Convert the JSON content back to text for editing
241
- text_content = "\n".join([f"{k}: {v}" for k, v in value.items()])
242
- edited_text = st.text_area(key, text_content)
243
- edited_item[key] = text_to_json(edited_text)
244
- else:
245
- edited_item[key] = st.text_input(key, value)
246
-
247
- if st.button("💾 Save Changes"):
248
- try:
249
- container.upsert_item(body=edited_item)
250
- st.success("Item updated successfully!")
251
- st.json(edited_item) # Display the updated item in JSON format
252
- st.rerun()
253
- except Exception as e:
254
- st.error(f"Error updating item: {str(e)}")
255
-
256
- def delete_item(client, db_name, container_name, item_id):
257
- st.subheader(f"Delete Item: {item_id}")
258
- st.write("Are you sure you want to delete this item?")
259
- if st.button("🗑️ Confirm Delete"):
260
- try:
261
- container = client.get_database_client(db_name).get_container_client(container_name)
262
- container.delete_item(item=item_id, partition_key=item_id)
263
- st.success(f"Item {item_id} deleted successfully!")
264
- st.rerun()
265
- except Exception as e:
266
- st.error(f"Error deleting item: {str(e)}")
267
-
268
- # Main Streamlit app
269
- def main():
270
- st.set_page_config(layout="wide")
271
- st.title("🌟 Cosmos DB and GitHub Integration")
272
-
273
- # Initialize session state
274
- if 'logged_in' not in st.session_state:
275
- st.session_state.logged_in = False
276
- if 'action' not in st.session_state:
277
- st.session_state.action = None
278
- if 'selected_item' not in st.session_state:
279
- st.session_state.selected_item = None
280
-
281
- # Login section
282
- if not st.session_state.logged_in:
283
- st.subheader("🔐 Login")
284
- input_key = Key # Get the key from the environment variable
285
- if st.button("🚀 Login"):
286
- if input_key:
287
- st.session_state.primary_key = input_key
288
- st.session_state.logged_in = True
289
- st.rerun()
290
- else:
291
- st.error("Invalid key. Please check your environment variables.")
292
- else:
293
- # Initialize Cosmos DB client
294
- try:
295
- client = CosmosClient(ENDPOINT, credential=st.session_state.primary_key)
296
-
297
- # Fetch database structure
298
- structure = fetch_db_structure(client)
299
-
300
- # Render sidebar and get selections
301
- selected_db, selected_container, selected_item = render_sidebar(client, structure)
302
-
303
- # Main area
304
- if st.session_state.action == "create":
305
- create_item(client, selected_db, selected_container)
306
- elif st.session_state.action == "edit":
307
- edit_item(client, selected_db, selected_container, st.session_state.selected_item)
308
- elif st.session_state.action == "delete":
309
- delete_item(client, selected_db, selected_container, st.session_state.selected_item)
310
- else:
311
- st.write("Select an action from the sidebar to get started.")
312
-
313
- except exceptions.CosmosHttpResponseError as e:
314
- st.error(f"Failed to connect to Cosmos DB. HTTP error: {str(e)}. Status code: {e.status_code}")
315
- except Exception as e:
316
- st.error(f"An unexpected error occurred: {str(e)}")
317
-
318
- if __name__ == "__main__":
319
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  def render_sidebar(client, structure):
2
+ # Existing code...
3
+ # GitHub Operations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  st.sidebar.subheader("🐙 GitHub Operations")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ if GITHUB_TOKEN:
7
+ # Proceed with GitHub operations
8
+ source_repo = st.sidebar.text_input("🔗 Source Repo URL")
9
+ new_repo_name = st.sidebar.text_input("🆕 New Repo Name", value=f"Clone-{datetime.now().strftime('%Y%m%d_%H%M%S')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if st.sidebar.button("📥 Clone Repository"):
12
+ clone_github_repo(source_repo, new_repo_name)
13
+ if st.sidebar.button("📤 Push to New Repository"):
14
+ push_to_new_repo(source_repo, new_repo_name)
 
 
 
 
 
 
 
 
 
 
15
  else:
16
+ st.sidebar.warning("⚠️ GitHub token not set. GitHub operations are disabled.")