nakas commited on
Commit
ece917e
·
verified ·
1 Parent(s): 1368c37

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -184
app.py CHANGED
@@ -3,34 +3,17 @@ import requests
3
  import re
4
  import os
5
  import subprocess
6
- import uuid
7
- import time
8
- import json
9
- import sys
10
- import importlib.util
11
  import tempfile
 
 
 
12
  import signal
13
  import atexit
14
- from pathlib import Path
15
 
16
  # Print Python version info for debugging
17
  print(f"Python version: {sys.version}")
18
- print(f"Python executable: {sys.executable}")
19
 
20
- # Application directories
21
- APP_DIR = Path(os.getcwd())
22
- VENV_DIR = APP_DIR / "venvs"
23
- os.makedirs(VENV_DIR, exist_ok=True)
24
-
25
- # Make sure we have virtualenv installed
26
- try:
27
- import venv
28
- print("venv module available")
29
- except ImportError:
30
- subprocess.run([sys.executable, "-m", "pip", "install", "virtualenv"], check=True)
31
- print("Installed virtualenv")
32
-
33
- # Track running processes
34
  running_processes = []
35
 
36
  # Clean up any running processes on exit
@@ -59,23 +42,22 @@ Your task is to create a complete, standalone Gradio application based on the us
59
  Provide your response in the following JSON format:
60
  {
61
  "app_code": "# Your Python code here...",
62
- "requirements": ["gradio==3.50.2", "numpy", "pandas", ...],
63
  "app_name": "descriptive-name-of-app",
64
  "description": "Brief description of what the app does"
65
  }
66
 
67
  Important guidelines:
68
  1. The app_code should be a complete Gradio application.
69
- 2. Include gradio.launch(server_name="0.0.0.0", server_port=8000) at the end of the app.
70
  3. Don't use any resource that requires internet access (no API calls).
71
  4. Only use libraries that can be installed via pip.
72
- 5. First requirement should be gradio==3.50.2.
73
- 6. Make sure your code only uses the import statements for packages in the requirements list.
74
- 7. Make the app functionality self-contained and robust.
75
- 8. Don't use any buttons' .click() methods or event handlers - use gr.Interface() instead.
76
  9. Don't create directories or write to any file paths.
77
  10. Don't use flagging callbacks or features.
78
- 11. Don't use __name__ == "__main__" checks, just have the launch call at the end.
79
 
80
  Here's a simple template to follow:
81
 
@@ -97,7 +79,7 @@ demo = gr.Interface(
97
  )
98
 
99
  # Launch the app
100
- demo.launch(server_name="0.0.0.0", server_port=8000)
101
  ```
102
  """
103
 
@@ -163,20 +145,20 @@ demo.launch(server_name="0.0.0.0", server_port=8000)
163
  return None, "Could not extract app code from response"
164
 
165
  # Try to extract requirements
166
- req_pattern = r'```(?:python)?\s*.*?import\s+([a-zA-Z0-9_]+)'
167
- req_matches = re.findall(req_pattern, content)
168
 
169
- requirements = ["gradio==3.50.2"]
170
  if req_matches:
171
  for module in req_matches:
172
- if module != "gradio" and module not in requirements:
173
  requirements.append(module)
174
 
175
  # Construct a partial app_info
176
  app_info = {
177
  "app_code": app_code,
178
  "requirements": requirements,
179
- "app_name": f"gradio-app-{int(time.time())}",
180
  "description": "Generated Gradio application"
181
  }
182
 
@@ -184,115 +166,103 @@ demo.launch(server_name="0.0.0.0", server_port=8000)
184
  except Exception as e:
185
  return None, f"Error: {str(e)}"
186
 
187
- def create_virtual_env(app_info):
188
- """Create a virtual environment with the required packages"""
189
  try:
190
- # Create a unique ID for this app
191
- app_id = str(uuid.uuid4())[:8]
192
- app_name = f"{app_info['app_name']}-{app_id}"
193
- venv_path = VENV_DIR / app_name
194
-
195
- # Create a virtual environment
196
- print(f"Creating virtual environment at {venv_path}")
197
- subprocess.run([sys.executable, "-m", "venv", str(venv_path)], check=True)
198
 
