oscarwang2 commited on
Commit
36ca81e
1 Parent(s): 1dcef25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -82
app.py CHANGED
@@ -1,13 +1,12 @@
1
  import os
2
- import subprocess
3
  import tempfile
4
  import shutil
5
  from zipfile import ZipFile
6
  import logging
7
- import json
8
  import psutil
9
- import multiprocessing
10
  from flask import Flask, request, jsonify, render_template, send_file
 
 
11
 
12
  # Configure logging
13
  logging.basicConfig(level=logging.INFO)
@@ -18,101 +17,94 @@ app = Flask(__name__)
18
 
19
  connected_cpus = {"localhost": {"cpu_count": psutil.cpu_count(logical=False), "usage": 0.0}}
20
 
21
- # Endpoint to donate CPU resources
22
- @app.route('/donate_cpu', methods=['POST'])
23
- def donate_cpu_handler():
24
- data = request.get_json()
25
- host = data['host']
26
- cpu_count = data['cpu_count']
27
- connected_cpus[host] = {"cpu_count": cpu_count, "usage": 0.0}
28
- logger.info(f"CPU donated by {host} with {cpu_count} CPUs.")
29
- return jsonify({"status": "success", "message": f"CPU donated by {host}"})
30
-
31
- # Endpoint to update CPU usage
32
- @app.route('/update_cpu_usage', methods=['POST'])
33
- def update_cpu_usage_handler():
34
- data = request.get_json()
35
- host = data['host']
36
- usage = data['usage']
37
- if host in connected_cpus:
38
- connected_cpus[host]['usage'] = usage
39
- logger.info(f"Updated CPU usage for {host}: {usage}%")
40
- return jsonify({"status": "success"})
41
-
42
- # Function to run the provided Python script using multiprocessing
43
- def run_script(script_content, folder_path):
44
- script_path = os.path.join(folder_path, 'user_script.py')
45
- with open(script_path, 'w') as script_file:
46
- script_file.write(script_content)
47
-
48
- def target_function(cpu_id):
49
- output_log = tempfile.TemporaryFile(mode='w+t')
50
- try:
51
- result = subprocess.run(['python', script_path], cwd=folder_path, stdout=output_log, stderr=subprocess.STDOUT)
52
- output_log.seek(0)
53
- log_output = output_log.read()
54
- except Exception as e:
55
- log_output = str(e)
56
- finally:
57
- output_log.close()
58
- return log_output
59
-
60
- # Collect all available CPUs including the local host CPU
61
- total_cpus = sum(cpu['cpu_count'] for cpu in connected_cpus.values())
62
-
63
- # Run the script using multiprocessing
64
- with multiprocessing.Pool(total_cpus) as pool:
65
- log_outputs = pool.map(target_function, range(total_cpus))
66
-
67
- return '\n'.join(log_outputs)
68
 
69
- # Function to handle file uploads and script execution
70
  @app.route('/upload', methods=['POST'])
71
  def handle_upload():
72
- if 'file' not in request.files or 'script_content' not in request.form:
73
- return jsonify({"status": "error", "message": "File or script content not provided"}), 400
74
-
75
- files = request.files.getlist('file')
76
- script_content = request.form['script_content']
77
-
78
- # Create a temporary directory to store uploaded files
79
- temp_dir = tempfile.mkdtemp()
80
-
81
- # Save the uploaded folder contents to the temporary directory
82
- folder_path = os.path.join(temp_dir, 'uploaded_folder')
83
- os.makedirs(folder_path, exist_ok=True)
84
- for file_obj in files:
85
- file_path = os.path.join(folder_path, file_obj.filename)
86
- file_obj.save(file_path)
87
-
88
- # Run the script
89
- log_output = run_script(script_content, folder_path)
90
-
91
- # Create a zip file of the entire folder (including any new files created by the script)
92
- zip_path = os.path.join(temp_dir, 'output_folder.zip')
93
- with ZipFile(zip_path, 'w') as zipf:
94
- for root, _, files in os.walk(folder_path):
95
- for file in files:
96
- zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), folder_path))
 
 
 
 
 
 
 
 
97
 
98
- return jsonify({"status": "success", "log_output": log_output, "download_url": f"/download/{os.path.basename(zip_path)}"})
 
 
99
 
100
  @app.route('/download/<filename>')
101
  def download_file(filename):
102
- return send_file(os.path.join(tempfile.gettempdir(), filename), as_attachment=True)
 
 
 
 
103
 
104
  # Endpoint to get connected CPUs information
105
  @app.route('/cpu_info', methods=['GET'])
106
  def get_cpu_info():
107
- info = []
108
- for host, data in connected_cpus.items():
109
- info.append(f"{host}: {data['cpu_count']} CPUs, {data['usage']}% usage")
110
- return jsonify({"status": "success", "cpu_info": "\n".join(info)})
 
 
 
 
111
 
