akhaliq HF Staff commited on
Commit
668c0c5
·
verified ·
1 Parent(s): 6f82fc0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -54
app.py CHANGED
@@ -1,17 +1,60 @@
1
  import gradio as gr
2
- import io
3
  import sys
 
4
  import matplotlib.pyplot as plt
5
  from PIL import Image
6
 
7
- # Function to execute code and capture output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  def run_code(code, namespace):
 
9
  output = io.StringIO()
10
  sys.stdout = output
11
  images = []
12
  try:
13
  exec(code, namespace)
14
- # Capture any matplotlib plots
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
- # Function to load code for the selected file
29
- def select_file(file_name, files):
30
- return files[file_name]
 
 
 
 
 
 
 
 
31
 
32
- # Function to update the files state when code is edited
33
- def update_code(code, file_name, files):
34
- files[file_name] = code
35
- return files
 
36
 
37
- # Function to add a new file
38
- def add_file(files):
39
- new_file_name = f"file_{len(files)}.py"
40
- files[new_file_name] = "# New file"
41
- return files, list(files.keys()), new_file_name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- # Function to delete the current file
44
- def delete_file(file_name, files):
45
- if len(files) > 1: # Prevent deleting the last file
46
- del files[file_name]
47
- new_file_name = list(files.keys())[0]
48
- return files, list(files.keys()), new_file_name, files[new_file_name]
49
- else:
50
- return files, list(files.keys()), file_name, files[file_name]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- # Build the interface
53
- with gr.Blocks(title="Simple IDE with Gradio") as demo:
54
- # Initial state
55
- initial_files = {"main.py": "# Write your code here\nprint('Hello, World!')"}
56
-
57
- # State components
58
- files = gr.State(initial_files)
59
- namespace = gr.State({})
60
 
61
- # UI components
62
- file_selector = gr.Dropdown(choices=list(initial_files.keys()), label="Select File")
63
- code_input = gr.Code(label="Code Editor", language="python", value=initial_files["main.py"])
64
- with gr.Row():
65
- run_button = gr.Button("Run")
66
- add_file_button = gr.Button("Add File")
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
- # Event handlers
74
- file_selector.change(select_file, inputs=[file_selector, files], outputs=code_input)
75
- code_input.change(update_code, inputs=[code_input, file_selector, files], outputs=files)
76
- add_file_button.click(add_file, inputs=files, outputs=[files, file_selector, file_selector])
77
- delete_file_button.click(delete_file, inputs=[file_selector, files],
78
- outputs=[files, file_selector, file_selector, code_input])
79
- run_button.click(run_code, inputs=[code_input, namespace],
80
- outputs=[output_display, image_gallery, namespace])
81
- clear_button.click(lambda: ("", []), outputs=[output_display, image_gallery])
82
- reset_button.click(lambda: ({}, "", []), outputs=[namespace, output_display, image_gallery])
83
 
84
- # Launch the interface
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()