199
- # Determine the pip executable path
200
- if os.name == 'nt': # Windows
201
- pip_path = venv_path / "Scripts" / "pip"
202
- else: # Unix/Linux
203
- pip_path = venv_path / "bin" / "pip"
204
 
205
- # Install required packages
206
- print(f"Installing packages: {', '.join(app_info['requirements'])}")
207
- subprocess.run([str(pip_path), "install", "--upgrade", "pip"], check=True)
208
- for req in app_info["requirements"]:
209
- subprocess.run([str(pip_path), "install", req], check=True)
210
-
211
- return {
212
- "app_id": app_id,
213
- "app_name": app_name,
214
- "venv_path": str(venv_path),
215
- "pip_path": str(pip_path),
216
- "description": app_info["description"],
217
- "code": app_info["app_code"],
218
- "requirements": app_info["requirements"]
219
- }
220
- except Exception as e:
221
- return None, f"Error creating virtual environment: {str(e)}"
222
-
223
- def run_app_in_venv(app_details, app_code):
224
- """Run the Gradio app in a virtual environment"""
225
- try:
226
- # Determine the Python executable path
227
- if os.name == 'nt': # Windows
228
- python_path = Path(app_details["venv_path"]) / "Scripts" / "python"
229
- else: # Unix/Linux
230
- python_path = Path(app_details["venv_path"]) / "bin" / "python"
231
-
232
- # Create a temporary file for the app code
233
- with tempfile.NamedTemporaryFile(suffix='.py', delete=False) as f:
234
- app_file = f.name
235
- f.write(app_code.encode('utf-8'))
236
-
237
- # Change the port to 8000 if not already set
238
  if "server_port" not in app_code:
239
  with open(app_file, 'a') as f:
240
- f.write("\n\n# Ensure the app is running on port 8000\nif 'demo' in locals():\n demo.launch(server_name='0.0.0.0', server_port=8000)\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
 
242
  # Run the app
243
- print(f"Running app with Python: {python_path}")
244
- process = subprocess.Popen(
245
- [str(python_path), app_file],
246
- stdout=subprocess.PIPE,
247
  stderr=subprocess.PIPE,
248
  text=True
249
  )
250
 
251
- running_processes.append(process)
252
 
253
  # Wait a bit for the app to start
254
- time.sleep(5)
255
 
256
  # Check if the process is still running
257
- if process.poll() is not None:
258
- stdout, stderr = process.communicate()
259
- return None, f"App failed to start: {stderr}"
260
 
261
  return {
262
- "process": process,
263
  "app_file": app_file,
264
- "url": "http://localhost:8000",
265
- "process_id": process.pid
 
266
  }, None
267
  except Exception as e:
268
- return None, f"Error running app: {str(e)}"
269
 
270
- def stop_running_app(app_process):
271
- """Stop a running Gradio app process"""
272
- if app_process and app_process.poll() is None:
273
- app_process.terminate()
274
- try:
275
- app_process.wait(timeout=5)
276
- except subprocess.TimeoutExpired:
277
- app_process.kill()
 
 
 
 
 
 
278
 
279
- if app_process in running_processes:
280
- running_processes.remove(app_process)
 
 
 
 
 
281
 
282
  return True
283
- return False
 
 
284
 
285
  # Create the Gradio interface
286
  with gr.Blocks(title="Gradio App Generator") as demo:
287
  gr.Markdown("# 🤖 Gradio App Generator")
288
  gr.Markdown("""
289
- This app generates a Gradio application based on your description and runs it in a virtual environment
290
- with the required dependencies. The generated app will be displayed below.
291
  """)
292
 
293
- # State variables to track the running app
294
- running_app_process = gr.State(None)
295
- running_app_file = gr.State(None)
296
 
297
  with gr.Row():
298
  with gr.Column(scale=1):
@@ -309,12 +279,6 @@ with gr.Blocks(title="Gradio App Generator") as demo:
309
  lines=5
310
  )
311
 
312
- install_bar = gr.HTML(
313
- "<div id='install-status'></div>",
314
- visible=False,
315
- label="Installation Status"
316
- )
317
-
318
  with gr.Row():
319
  generate_btn = gr.Button("Generate & Run App", variant="primary")
320
  stop_btn = gr.Button("Stop Running App", variant="stop", visible=False)
