broadfield-dev commited on
Commit
05977dd
·
verified ·
1 Parent(s): 86f68f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -55
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from flask import Flask, request, send_file, render_template_string
2
  import gradio as gr
3
  import ast
4
  import os
@@ -8,15 +8,15 @@ app = Flask(__name__)
8
 
9
  # Mapping of Gradio components to Toga equivalents
10
  GRADIO_TO_TOGA = {
11
- "Textbox": ("toga.TextInput", "placeholder='Enter Text'"),
12
- "Image": ("toga.Label", "Placeholder: Use file picker for image"),
13
- "Button": ("toga.Button", "on_press=button_handler"),
14
- "Markdown": ("toga.Label", ""),
15
- "Audio": ("toga.Label", "Placeholder: Audio not supported"),
16
- "Video": ("toga.Label", "Placeholder: Video not supported"),
17
  }
18
 
19
- # Parse Gradio app code and extract components
20
  def parse_gradio_code(code):
21
  try:
22
  tree = ast.parse(code)
@@ -37,18 +37,16 @@ def parse_gradio_code(code):
37
 
38
  return components, functions
39
  except Exception as e:
40
- return [], [str(e)]
41
 
42
- # Generate Toga code from parsed components
43
  def generate_toga_code(components, functions):
44
  toga_code = [
45
  "import toga",
46
  "from toga.style import Pack",
47
- "from toga.style.pack import COLUMN, ROW",
48
- "import os",
49
  "",
50
- "# Placeholder for original functions",
51
- "# Copy your original function definitions here",
52
  f"# Detected functions: {', '.join(functions) if functions else 'None'}",
53
  "",
54
  "def build(app):",
@@ -57,38 +55,43 @@ def generate_toga_code(components, functions):
57
  ]
58
 
59
  for idx, comp in enumerate(components):
60
- toga_comp, extra = GRADIO_TO_TOGA.get(comp["type"], ("toga.Label", f"Placeholder: {comp['type']} not supported"))
61
 
62
  # Handle component-specific logic
63
  if comp["type"] == "Textbox":
64
- label = comp["kwargs"].get("label", f"'Text Input {idx}'")
65
  toga_code.append(f" label_{idx} = toga.Label({label}, style=Pack(padding=(5, 5, 0, 5)))")
66
- toga_code.append(f" input_{idx} = {toga_comp}(style=Pack(padding=5))")
67
  toga_code.append(f" box.add(label_{idx})")
68
  toga_code.append(f" box.add(input_{idx})")
69
 
70
- elif comp["type"] == "Image":
71
- toga_code.append(f" image_label_{idx} = toga.Label('Image: None selected', style=Pack(padding=5))")
72
- toga_code.append(f" def select_image_{idx}(widget):")
73
- toga_code.append(f" path = app.main_window.open_file_dialog('Select Image', file_types=['png', 'jpg', 'jpeg'])")
 
 
 
 
 
74
  toga_code.append(f" if path:")
75
- toga_code.append(f" image_label_{idx}.text = f'Image: {{path}}'")
76
- toga_code.append(f" image_button_{idx} = toga.Button('Upload Image', on_press=select_image_{idx}, style=Pack(padding=5))")
77
- toga_code.append(f" box.add(toga.Label('Upload Image', style=Pack(padding=(5, 5, 0, 5))))")
78
- toga_code.append(f" box.add(image_button_{idx})")
79
- toga_code.append(f" box.add(image_label_{idx})")
80
 
81
  elif comp["type"] == "Button":
82
- label = comp["kwargs"].get("value", f"'Submit {idx}'")
83
  toga_code.append(f" def button_handler_{idx}(widget):")
84
- toga_code.append(f" # Placeholder: Implement logic for {functions[0] if functions else 'function'}")
85
  toga_code.append(f" pass")
86
- toga_code.append(f" button_{idx} = {toga_comp}(label={label}, style=Pack(padding=5))")
87
  toga_code.append(f" box.add(button_{idx})")
88
 
89
  elif comp["type"] == "Markdown":
90
- text = comp["args"][0] if comp["args"] else "'Markdown Text'"
91
- toga_code.append(f" markdown_{idx} = {toga_comp}({text}, style=Pack(padding=5, font_size=16))")
92
  toga_code.append(f" box.add(markdown_{idx})")
93
 
94
  else:
@@ -108,7 +111,7 @@ def generate_toga_code(components, functions):
108
 
109
  return "\n".join(toga_code)
110
 
111
- # Gradio interface for file upload
112
  def convert_gradio_to_toga(file):
113
  if not file:
114
  return "Please upload a Gradio app Python file."
