Spaces:
Sleeping
Sleeping
File size: 9,935 Bytes
6e19f63 1368c37 018aa15 ece917e 018aa15 8be8236 018aa15 da5bcdc 018aa15 6e19f63 018aa15 6e19f63 018aa15 44abb7c 018aa15 07aeb52 018aa15 07aeb52 018aa15 07aeb52 018aa15 da5bcdc 8be8236 018aa15 9833992 018aa15 9833992 018aa15 9833992 8be8236 018aa15 8be8236 018aa15 1368c37 018aa15 9833992 018aa15 9833992 018aa15 8be8236 018aa15 6e19f63 07aeb52 018aa15 83a7163 018aa15 9833992 018aa15 e9c6962 018aa15 9833992 018aa15 9833992 018aa15 e9c6962 07aeb52 018aa15 07aeb52 f8ca66e 018aa15 07aeb52 e9c6962 07aeb52 83a7163 07aeb52 018aa15 e9c6962 07aeb52 e9c6962 9833992 018aa15 e9c6962 018aa15 57a2c17 018aa15 9e8ab62 018aa15 44abb7c 018aa15 9833992 018aa15 9833992 018aa15 9833992 018aa15 9833992 018aa15 8be8236 07aeb52 018aa15 e9c6962 018aa15 9833992 018aa15 1368c37 018aa15 9e8ab62 1368c37 018aa15 44abb7c 07aeb52 1368c37 018aa15 9833992 018aa15 9e8ab62 7928d62 fc0b4cb 9833992 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
import gradio as gr
import os
import tempfile
import requests
import subprocess
import re
import time
import sys
# Global variables to track resources
app_process = None
temp_file_path = None
def cleanup():
"""Clean up resources when the app exits"""
global app_process, temp_file_path
if app_process and app_process.poll() is None:
print("Stopping running process...")
app_process.terminate()
time.sleep(1)
if app_process.poll() is None:
app_process.kill()
if temp_file_path and os.path.exists(temp_file_path):
print(f"Removing temp file: {temp_file_path}")
try:
os.unlink(temp_file_path)
except Exception as e:
print(f"Error removing temp file: {e}")
# Register cleanup function to run at exit
import atexit
atexit.register(cleanup)
def get_app_code(api_key, description):
"""Get app code from the OpenAI API"""
prompt = f"""Create a simple Gradio app that {description}.
VERY IMPORTANT: You MUST include this to disable flagging which creates permission errors:
gr.Interface(..., flagging_callback=None)
The app should:
1. Use gr.Interface with flagging_callback=None
2. Be self-contained and not use any external dependencies
3. Use only Python standard library and NumPy/Pandas if needed
4. Include demo.launch(server_name="0.0.0.0", server_port=7861) at the end
5. Do NOT create any directories or write any files
Provide ONLY Python code with no explanation or markdown."""
try:
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
},
json={
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "You are a Gradio expert. Provide only Python code without explanations."},
{"role": "user", "content": prompt}
],
"temperature": 0.2
}
)
if response.status_code != 200:
return None, f"API Error: {response.status_code}"
content = response.json()["choices"][0]["message"]["content"]
# Extract code blocks if present
code_pattern = r'```python\s*([\s\S]*?)```'
code_matches = re.findall(code_pattern, content)
if code_matches:
return code_matches[0], None
# If no code blocks found, use the whole content
return content, None
except Exception as e:
return None, f"Error: {str(e)}"
def ensure_flagging_disabled(code):
"""Ensure flagging is disabled in the code"""
# Check if flagging_callback=None is present in Interface creation
if 'Interface(' in code and 'flagging_callback=None' not in code:
# Insert flagging_callback=None in the Interface parameters
code = code.replace('Interface(', 'Interface(flagging_callback=None, ')
return code
def run_gradio_app(code):
"""Save the code to a temp file and run it as a subprocess"""
global app_process, temp_file_path
# Stop any existing process
if app_process and app_process.poll() is None:
app_process.terminate()
time.sleep(1)
if app_process.poll() is None:
app_process.kill()
# Remove any existing temp file
if temp_file_path and os.path.exists(temp_file_path):
try:
os.unlink(temp_file_path)
except:
pass
# Create a new temp file
fd, temp_file_path = tempfile.mkstemp(suffix='.py')
os.close(fd)
# Ensure flagging is disabled
modified_code = ensure_flagging_disabled(code)
# Write code to file
with open(temp_file_path, 'w') as f:
f.write(modified_code)
# Run the app as a subprocess
try:
app_process = subprocess.Popen(
[sys.executable, temp_file_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Wait a moment for the app to start
time.sleep(3)
# Check if process is still running
if app_process.poll() is not None:
# Get error output
_, stderr = app_process.communicate()
error_msg = stderr.decode('utf-8')
return False, f"App failed to start:\n{error_msg}"
return True, None
except Exception as e:
return False, f"Error launching app: {str(e)}"
# Create demo app for direct usage
def make_demo_app(app_type):
"""Create a simple demo app based on type"""
if app_type == "calculator":
return """
import gradio as gr
import numpy as np
def calculate(num1, num2, operation):
if operation == "Add":
return num1 + num2
elif operation == "Subtract":
return num1 - num2
elif operation == "Multiply":
return num1 * num2
elif operation == "Divide":
return num1 / num2 if num2 != 0 else "Error: Division by zero"
else:
return "Invalid operation"
demo = gr.Interface(
fn=calculate,
inputs=[
gr.Number(label="First Number"),
gr.Number(label="Second Number"),
gr.Radio(["Add", "Subtract", "Multiply", "Divide"], label="Operation")
],
outputs=gr.Textbox(label="Result"),
title="Simple Calculator",
flagging_callback=None
)
demo.launch(server_name="0.0.0.0", server_port=7861)
"""
elif app_type == "image":
return """
import gradio as gr
import numpy as np
from PIL import Image
def grayscale(img):
gray_img = np.mean(img, axis=2).astype(np.uint8)
return gray_img
demo = gr.Interface(
fn=grayscale,
inputs=gr.Image(type="numpy"),
outputs=gr.Image(type="numpy"),
title="Image Grayscale Converter",
flagging_callback=None
)
demo.launch(server_name="0.0.0.0", server_port=7861)
"""
else: # Default hello world
return """
import gradio as gr
def greet(name):
return f"Hello, {name}!"
demo = gr.Interface(
fn=greet,
inputs=gr.Textbox(label="Your Name"),
outputs=gr.Textbox(label="Greeting"),
title="Hello World App",
flagging_callback=None
)
demo.launch(server_name="0.0.0.0", server_port=7861)
"""
# Create a very simple Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# 🤖 Simple Gradio App Generator")
with gr.Tab("Generate Custom App"):
api_key = gr.Textbox(label="OpenAI API Key", placeholder="sk-...", type="password")
description = gr.Textbox(label="Describe the app you want", lines=3)
generate_btn = gr.Button("Generate & Run App")
with gr.Tab("Quick Demo Apps"):
demo_type = gr.Radio(
["hello", "calculator", "image"],
label="Select Demo App",
value="hello"
)
demo_btn = gr.Button("Run Demo App")
with gr.Row():
stop_btn = gr.Button("Stop Running App", visible=False)
code_display = gr.Code(label="Generated Code", language="python")
status = gr.Markdown("")
# Frame to display the running app
app_display = gr.HTML("<div style='text-align:center; margin-top:20px;'>App will appear here</div>")
def generate_and_run(key, desc):
if not key or len(key) < 20:
return None, "Please enter a valid API key", gr.update(visible=False), gr.update(visible=False)
# Get code from API
code, error = get_app_code(key, desc)
if error:
return None, f"Error: {error}", gr.update(visible=False), gr.update(visible=False)
# Run the app
success, run_error = run_gradio_app(code)
if not success:
return code, f"Error running app: {run_error}", gr.update(visible=False), gr.update(visible=False)
# Create iframe to show the app
iframe = f"""
<div style="border:1px solid #ddd; border-radius:5px; height:500px; margin-top:10px;">
<iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
</div>
"""
return code, "✅ App is running! View it below:", iframe, gr.update(visible=True)
def run_demo(app_type):
code = make_demo_app(app_type)
success, run_error = run_gradio_app(code)
if not success:
return code, f"Error running demo: {run_error}", gr.update(visible=False), gr.update(visible=False)
# Create iframe to show the app
iframe = f"""
<div style="border:1px solid #ddd; border-radius:5px; height:500px; margin-top:10px;">
<iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
</div>
"""
return code, "✅ Demo app is running! View it below:", iframe, gr.update(visible=True)
def stop_app():
global app_process
if app_process and app_process.poll() is None:
app_process.terminate()
time.sleep(1)
if app_process.poll() is None:
app_process.kill()
return "App stopped", "<div style='text-align:center; margin-top:20px;'>App stopped</div>", gr.update(visible=False)
generate_btn.click(
generate_and_run,
inputs=[api_key, description],
outputs=[code_display, status, app_display, stop_btn]
)
demo_btn.click(
run_demo,
inputs=[demo_type],
outputs=[code_display, status, app_display, stop_btn]
)
stop_btn.click(
stop_app,
inputs=[],
outputs=[status, app_display, stop_btn]
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860) |