@@ -322,8 +286,8 @@ with gr.Blocks(title="Gradio App Generator") as demo:
322
  with gr.Accordion("Generated Code", open=False):
323
  code_output = gr.Code(language="python", label="App Code")
324
 
325
- with gr.Accordion("Requirements", open=False):
326
- req_output = gr.Textbox(label="Required Packages")
327
 
328
  status_output = gr.Markdown("")
329
 
@@ -331,127 +295,107 @@ with gr.Blocks(title="Gradio App Generator") as demo:
331
  # Frame to display the running app
332
  app_frame = gr.HTML("<div style='text-align:center; padding:50px;'><h3>Your generated app will appear here</h3></div>")
333
 
334
- def on_generate(api_key_val, prompt_val, running_process, app_file):
335
  # Stop any previously running app
336
- if running_process:
337
- stop_running_app(running_process)
338
-
339
- # Clean up previous app file
340
- if app_file and os.path.exists(app_file):
341
- try:
342
- os.unlink(app_file)
343
- except:
344
- pass
345
 
346
  # Validate API key
347
  if not api_key_val or len(api_key_val) < 20 or not api_key_val.startswith("sk-"):
348
  return (
349
- None, None, None, "⚠️ Please provide a valid OpenAI API key",
350
  "<div style='text-align:center; padding:50px;'><h3>Invalid API key</h3></div>",
351
- gr.update(visible=False), gr.update(visible=False), running_process, app_file
352
  )
353
 
354
  try:
355
- # Generate code via API
 
 
 
 
 
 
 
356
  app_info, api_error = call_openai_api(api_key_val, prompt_val)
357
  if api_error or not app_info:
358
  return (
359
- None, None, None, f"⚠️ {api_error or 'Failed to generate app'}",
360
  "<div style='text-align:center; padding:50px;'><h3>Error generating app</h3></div>",
361
- gr.update(visible=False), gr.update(visible=False), running_process, app_file
362
  )
363
 
364
- # Create virtual environment with required packages
365
- install_status = f"<div style='padding:10px; background-color:#f0f0f0; border-radius:5px;'>"
366
- install_status += f"<p>Creating virtual environment for '{app_info['app_name']}'...</p>"
367
- install_status += f"<p>Installing packages: {', '.join(app_info['requirements'])}</p>"
368
- install_status += "</div>"
369
 
 
370
  yield (
371
- app_info["app_code"], "\n".join(app_info["requirements"]), None,
372
- " Setting up virtual environment and installing packages...",
373
- "<div style='text-align:center; padding:50px;'><h3>Preparing your app...</h3></div>",
374
- gr.update(visible=True, value=install_status), gr.update(visible=False), running_process, app_file
375
  )
376
 
377
- venv_details, venv_error = create_virtual_env(app_info)
378
- if venv_error or not venv_details:
379
- return (
380
- app_info["app_code"], "\n".join(app_info["requirements"]), None,
381
- f"⚠️ {venv_error or 'Failed to create virtual environment'}",
382
- "<div style='text-align:center; padding:50px;'><h3>Error setting up environment</h3></div>",
383
- gr.update(visible=False), gr.update(visible=False), running_process, app_file
384
- )
385
-
386
- # Run the app
387
- app_result, app_error = run_app_in_venv(venv_details, app_info["app_code"])
388
- if app_error or not app_result:
389
  return (
390
- app_info["app_code"], "\n".join(app_info["requirements"]), None,
391
- f"⚠️ {app_error or 'Failed to run app'}",
392
  "<div style='text-align:center; padding:50px;'><h3>Error running app</h3></div>",
393
- gr.update(visible=False), gr.update(visible=False), running_process, app_file
394
  )
395
 
396
- # Display the running app in an iframe
397
  iframe_html = f"""
398
  <div style="height:600px; border:1px solid #ddd; border-radius:5px; overflow:hidden;">
399
- <iframe src="http://localhost:8000" width="100%" height="100%" frameborder="0"></iframe>
400
  </div>
401
  """
402
 
403
  return (
404
- app_info["app_code"], "\n".join(app_info["requirements"]), None,
405
- f"✅ App '{venv_details['app_name']}' is running! View it below.",
406
  iframe_html,
407
- gr.update(visible=False), gr.update(visible=True), app_result["process"], app_result["app_file"]
408
  )