112
  # Main interface
113
  @app.route('/')
114
  def index():
115
  return render_template('index.html')
116
 
 
 
 
 
 
 
 
 
 
 
117
  if __name__ == "__main__":
118
  app.run(host='0.0.0.0', port=7860, threaded=True)
 
1
  import os
 
2
  import tempfile
3
  import shutil
4
  from zipfile import ZipFile
5
  import logging
 
6
  import psutil
 
7
  from flask import Flask, request, jsonify, render_template, send_file
8
+ import multiprocessing
9
+ import subprocess
10
 
11
  # Configure logging
12
  logging.basicConfig(level=logging.INFO)
 
17
 
18
  connected_cpus = {"localhost": {"cpu_count": psutil.cpu_count(logical=False), "usage": 0.0}}
19
 
20
+ # Define the target function for multiprocessing
21
+ def target_function(script_path, folder_path):
22
+ output_log = tempfile.TemporaryFile(mode='w+t')
23
+ try:
24
+ result = subprocess.run(['python', script_path], cwd=folder_path, stdout=output_log, stderr=subprocess.STDOUT)
25
+ output_log.seek(0)
26
+ log_output = output_log.read()
27
+ except Exception as e:
28
+ log_output = str(e)
29
+ finally:
30
+ output_log.close()
31
+ return log_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ # Endpoint to handle file uploads and script execution
34
  @app.route('/upload', methods=['POST'])
35
  def handle_upload():
36
+ try:
37
+ if 'file' not in request.files or 'script_content' not in request.form:
38
+ return jsonify({"status": "error", "message": "File or script content not provided"}), 400
39
+
40
+ files = request.files.getlist('file')
41
+ script_content = request.form['script_content']
42
+
43
+ # Create a temporary directory to store uploaded files
44
+ temp_dir = tempfile.mkdtemp()
45
+
46
+ # Save the uploaded files to the temporary directory
47
+ folder_path = os.path.join(temp_dir, 'uploaded_folder')
48
+ os.makedirs(folder_path, exist_ok=True)
49
+ for file_obj in files:
50
+ file_path = os.path.join(folder_path, file_obj.filename)
51
+ file_obj.save(file_path)
52
+
53
+ # Save the script content to a file
54
+ script_path = os.path.join(folder_path, 'user_script.py')
55
+ with open(script_path, 'w') as script_file:
56
+ script_file.write(script_content)
57
+
58
+ # Run the script using multiprocessing
59
+ log_output = run_script(script_path, folder_path)
60
+
61
+ # Create a zip file of the entire folder
62
+ zip_path = os.path.join(temp_dir, 'output_folder.zip')
63
+ with ZipFile(zip_path, 'w') as zipf:
64
+ for root, _, files in os.walk(folder_path):
65
+ for file in files:
66
+ zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), folder_path))
67
+
68
+ return jsonify({"status": "success", "log_output": log_output, "download_url": f"/download/{os.path.basename(zip_path)}"})
69
 
70
+ except Exception as e:
71
+ logger.error(f"Error in handle_upload: {e}")
72
+ return jsonify({"status": "error", "message": str(e)}), 500
73
 
74
  @app.route('/download/<filename>')
75
  def download_file(filename):
76
+ try:
77
+ return send_file(os.path.join(tempfile.gettempdir(), filename), as_attachment=True)
78
+ except Exception as e:
79
+ logger.error(f"Error in download_file: {e}")
80
+ return jsonify({"status": "error", "message": str(e)}), 500
81
 
82
  # Endpoint to get connected CPUs information
83
  @app.route('/cpu_info', methods=['GET'])
84
  def get_cpu_info():
85
+ try:
86
+ info = []
87
+ for host, data in connected_cpus.items():
88
+ info.append(f"{host}: {data['cpu_count']} CPUs, {data['usage']}% usage")
89
+ return jsonify({"status": "success", "cpu_info": "\n".join(info)})
90
+ except Exception as e:
91
+ logger.error(f"Error in get_cpu_info: {e}")
92
+ return jsonify({"status": "error", "message": str(e)}), 500
93
 
94
  # Main interface
95
  @app.route('/')
96
  def index():
97
  return render_template('index.html')
98
 
99
+ def run_script(script_path, folder_path):
100
+ # Collect all available CPUs including the local host CPU
101
+ total_cpus = sum(cpu['cpu_count'] for cpu in connected_cpus.values()) + 1
102
+
103
+ # Use multiprocessing to run the script
104
+ with multiprocessing.Pool(total_cpus) as pool:
105
+ log_outputs = pool.starmap(target_function, [(script_path, folder_path)] * total_cpus)
106
+
107
+ return '\n'.join(log_outputs)
108
+
109
  if __name__ == "__main__":
110
  app.run(host='0.0.0.0', port=7860, threaded=True)