@@ -119,53 +122,70 @@ def convert_gradio_to_toga(file):
119
  components, functions = parse_gradio_code(code)
120
 
121
  if not components and functions and isinstance(functions[0], str):
122
- return f"Error parsing code: {functions[0]}"
123
 
124
  # Generate Toga code
125
  toga_code = generate_toga_code(components, functions)
126
 
127
- # Save Toga code to a temporary file
128
- output_path = "toga_app.py"
129
  with open(output_path, "w") as f:
130
  f.write(toga_code)
131
 
132
- return send_file(output_path, as_attachment=True, download_name="toga_app.py")
133
  except Exception as e:
134
  return f"Error: {str(e)}"
135
 
136
  # Gradio interface
137
- def create_gradio_interface():
138
- with gr.Blocks() as interface:
139
- gr.Markdown("# Gradio to Toga Converter")
140
- file_input = gr.File(label="Upload Gradio Python File")
141
- convert_button = gr.Button("Convert to Toga")
142
- output = gr.File(label="Download Toga App")
143
-
144
- convert_button.click(
145
- fn=convert_gradio_to_toga,
146
- inputs=file_input,
147
- outputs=output
148
- )
149
- return interface
150
 
151
  # Flask route
152
  @app.route('/')
153
  def serve_gradio():
154
- interface = create_gradio_interface()
155
- # For Hugging Face Spaces, launch Gradio
156
- interface.launch(share=False, server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))
157
- return render_template_string("""
158
  <!DOCTYPE html>
159
  <html>
160
  <head>
161
  <title>Gradio to Toga Converter</title>
 
 
 
 
 
162
  </head>
163
  <body>
164
  <h1>Gradio to Toga Converter</h1>
165
- <p>Access the Gradio interface to upload your Gradio app and download the Toga equivalent.</p>
166
  </body>
167
  </html>
168
- """)
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
  if __name__ == "__main__":
171
  app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))
 
1
+ from flask import Flask, send_file
2
  import gradio as gr
3
  import ast
4
  import os
 
8
 
9
  # Mapping of Gradio components to Toga equivalents
10
  GRADIO_TO_TOGA = {
11
+ "Textbox": ("toga.TextInput", "style=Pack(padding=5)", "Text Input"),
12
+ "Image": ("toga.Label", "Placeholder: Image file picker", "Image Upload"),
13
+ "Button": ("toga.Button", "on_press=button_handler", "Submit"),
14
+ "Markdown": ("toga.Label", "style=Pack(padding=5, font_size=14)", "Markdown Text"),
15
+ "Audio": ("toga.Label", "Placeholder: Audio file picker", "Audio Upload"),
16
+ "Video": ("toga.Label", "Placeholder: Video file picker", "Video Upload"),
17
  }
18
 
19
+ # Parse Gradio app code
20
  def parse_gradio_code(code):
21
  try:
22
  tree = ast.parse(code)
 
37
 
38
  return components, functions
39
  except Exception as e:
40
+ return [], [f"Error parsing code: {str(e)}"]
41
 
42
+ # Generate Toga code
43
  def generate_toga_code(components, functions):
44
  toga_code = [
45
  "import toga",
46
  "from toga.style import Pack",
47
+ "from toga.style.pack import COLUMN",
 
48
  "",
49
+ "# Original functions (copy these from your Gradio app)",
 
50
  f"# Detected functions: {', '.join(functions) if functions else 'None'}",
51
  "",
52
  "def build(app):",
 
55
  ]
56
 
57
  for idx, comp in enumerate(components):
58
+ toga_comp, extra, label_prefix = GRADIO_TO_TOGA.get(comp["type"], ("toga.Label", f"Placeholder: {comp['type']} not supported", "Unknown"))
59
 
60
  # Handle component-specific logic
61
  if comp["type"] == "Textbox":
62
+ label = comp["kwargs"].get("label", f"'{label_prefix} {idx}'")
63
  toga_code.append(f" label_{idx} = toga.Label({label}, style=Pack(padding=(5, 5, 0, 5)))")
64
+ toga_code.append(f" input_{idx} = {toga_comp}({extra})")
65
  toga_code.append(f" box.add(label_{idx})")
66
  toga_code.append(f" box.add(input_{idx})")
67
 
68
+ elif comp["type"] in ["Image", "Audio", "Video"]:
69
+ file_types = {
70
+ "Image": "['png', 'jpg', 'jpeg']",
71
+ "Audio": "['mp3', 'wav']",
72
+ "Video": "['mp4', 'avi']"
73
+ }.get(comp["type"], "['*']")
74
+ toga_code.append(f" {comp['type'].lower()}_label_{idx} = toga.Label('{label_prefix}: None selected', style=Pack(padding=5))")
75
+ toga_code.append(f" def select_{comp['type'].lower()}_{idx}(widget):")
76
+ toga_code.append(f" path = app.main_window.open_file_dialog('Select {comp['type']}', file_types={file_types})")
77
  toga_code.append(f" if path:")