409
  except Exception as e:
410
  import traceback
411
  error_details = traceback.format_exc()
412
  return (
413
- None, None, None, f"⚠️ Error: {str(e)}\n\n{error_details}",
414
  "<div style='text-align:center; padding:50px;'><h3>An error occurred</h3></div>",
415
- gr.update(visible=False), gr.update(visible=False), running_process, app_file
416
  )
417
 
418
- def on_stop(running_process, app_file):
419
- if running_process:
420
- stopped = stop_running_app(running_process)
421
-
422
- # Clean up app file
423
- if app_file and os.path.exists(app_file):
424
- try:
425
- os.unlink(app_file)
426
- except:
427
- pass
428
-
429
  if stopped:
430
  return (
431
  "✅ App stopped successfully",
432
  "<div style='text-align:center; padding:50px;'><h3>App stopped</h3></div>",
433
- gr.update(visible=False), None, None
434
  )
435
 
436
  return (
437
  "⚠️ No app was running",
438
  "<div style='text-align:center; padding:50px;'><h3>No app was running</h3></div>",
439
- gr.update(visible=False), None, None
440
  )
441
 
442
  generate_btn.click(
443
  on_generate,
444
- inputs=[api_key, prompt, running_app_process, running_app_file],
445
  outputs=[
446
- code_output, req_output, install_bar, status_output, app_frame,
447
- install_bar, stop_btn, running_app_process, running_app_file
448
  ]
449
  )
450
 
451
  stop_btn.click(
452
  on_stop,
453
- inputs=[running_app_process, running_app_file],
454
- outputs=[status_output, app_frame, stop_btn, running_app_process, running_app_file]
455
  )
456
 
457
  if __name__ == "__main__":
 
3
  import re
4
  import os
5
  import subprocess
 
 
 
 
 
6
  import tempfile
7
+ import sys
8
+ import json
9
+ import time
10
  import signal
11
  import atexit
 
12
 
13
  # Print Python version info for debugging
14
  print(f"Python version: {sys.version}")
 
15
 
16
+ # Track running processes for cleanup
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  running_processes = []
18
 
19
  # Clean up any running processes on exit
 
42
  Provide your response in the following JSON format:
43
  {
44
  "app_code": "# Your Python code here...",
45
+ "requirements": ["gradio==3.32.0", "numpy", "pandas", ...],
46
  "app_name": "descriptive-name-of-app",
47
  "description": "Brief description of what the app does"
48
  }
49
 
50
  Important guidelines:
51
  1. The app_code should be a complete Gradio application.
52
+ 2. Include demo.launch(server_name="0.0.0.0", server_port=7861) at the end of the code
53
  3. Don't use any resource that requires internet access (no API calls).
54
  4. Only use libraries that can be installed via pip.
55
+ 5. First requirement should be gradio==3.32.0 (important: use exactly this version).
56
+ 6. Use only gr.Interface instead of gr.Blocks to avoid version compatibility issues.
57
+ 7. Don't use any buttons' .click() methods or event handlers - use gr.Interface() only.
58
+ 8. Make the app functionality self-contained and robust.
59
  9. Don't create directories or write to any file paths.
60
  10. Don't use flagging callbacks or features.
 
61
 
62
  Here's a simple template to follow:
63
 
 
79
  )
80
 
81
  # Launch the app
