oscarwang2 commited on
Commit
d97f2ec
1 Parent(s): c7c5410

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import subprocess
4
+ import tempfile
5
+ import shutil
6
+ from zipfile import ZipFile
7
+ import logging
8
+ import json
9
+ import threading
10
+ import psutil
11
+
12
+ # Configure logging
13
+ logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__)
15
+
16
+ connected_cpus = {}
17
+
18
+ # Function to donate CPU
19
+ def donate_cpu(data):
20
+ host = data['host']
21
+ cpu_count = data['cpu_count']
22
+ connected_cpus[host] = {"cpu_count": cpu_count, "usage": 0.0}
23
+ logger.info(f"CPU donated by {host} with {cpu_count} CPUs.")
24
+ return {"status": "success", "message": f"CPU donated by {host}"}
25
+
26
+ # Function to update CPU usage
27
+ def update_cpu_usage(data):
28
+ host = data['host']
29
+ usage = data['usage']
30
+ if host in connected_cpus:
31
+ connected_cpus[host]['usage'] = usage
32
+ logger.info(f"Updated CPU usage for {host}: {usage}%")
33
+ return {"status": "success"}
34
+
35
+ # Function to run the provided Python script using MPI
36
+ def run_script(script_name, folder_path):
37
+ output_log = tempfile.TemporaryFile(mode='w+t')
38
+ try:
39
+ # Collect all available CPUs
40
+ total_cpus = sum(cpu['cpu_count'] for cpu in connected_cpus.values())
41
+
42
+ # Run the script using MPI
43
+ result = subprocess.run(['mpiexec', '-n', str(total_cpus), 'python', script_name], cwd=folder_path, stdout=output_log, stderr=subprocess.STDOUT)
44
+ output_log.seek(0)
45
+ log_output = output_log.read()
46
+ except Exception as e:
47
+ log_output = str(e)
48
+ finally:
49
+ output_log.close()
50
+
51
+ return log_output
52
+
53
+ # Function to handle file uploads and script execution
54
+ def handle_upload(folder, script_name):
55
+ # Create a temporary directory to store uploaded files
56
+ temp_dir = tempfile.mkdtemp()
57
+
58
+ # Save the uploaded folder contents to the temporary directory
59
+ folder_path = os.path.join(temp_dir, 'uploaded_folder')
60
+ os.makedirs(folder_path, exist_ok=True)
61
+ for file_name, file_obj in folder.items():
62
+ with open(os.path.join(folder_path, file_name), 'wb') as f:
63
+ f.write(file_obj.read())
64
+
65
+ # Run the script
66
+ log_output = run_script(script_name, folder_path)
67
+
68
+ # Create a zip file of the entire folder (including any new files created by the script)
69
+ zip_path = os.path.join(temp_dir, 'output_folder.zip')
70
+ with ZipFile(zip_path, 'w') as zipf:
71
+ for root, _, files in os.walk(folder_path):
72
+ for file in files:
73
+ zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), folder_path))
74
+
75
+ return log_output, zip_path
76
+
77
+ # Function to get connected CPUs information
78
+ def get_cpu_info():
79
+ info = []
80
+ for host, data in connected_cpus.items():
81
+ info.append(f"{host}: {data['cpu_count']} CPUs, {data['usage']}% usage")
82
+ return "\n".join(info)
83
+
84
+ # Gradio interface
85
+ def gradio_interface():
86
+ with gr.Blocks() as demo:
87
+ gr.Markdown("## Python Script Executor with Distributed Computing")
88
+
89
+ with gr.Row():
90
+ folder = gr.File(label="Upload Folder", file_count="multiple", file_types=['file'])
91
+ script_name = gr.Textbox(label="Python Script Name")
92
+
93
+ log_output = gr.Textbox(label="Log Output", interactive=False)
94
+ output_folder = gr.File(label="Download Output Folder")
95
+ cpu_info = gr.Textbox(label="Connected CPUs Info", interactive=False)
96
+
97
+ run_button = gr.Button("Run Script")
98
+ refresh_button = gr.Button("Refresh CPU Info")
99
+
100
+ run_button.click(fn=handle_upload, inputs=[folder, script_name], outputs=[log_output, output_folder])
101
+ refresh_button.click(fn=get_cpu_info, inputs=[], outputs=[cpu_info])
102
+
103
+ # Define the donate CPU endpoint
104
+ demo.api(donate_cpu, inputs=gr.JSON(), outputs=gr.JSON(), name="donate_cpu")
105
+
106
+ demo.launch()
107
+
108
+ if __name__ == "__main__":
109
+ gradio_interface()