Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1,17 +1,60 @@
|
|
1 |
import gradio as gr
|
2 |
-
import
|
3 |
import sys
|
|
|
4 |
import matplotlib.pyplot as plt
|
5 |
from PIL import Image
|
6 |
|
7 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
def run_code(code, namespace):
|
|
|
9 |
output = io.StringIO()
|
10 |
sys.stdout = output
|
11 |
images = []
|
12 |
try:
|
13 |
exec(code, namespace)
|
14 |
-
# Capture
|
15 |
figs = [plt.figure(i) for i in plt.get_fignums()]
|
16 |
for fig in figs:
|
17 |
buf = io.BytesIO()
|
@@ -20,66 +63,120 @@ def run_code(code, namespace):
|
|
20 |
img = Image.open(buf)
|
21 |
images.append(img)
|
22 |
plt.close('all')
|
|
|
|
|
|
|
|
|
23 |
except Exception as e:
|
24 |
print(f"Error: {e}")
|
|
|
25 |
sys.stdout = sys.__stdout__
|
26 |
-
return output.getvalue(), images, namespace
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
-
#
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
36 |
|
37 |
-
#
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
-
#
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
-
#
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
files = gr.State(initial_files)
|
59 |
-
namespace = gr.State({})
|
60 |
|
61 |
-
#
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
delete_file_button = gr.Button("Delete File")
|
68 |
-
clear_button = gr.Button("Clear Output")
|
69 |
-
reset_button = gr.Button("Reset Namespace")
|
70 |
-
output_display = gr.Textbox(label="Output")
|
71 |
-
image_gallery = gr.Gallery(label="Plots")
|
72 |
|
73 |
-
#
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
reset_button.click(lambda: ({}, "", []), outputs=[namespace, output_display, image_gallery])
|
83 |
|
84 |
-
# Launch the
|
85 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
+
import pickle
|
3 |
import sys
|
4 |
+
import io
|
5 |
import matplotlib.pyplot as plt
|
6 |
from PIL import Image
|
7 |
|
8 |
+
# File persistence functions
|
9 |
+
def save_files(files):
|
10 |
+
"""Save the files dictionary to a pickle file."""
|
11 |
+
with open('files.pkl', 'wb') as f:
|
12 |
+
pickle.dump(files, f)
|
13 |
+
|
14 |
+
def load_files():
|
15 |
+
"""Load the files dictionary from a pickle file or return a default state."""
|
16 |
+
try:
|
17 |
+
with open('files.pkl', 'rb') as f:
|
18 |
+
return pickle.load(f)
|
19 |
+
except FileNotFoundError:
|
20 |
+
return {"main.py": "# Write your code here\nprint('Hello, World!')"}
|
21 |
+
|
22 |
+
# File management functions
|
23 |
+
def add_file(files):
|
24 |
+
"""Add a new file to the files dictionary."""
|
25 |
+
new_file_name = f"file_{len(files)}.py"
|
26 |
+
files[new_file_name] = "# New file"
|
27 |
+
save_files(files)
|
28 |
+
return files, list(files.keys()), new_file_name
|
29 |
+
|
30 |
+
def delete_file(file_name, files):
|
31 |
+
"""Delete a file from the files dictionary if more than one file exists."""
|
32 |
+
if len(files) > 1:
|
33 |
+
del files[file_name]
|
34 |
+
save_files(files)
|
35 |
+
new_file_name = list(files.keys())[0]
|
36 |
+
return files, list(files.keys()), new_file_name, files[new_file_name]
|
37 |
+
return files, list(files.keys()), file_name, files[file_name]
|
38 |
+
|
39 |
+
def update_code(code, file_name, files):
|
40 |
+
"""Update the code for a specific file and save the files state."""
|
41 |
+
files[file_name] = code
|
42 |
+
save_files(files)
|
43 |
+
return files
|
44 |
+
|
45 |
+
def select_file(file_name, files):
|
46 |
+
"""Return the code for the selected file."""
|
47 |
+
return files[file_name]
|
48 |
+
|
49 |
+
# Code execution and command functions
|
50 |
def run_code(code, namespace):
|
51 |
+
"""Execute the code, capture output and plots, and display variables."""
|
52 |
output = io.StringIO()
|
53 |
sys.stdout = output
|
54 |
images = []
|
55 |
try:
|
56 |
exec(code, namespace)
|
57 |
+
# Capture matplotlib plots
|
58 |
figs = [plt.figure(i) for i in plt.get_fignums()]
|
59 |
for fig in figs:
|
60 |
buf = io.BytesIO()
|
|
|
63 |
img = Image.open(buf)
|
64 |
images.append(img)
|
65 |
plt.close('all')
|
66 |
+
# Get user-defined variables
|
67 |
+
variables = {k: v for k, v in namespace.items()
|
68 |
+
if not k.startswith('_') and not callable(v) and not isinstance(v, type(sys))}
|
69 |
+
variables_str = "\nVariables:\n" + "\n".join(f"{k} = {v}" for k, v in variables.items()) if variables else ""
|
70 |
except Exception as e:
|
71 |
print(f"Error: {e}")
|
72 |
+
variables_str = ""
|
73 |
sys.stdout = sys.__stdout__
|
74 |
+
return output.getvalue() + variables_str, images, namespace
|
75 |
|
76 |
+
def run_command(command, namespace, terminal_display):
|
77 |
+
"""Execute a single command and append its output to the terminal display."""
|
78 |
+
output = io.StringIO()
|
79 |
+
sys.stdout = output
|
80 |
+
try:
|
81 |
+
exec(command, namespace)
|
82 |
+
except Exception as e:
|
83 |
+
print(f"Error: {e}")
|
84 |
+
sys.stdout = sys.__stdout__
|
85 |
+
command_output = output.getvalue()
|
86 |
+
return (terminal_display + "\n" + command_output).strip()
|
87 |
|
88 |
+
# Gradio interface
|
89 |
+
with gr.Blocks(title="Python Code Editor") as demo:
|
90 |
+
# Initial states
|
91 |
+
files = gr.State(value=load_files)
|
92 |
+
namespace = gr.State(value={})
|
93 |
|
94 |
+
# Layout
|
95 |
+
with gr.Row():
|
96 |
+
# Sidebar for file management
|
97 |
+
with gr.Column(scale=1, min_width=200):
|
98 |
+
file_selector = gr.Dropdown(
|
99 |
+
choices=list(load_files().keys()),
|
100 |
+
label="Select File",
|
101 |
+
value=list(load_files().keys())[0]
|
102 |
+
)
|
103 |
+
add_file_button = gr.Button("Add File")
|
104 |
+
delete_file_button = gr.Button("Delete File")
|
105 |
+
|
106 |
+
# Main panel
|
107 |
+
with gr.Column(scale=4):
|
108 |
+
code_input = gr.Code(
|
109 |
+
label="Code Editor",
|
110 |
+
language="python",
|
111 |
+
value=load_files()[list(load_files().keys())[0]],
|
112 |
+
lines=20
|
113 |
+
)
|
114 |
+
# Tabbed bottom panel
|
115 |
+
with gr.Tabs():
|
116 |
+
with gr.TabItem("Output"):
|
117 |
+
output_display = gr.Textbox(label="Output", lines=10)
|
118 |
+
image_gallery = gr.Gallery(label="Plots", preview=True)
|
119 |
+
with gr.TabItem("Terminal"):
|
120 |
+
terminal_display = gr.Textbox(
|
121 |
+
label="Terminal Output",
|
122 |
+
lines=10,
|
123 |
+
interactive=False
|
124 |
+
)
|
125 |
+
command_input = gr.Textbox(label="Command Input", placeholder="Enter Python command")
|
126 |
+
run_command_button = gr.Button("Run Command")
|
127 |
+
|
128 |
+
# Control buttons
|
129 |
+
with gr.Row():
|
130 |
+
run_button = gr.Button("Run Code")
|
131 |
+
clear_button = gr.Button("Clear Output")
|
132 |
+
reset_button = gr.Button("Reset Namespace")
|
133 |
|
134 |
+
# Event handlers
|
135 |
+
# File management
|
136 |
+
file_selector.change(
|
137 |
+
fn=select_file,
|
138 |
+
inputs=[file_selector, files],
|
139 |
+
outputs=code_input
|
140 |
+
)
|
141 |
+
add_file_button.click(
|
142 |
+
fn=add_file,
|
143 |
+
inputs=files,
|
144 |
+
outputs=[files, file_selector, file_selector]
|
145 |
+
)
|
146 |
+
delete_file_button.click(
|
147 |
+
fn=delete_file,
|
148 |
+
inputs=[file_selector, files],
|
149 |
+
outputs=[files, file_selector, file_selector, code_input]
|
150 |
+
)
|
151 |
+
code_input.change(
|
152 |
+
fn=update_code,
|
153 |
+
inputs=[code_input, file_selector, files],
|
154 |
+
outputs=files
|
155 |
+
)
|
156 |
|
157 |
+
# Code execution
|
158 |
+
run_button.click(
|
159 |
+
fn=run_code,
|
160 |
+
inputs=[code_input, namespace],
|
161 |
+
outputs=[output_display, image_gallery, namespace]
|
162 |
+
)
|
|
|
|
|
163 |
|
164 |
+
# Terminal command
|
165 |
+
run_command_button.click(
|
166 |
+
fn=run_command,
|
167 |
+
inputs=[command_input, namespace, terminal_display],
|
168 |
+
outputs=terminal_display
|
169 |
+
)
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
+
# Clear and reset
|
172 |
+
clear_button.click(
|
173 |
+
fn=lambda: ("", [], ""),
|
174 |
+
outputs=[output_display, image_gallery, terminal_display]
|
175 |
+
)
|
176 |
+
reset_button.click(
|
177 |
+
fn=lambda: ({}, "", [], ""),
|
178 |
+
outputs=[namespace, output_display, image_gallery, terminal_display]
|
179 |
+
)
|
|
|
180 |
|
181 |
+
# Launch the app
|
182 |
demo.launch()
|