mic3333 commited on
Commit
76038a5
Β·
verified Β·
1 Parent(s): e286f46

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -47
app.py CHANGED
@@ -41,24 +41,16 @@ def create_pyodide_interface():
41
  try {
42
  updateStatus('πŸ”„ Loading Pyodide core...', 'blue');
43
 
44
- // Load Pyodide with error handling
45
  pyodide = await loadPyodide({
46
  indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
47
  });
48
 
49
  updateStatus('πŸ“¦ Loading Python packages (numpy, matplotlib, pandas)...', 'blue');
50
 
51
- // Load packages one by one with progress
52
- await pyodide.loadPackage("numpy");
53
- updateStatus('πŸ“¦ numpy loaded, loading matplotlib...', 'blue');
54
-
55
- await pyodide.loadPackage("matplotlib");
56
- updateStatus('πŸ“¦ matplotlib loaded, loading pandas...', 'blue');
57
-
58
- await pyodide.loadPackage("pandas");
59
  updateStatus('βš™οΈ Setting up matplotlib backend...', 'blue');
60
 
61
- // Set up matplotlib backend for web
62
  pyodide.runPython(`
63
  import matplotlib
64
  matplotlib.use('AGG')
@@ -68,22 +60,40 @@ def create_pyodide_interface():
68
  import io
69
  import base64
70
 
71
- def show_plot():
 
 
 
 
72
  try:
73
- buffer = io.BytesIO()
74
- plt.savefig(buffer, format='png', bbox_inches='tight', dpi=100)
75
- buffer.seek(0)
76
- plot_data = buffer.getvalue()
77
- buffer.close()
78
- plt.close()
79
- return base64.b64encode(plot_data).decode()
 
 
 
 
 
80
  except Exception as e:
 
 
81
  return None
82
 
83
- # Override plt.show() to capture plots
 
 
 
 
 
 
 
84
  original_show = plt.show
85
  def custom_show(*args, **kwargs):
86
- return show_plot()
87
  plt.show = custom_show
88
 
89
  print("Pyodide Python environment ready!")
@@ -92,7 +102,6 @@ def create_pyodide_interface():
92
  pyodideReady = true;
93
  updateStatus('βœ… Pyodide ready! You can now execute Python code.', 'green');
94
 
95
- // Show a test message
96
  document.getElementById('pyodide-output').style.display = 'block';
97
  document.getElementById('output-text').textContent = 'Pyodide initialization complete! Ready to execute Python code.';
98
 
@@ -118,6 +127,9 @@ def create_pyodide_interface():
118
  try {
119
  updateStatus('▢️ Executing Python code...', 'blue');
120
 
 
 
 
121
  // Capture stdout
122
  pyodide.runPython(`
123
  import sys
@@ -129,24 +141,18 @@ def create_pyodide_interface():
129
  // Execute user code
130
  let result = pyodide.runPython(code);
131
 
132
- // Get captured output
133
  let stdout = pyodide.runPython(`
134
  sys.stdout = old_stdout
135
  captured_output.getvalue()
136
  `);
137
 
138
- // Check for plots separately - don't mix with stdout
139
- let plotData = null;
140
- try {
141
- plotData = pyodide.runPython(`
142
- if plt.get_fignums():
143
- show_plot()
144
- else:
145
- None
146
- `);
147
- } catch (e) {
148
- console.log('No plot generated or plot error:', e);
149
- }
150
 
151
  // Display results
152
  let outputDiv = document.getElementById('pyodide-output');
@@ -155,29 +161,34 @@ def create_pyodide_interface():
155
 
156
  outputDiv.style.display = 'block';
157
 
158
- // Clean text output - exclude any base64 data that might have leaked
159
- let cleanOutput = stdout || (result !== undefined ? String(result) : '');
160
- // Filter out any base64 image data that might have accidentally been printed
161
- cleanOutput = cleanOutput.replace(/iVBORw0KGgoAAAANSUhEUgAA[A-Za-z0-9+/=]+/g, '[Image data filtered]');
162
-
163
- outputText.textContent = cleanOutput || 'Code executed successfully (no output)';
164
 
165
  // Display plot if generated
166
- if (plotData && plotData.length > 100) { // Valid base64 should be long
167
- plotContainer.innerHTML = `<img src="data:image/png;base64,${plotData}" style="max-width: 100%; height: auto; border: 1px solid #ddd;" alt="Generated Plot">`;
 
 
 
 
 
 
 
 
168
 
169
- // Add plot success message to text (but not the raw base64)
170
- if (cleanOutput.trim()) {
171
  outputText.textContent += '\\n\\nπŸ“Š Plot generated and displayed below!';
172
  } else {
173
  outputText.textContent = 'πŸ“Š Plot generated and displayed below!';
174
  }
175
  updateStatus('βœ… Code executed with plot generated!', 'green');
176
- return 'Code executed successfully with plot generated';
177
  } else {
 
178
  plotContainer.innerHTML = '';
179
  updateStatus('βœ… Code executed successfully!', 'green');
180
- return cleanOutput || 'Code executed successfully';
181
  }
182
 
183
  } catch (error) {
@@ -206,7 +217,7 @@ def create_pyodide_interface():
206
  safeInitPyodide();
207
  }
208
 
209
- // Make function globally available
210
  window.executePyodideCode = executePyodideCode;
211
  window.checkPyodideStatus = () => pyodideReady;
212
  </script>
 
41
  try {
42
  updateStatus('πŸ”„ Loading Pyodide core...', 'blue');
43
 
 
44
  pyodide = await loadPyodide({
45
  indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
46
  });
47
 
48
  updateStatus('πŸ“¦ Loading Python packages (numpy, matplotlib, pandas)...', 'blue');
49
 
50
+ await pyodide.loadPackage(["numpy", "matplotlib", "pandas"]);
 
 
 
 
 
 
 
51
  updateStatus('βš™οΈ Setting up matplotlib backend...', 'blue');
52
 
53
+ // Set up matplotlib backend for web - IMPROVED VERSION
54
  pyodide.runPython(`
55
  import matplotlib
56
  matplotlib.use('AGG')
 
60
  import io
61
  import base64
62
 
63
+ # Global variable to store plot data
64
+ _current_plot_data = None
65
+
66
+ def capture_plot():
67
+ global _current_plot_data
68
  try:
69
+ if len(plt.get_fignums()) > 0:
70
+ buffer = io.BytesIO()
71
+ plt.savefig(buffer, format='png', bbox_inches='tight', dpi=100)
72
+ buffer.seek(0)
73
+ plot_data = buffer.getvalue()
74
+ buffer.close()
75
+ _current_plot_data = base64.b64encode(plot_data).decode()
76
+ plt.close('all') # Close all figures
77
+ return _current_plot_data
78
+ else:
79
+ _current_plot_data = None
80
+ return None
81
  except Exception as e:
82
+ print(f"Plot capture error: {e}")
83
+ _current_plot_data = None
84
  return None
85
 
86
+ def get_plot_data():
87
+ return _current_plot_data
88
+
89
+ def clear_plot_data():
90
+ global _current_plot_data
91
+ _current_plot_data = None
92
+
93
+ # Override plt.show() to capture plots automatically
94
  original_show = plt.show
95
  def custom_show(*args, **kwargs):
96
+ return capture_plot()
97
  plt.show = custom_show
98
 
99
  print("Pyodide Python environment ready!")
 
102
  pyodideReady = true;
103
  updateStatus('βœ… Pyodide ready! You can now execute Python code.', 'green');
104
 
 
105
  document.getElementById('pyodide-output').style.display = 'block';
106
  document.getElementById('output-text').textContent = 'Pyodide initialization complete! Ready to execute Python code.';
107
 
 
127
  try {
128
  updateStatus('▢️ Executing Python code...', 'blue');
129
 
130
+ // Clear any previous plot data
131
+ pyodide.runPython('clear_plot_data()');
132
+
133
  // Capture stdout
134
  pyodide.runPython(`
135
  import sys
 
141
  // Execute user code
142
  let result = pyodide.runPython(code);
143
 
144
+ // Get captured output (this should NOT contain base64 data)
145
  let stdout = pyodide.runPython(`
146
  sys.stdout = old_stdout
147
  captured_output.getvalue()
148
  `);
149
 
150
+ // Get plot data separately
151
+ let plotData = pyodide.runPython('get_plot_data()');
152
+
153
+ console.log('Stdout length:', stdout ? stdout.length : 0);
154
+ console.log('Plot data length:', plotData ? plotData.length : 0);
155
+ console.log('Plot data preview:', plotData ? plotData.substring(0, 50) + '...' : 'None');
 
 
 
 
 
 
156
 
157
  // Display results
158
  let outputDiv = document.getElementById('pyodide-output');
 
161
 
162
  outputDiv.style.display = 'block';
163
 
164
+ // Display clean text output
165
+ let textOutput = stdout || (result !== undefined ? String(result) : '');
166
+ outputText.textContent = textOutput || 'Code executed successfully (no output)';
 
 
 
167
 
168
  // Display plot if generated
169
+ if (plotData && plotData.length > 100) {
170
+ console.log('Displaying plot...');
171
+ plotContainer.innerHTML = `
172
+ <div style="margin: 10px 0;">
173
+ <h5>πŸ“Š Generated Plot:</h5>
174
+ <img src="data:image/png;base64,${plotData}"
175
+ style="max-width: 100%; height: auto; border: 1px solid #ddd; border-radius: 3px;"
176
+ alt="Generated Plot">
177
+ </div>
178
+ `;
179
 
180
+ if (textOutput.trim()) {
 
181
  outputText.textContent += '\\n\\nπŸ“Š Plot generated and displayed below!';
182
  } else {
183
  outputText.textContent = 'πŸ“Š Plot generated and displayed below!';
184
  }
185
  updateStatus('βœ… Code executed with plot generated!', 'green');
186
+ return 'Code executed successfully with plot';
187
  } else {
188
+ console.log('No plot data detected');
189
  plotContainer.innerHTML = '';
190
  updateStatus('βœ… Code executed successfully!', 'green');
191
+ return textOutput || 'Code executed successfully';
192
  }
193
 
194
  } catch (error) {
 
217
  safeInitPyodide();
218
  }
219
 
220
+ // Make functions globally available
221
  window.executePyodideCode = executePyodideCode;
222
  window.checkPyodideStatus = () => pyodideReady;
223
  </script>