82
+ demo.launch(server_name="0.0.0.0", server_port=7861)
83
  ```
84
  """
85
 
 
145
  return None, "Could not extract app code from response"
146
 
147
  # Try to extract requirements
148
+ req_pattern = r'import\s+([a-zA-Z0-9_]+)'
149
+ req_matches = re.findall(req_pattern, app_code)
150
 
151
+ requirements = ["gradio==3.32.0"]
152
  if req_matches:
153
  for module in req_matches:
154
+ if module != "gradio" and module not in requirements and module != "os" and module != "sys":
155
  requirements.append(module)
156
 
157
  # Construct a partial app_info
158
  app_info = {
159
  "app_code": app_code,
160
  "requirements": requirements,
161
+ "app_name": "gradio-app",
162
  "description": "Generated Gradio application"
163
  }
164
 
 
166
  except Exception as e:
167
  return None, f"Error: {str(e)}"
168
 
169
+ def install_and_run_app(app_code, requirements):
170
+ """Install requirements and run the app in a subprocess"""
171
  try:
172
+ # Create a temporary directory for the app
173
+ temp_dir = tempfile.mkdtemp()
 
 
 
 
 
 
174
 
175
+ # Create app file
176
+ app_file = os.path.join(temp_dir, "app.py")
177
+ with open(app_file, 'w') as f:
178
+ f.write(app_code)
 
179
 
180
+ # Make sure port 7861 is specified
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  if "server_port" not in app_code:
182
  with open(app_file, 'a') as f:
183
+ f.write("\n\n# Ensure the app is running on port 7861\n")
184
+ f.write("if 'demo' in locals():\n")
185
+ f.write(" demo.launch(server_name='0.0.0.0', server_port=7861)\n")
186
+
187
+ # Install requirements
188
+ pip_output = ""
189
+ for req in requirements:
190
+ try:
191
+ cmd = [sys.executable, "-m", "pip", "install", req]
192
+ result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
193
+ pip_output += f"Installing {req}: {'SUCCESS' if result.returncode == 0 else 'FAILED'}\n"
194
+ if result.returncode != 0:
195
+ pip_output += f"Error: {result.stderr}\n"
196
+ except Exception as e:
197
+ pip_output += f"Error installing {req}: {str(e)}\n"
198
 
199
  # Run the app
200
+ cmd = [sys.executable, app_file]
201
+ app_process = subprocess.Popen(
202
+ cmd,
203
+ stdout=subprocess.PIPE,
204
  stderr=subprocess.PIPE,
205
  text=True
206
  )
207
 
208
+ running_processes.append(app_process)
209
 
210
  # Wait a bit for the app to start
211
+ time.sleep(3)
212
 
213
  # Check if the process is still running
214
+ if app_process.poll() is not None:
215
+ stdout, stderr = app_process.communicate()
216
+ return None, f"App failed to start:\n{stderr}\n\nInstallation log:\n{pip_output}"
217
 
218
  return {
219
+ "process": app_process,
220
  "app_file": app_file,
221
+ "temp_dir": temp_dir,
222
+ "url": "http://localhost:7861",
223
+ "pip_output": pip_output
224
  }, None
225
  except Exception as e:
226
+ return None, f"Error setting up and running app: {str(e)}"
227
 
228
+ def stop_running_app(app_details):
229
+ """Stop a running app and clean up"""
230
+ try:
231
+ if app_details and "process" in app_details:
232
+ process = app_details["process"]
233
+ if process.poll() is None: # If process is still running
234
+ process.terminate()
235
+ try:
236
+ process.wait(timeout=5)
237
+ except subprocess.TimeoutExpired:
238
+ process.kill()
239
+
240
+ if process in running_processes:
241
+ running_processes.remove(process)
242
 
243
+ # Clean up temp directory
244
+ if app_details and "temp_dir" in app_details:
245
+ import shutil
246
+ try:
247
+ shutil.rmtree(app_details["temp_dir"])
248
+ except:
249
+ pass
250
 
251
  return True
252
+ except Exception as e:
253
+ print(f"Error stopping app: {str(e)}")
254
+ return False
255
 
256
  # Create the Gradio interface
257
  with gr.Blocks(title="Gradio App Generator") as demo:
258
  gr.Markdown("# 🤖 Gradio App Generator")
259
  gr.Markdown("""
260
+ This app generates a Gradio application based on your description, installs required packages,
261
+ and runs it directly within this container. The generated app will be displayed below.
262
  """)
263
 
264
+ # State variable to track running app details
265
+ app_details_state = gr.State(None)
 
266
 
267
  with gr.Row():
268
  with gr.Column(scale=1):
 
279
  lines=5
280
  )
281
 
 
 
 
 
 
 
282
  with gr.Row():
283
  generate_btn = gr.Button("Generate & Run App", variant="primary")
284
  stop_btn = gr.Button("Stop Running App", variant="stop", visible=False)
 
286
  with gr.Accordion("Generated Code", open=False):
287
  code_output = gr.Code(language="python", label="App Code")
288
 
289
+ with gr.Accordion("Package Installation Log", open=False):
290
+ install_output = gr.Textbox(label="Installation Log", lines=5)
291
 
292
  status_output = gr.Markdown("")
293
 
 
295
  # Frame to display the running app
296
  app_frame = gr.HTML("<div style='text-align:center; padding:50px;'><h3>Your generated app will appear here</h3></div>")
297
 
298
+ def on_generate(api_key_val, prompt_val, current_app_details):
299
  # Stop any previously running app
300
+ if current_app_details:
301
+ stop_running_app(current_app_details)
 
 
 
 
 
 
 
302
 
303
  # Validate API key
304
  if not api_key_val or len(api_key_val) < 20 or not api_key_val.startswith("sk-"):
305
  return (
306
+ None, None, "⚠️ Please provide a valid OpenAI API key",
307
  "<div style='text-align:center; padding:50px;'><h3>Invalid API key</h3></div>",
308
+ gr.update(visible=False), None
309
  )
310
 
311
  try:
312
+ # Call the OpenAI API to generate app code and requirements
313
+ status_message = "⏳ Generating app code..."
314
+ yield (
315
+ None, None, status_message,
316
+ "<div style='text-align:center; padding:50px;'><h3>Generating code...</h3></div>",
317
+ gr.update(visible=False), None
318
+ )
319
+
320
  app_info, api_error = call_openai_api(api_key_val, prompt_val)
321
  if api_error or not app_info:
322
  return (
323
+ None, None, f"⚠️ {api_error or 'Failed to generate app'}",
324
  "<div style='text-align:center; padding:50px;'><h3>Error generating app</h3></div>",
325
+ gr.update(visible=False), None
326
  )
327
 
328
+ # At this point we have app code and requirements
329
+ code = app_info["app_code"]
330
+ requirements = app_info["requirements"]
 
 
331
 
332
+ status_message = "⏳ Installing packages and starting app..."
333
  yield (
334
+ code, None, status_message,
335
+ "<div style='text-align:center; padding:50px;'><h3>Installing packages...</h3></div>",
336
+ gr.update(visible=False), None
 
337
  )
338
 
339
+ # Install packages and run the app
340
+ app_details, run_error = install_and_run_app(code, requirements)
341
+ if run_error or not app_details:
 
 
 
 
 
 
 
 
 
342
  return (
343
+ code, None, f"⚠️ {run_error or 'Failed to run app'}",
 
344
  "<div style='text-align:center; padding:50px;'><h3>Error running app</h3></div>",
345
+ gr.update(visible=False), None
346
  )
347
 
348
+ # Create iframe to display the app
349
  iframe_html = f"""
350
  <div style="height:600px; border:1px solid #ddd; border-radius:5px; overflow:hidden;">
351
+ <iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
352
  </div>
353
  """
354
 
355
  return (
356
+ code, app_details["pip_output"],
357
+ f"✅ App is running! View it below.",
358
  iframe_html,
359
+ gr.update(visible=True), app_details
360
  )
361
  except Exception as e:
362
  import traceback
363
  error_details = traceback.format_exc()
364
  return (
365
+ None, None, f"⚠️ Error: {str(e)}\n\n{error_details}",
366
  "<div style='text-align:center; padding:50px;'><h3>An error occurred</h3></div>",
367
+ gr.update(visible=False), None
368
  )
369
 
370
+ def on_stop(current_app_details):
371
+ if current_app_details:
372
+ stopped = stop_running_app(current_app_details)
 
 
 
 
 
 
 
 
373
  if stopped:
374
  return (
375
  "✅ App stopped successfully",
376
  "<div style='text-align:center; padding:50px;'><h3>App stopped</h3></div>",
377
+ gr.update(visible=False), None
378
  )
379
 
380
  return (
381
  "⚠️ No app was running",
382
  "<div style='text-align:center; padding:50px;'><h3>No app was running</h3></div>",
383
+ gr.update(visible=False), None
384
  )
385
 
386
  generate_btn.click(
387
  on_generate,
388
+ inputs=[api_key, prompt, app_details_state],
389
  outputs=[
390
+ code_output, install_output, status_output, app_frame,
391
+ stop_btn, app_details_state
392
  ]
393
  )
394
 
395
  stop_btn.click(
396
  on_stop,
397
+ inputs=[app_details_state],
398
+ outputs=[status_output, app_frame, stop_btn, app_details_state]
399
  )
400
 
401
  if __name__ == "__main__":