78
+ toga_code.append(f" {comp['type'].lower()}_label_{idx}.text = f'{label_prefix}: {{path}}'")
79
+ toga_code.append(f" {comp['type'].lower()}_button_{idx} = toga.Button('Upload {comp['type']}', on_press=select_{comp['type'].lower()}_{idx}, style=Pack(padding=5))")
80
+ toga_code.append(f" box.add(toga.Label('{label_prefix}', style=Pack(padding=(5, 5, 0, 5))))")
81
+ toga_code.append(f" box.add({comp['type'].lower()}_button_{idx})")
82
+ toga_code.append(f" box.add({comp['type'].lower()}_label_{idx})")
83
 
84
  elif comp["type"] == "Button":
85
+ label = comp["kwargs"].get("value", f"'{label_prefix} {idx}'")
86
  toga_code.append(f" def button_handler_{idx}(widget):")
87
+ toga_code.append(f" # Implement logic for {functions[0] if functions else 'function'}")
88
  toga_code.append(f" pass")
89
+ toga_code.append(f" button_{idx} = {toga_comp}(label={label}, {extra})")
90
  toga_code.append(f" box.add(button_{idx})")
91
 
92
  elif comp["type"] == "Markdown":
93
+ text = comp["args"][0] if comp["args"] else f"'{label_prefix} {idx}'"
94
+ toga_code.append(f" markdown_{idx} = {toga_comp}({text}, {extra})")
95
  toga_code.append(f" box.add(markdown_{idx})")
96
 
97
  else:
 
111
 
112
  return "\n".join(toga_code)
113
 
114
+ # Conversion function
115
  def convert_gradio_to_toga(file):
116
  if not file:
117
  return "Please upload a Gradio app Python file."
 
122
  components, functions = parse_gradio_code(code)
123
 
124
  if not components and functions and isinstance(functions[0], str):
125
+ return f"Error: {functions[0]}"
126
 
127
  # Generate Toga code
128
  toga_code = generate_toga_code(components, functions)
129
 
130
+ # Save to temporary file
131
+ output_path = "/tmp/toga_app.py"
132
  with open(output_path, "w") as f:
133
  f.write(toga_code)
134
 
135
+ return output_path
136
  except Exception as e:
137
  return f"Error: {str(e)}"
138
 
139
  # Gradio interface
140
+ with gr.Blocks(theme=gr.themes.Soft()) as interface:
141
+ gr.Markdown("# Gradio to Toga Converter")
142
+ gr.Markdown("Upload a Gradio app Python file to convert it to a Toga desktop app.")
143
+ file_input = gr.File(label="Upload Gradio App (.py)", file_types=[".py"])
144
+ convert_button = gr.Button("Convert to Toga")
145
+ output = gr.File(label="Download Toga App (.py)")
146
+ error_message = gr.Textbox(label="Status", interactive=False)
147
+
148
+ convert_button.click(
149
+ fn=convert_gradio_to_toga,
150
+ inputs=file_input,
151
+ outputs=[output, error_message]
152
+ )
153
 
154
  # Flask route
155
  @app.route('/')
156
  def serve_gradio():
157
+ # For Hugging Face Spaces, use environment port
158
+ port = int(os.environ.get("PORT", 7860))
159
+ interface.launch(server_name="0.0.0.0", server_port=port, quiet=True)
160
+ return """
161
  <!DOCTYPE html>
162
  <html>
163
  <head>
164
  <title>Gradio to Toga Converter</title>
165
+ <style>
166
+ body { font-family: Arial, sans-serif; text-align: center; padding: 20px; }
167
+ h1 { color: #333; }
168
+ p { color: #666; }
169
+ </style>
170
  </head>
171
  <body>
172
  <h1>Gradio to Toga Converter</h1>
173
+ <p>The converter is running. Use the Gradio interface to upload your Gradio app and download the Toga version.</p>
174
  </body>
175
  </html>
176
+ """
177
+
178
+ @app.route('/convert', methods=['POST'])
179
+ def convert():
180
+ file = request.files.get('file')
181
+ if not file:
182
+ return {"error": "No file uploaded"}, 400
183
+
184
+ result = convert_gradio_to_toga(file.read())
185
+ if result.startswith("Error"):
186
+ return {"error": result}, 400
187
+
188
+ return send_file(result, as_attachment=True, download_name="toga_app.py")
189
 
190
  if __name__ == "__main__":
191
  app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))