acecalisto3 commited on
Commit
beda045
·
verified ·
1 Parent(s): c9cb3bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -228
app.py CHANGED
@@ -7,13 +7,8 @@ import tempfile
7
  import time
8
  from pathlib import Path
9
  from datetime import datetime
10
- import asyncio
11
- import aiohttp
12
- from typing import List, Dict, Any
13
  import logging
14
- import black
15
- from pylint import lint
16
- from io import StringIO
17
 
18
  # Configure logging
19
  logging.basicConfig(
@@ -22,6 +17,94 @@ logging.basicConfig(
22
  )
23
  logger = logging.getLogger(__name__)
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  class EnhancedAppBuilder:
26
  def __init__(self):
27
  self.TEMPLATES = {
@@ -54,32 +137,15 @@ class EnhancedAppBuilder:
54
  "multiple": False
55
  },
56
  "code_snippet": 'gr.File(file_types={file_types}, label="{label}")'
57
- },
58
- "DataTable": {
59
- "properties": {
60
- "headers": [],
61
- "row_count": 10,
62
- "interactive": True
63
- },
64
- "code_snippet": 'gr.Dataframe(headers={headers}, interactive={interactive})'
65
- },
66
- "3D Plot": {
67
- "properties": {
68
- "type": ["surface", "scatter3d", "line3d"],
69
- "data": None
70
- },
71
- "code_snippet": 'gr.Plot3D(value=plot3d_{id})'
72
  }
73
  }
74
 
75
  async def validate_component(self, component: Dict) -> tuple:
76
- """Validate component configuration"""
77
  try:
78
  required_fields = ["type", "properties", "id"]
79
  if not all(field in component for field in required_fields):
80
  return False, "Missing required fields"
81
 
82
- # Validate component type
83
  if component["type"] not in {**components_registry, **self.ADVANCED_COMPONENTS}:
84
  return False, f"Invalid component type: {component['type']}"
85
 
@@ -87,187 +153,56 @@ class EnhancedAppBuilder:
87
  except Exception as e:
88
  return False, f"Validation error: {str(e)}"
89
 
90
- def format_code(self, code: str) -> str:
91
- """Format Python code using black"""
92
- try:
93
- return black.format_str(code, mode=black.FileMode())
94
- except Exception as e:
95
- logger.error(f"Code formatting error: {str(e)}")
96
- return code
97
-
98
- def lint_code(self, code: str) -> List[str]:
99
- """Run pylint on generated code"""
100
- with tempfile.NamedTemporaryFile(mode='w', suffix='.py') as tmp:
101
- tmp.write(code)
102
- tmp.flush()
103
-
104
- output = StringIO()
105
- lint.Run([tmp.name], do_exit=False, reporter=lint.reporters.TextReporter(output))
106
- return output.getvalue().split('\n')
107
-
108
- async def optimize_layout(self, components: List[Dict]) -> List[Dict]:
109
- """Optimize component layout for better UX"""
110
- # Group related components
111
- groups = {}
112
- for comp in components:
113
- category = comp['type'].split('_')[0]
114
- if category not in groups:
115
- groups[category] = []
116
- groups[category].append(comp)
117
-
118
- # Arrange components in optimal order
119
- optimized = []
120
- for category in ['input', 'process', 'output']:
121
- if category in groups:
122
- optimized.extend(groups[category])
123
-
124
- return optimized
125
-
126
  class EnhancedAppCreationProcess(AppCreationProcess):
127
  def __init__(self):
128
  super().__init__()
129
  self.builder = EnhancedAppBuilder()
130
  self.history = []
131
- self.current_theme = "Default"
132
- self.custom_css = ""
133
  self.event_handlers = {}
134
  self.dependencies = []
135
-
136
  def save_snapshot(self):
137
- """Save current state snapshot"""
138
  snapshot = {
139
  'timestamp': datetime.now().isoformat(),
140
  'app_name': self.app_name,
141
  'components': self.components.copy(),
142
- 'theme': self.current_theme,
143
  'custom_css': self.custom_css
144
  }
145
  self.history.append(snapshot)
146
 
147
- def restore_snapshot(self, index: int):
148
- """Restore from saved snapshot"""
149
- if 0 <= index < len(self.history):
150
- snapshot = self.history[index]
151
- self.app_name = snapshot['app_name']
152
- self.components = snapshot['components']
153
- self.current_theme = snapshot['theme']
154
- self.custom_css = snapshot['custom_css']
155
- return "Snapshot restored successfully"
156
- return "Invalid snapshot index"
157
-
158
  async def generate_enhanced_code(self):
159
- """Generate enhanced application code"""
160
  try:
161
- # Start with imports
162
  code = """import gradio as gr
163
  import pandas as pd
164
  import numpy as np
165
- import plotly.express as px
166
  from pathlib import Path
167
  import logging
168
- import json
169
 
170
- # Configure logging
171
  logging.basicConfig(level=logging.INFO)
172
  logger = logging.getLogger(__name__)
173
  """
174
-
175
- # Add theme configuration
176
- theme_config = self.builder.THEMES.get(self.current_theme, {})
177
  code += f"\ntheme = gr.themes.Default({', '.join(f'{k}={v!r}' for k, v in theme_config.items())})\n"
178
 
179
- # Add custom CSS
180
  if self.custom_css:
181
  code += f"\ncustom_css = '''{self.custom_css}'''\n"
182
 
183
- # Start app definition
184
  code += f"\nwith gr.Blocks(theme=theme{',' if self.custom_css else ''} css=custom_css) as {self.app_name}:\n"
185
 
186
- # Add components with layout optimization
187
- optimized_components = await self.builder.optimize_layout(self.components)
188
-
189
- # Generate component code
190
- for component in optimized_components:
191
  code += f" {Component(**component).render()}\n"
192
 
193
- # Add event handlers
194
- for handler in self.event_handlers:
195
- code += f"\n {handler['trigger']}.change(fn={handler['function']}, "
196
- code += f"inputs={handler['inputs']}, outputs={handler['outputs']})\n"
197
-
198
- # Add launch configuration
199
  code += f"\n{self.app_name}.launch(share=True, debug=True)\n"
200
 
201
- # Format the code
202
- formatted_code = self.builder.format_code(code)
203
-
204
- # Run linting
205
- lint_results = self.builder.lint_code(formatted_code)
206
-
207
- return formatted_code, lint_results
208
 
209
  except Exception as e:
210
  logger.error(f"Code generation error: {str(e)}")
211
  return str(e), []
212
 
213
- async def deploy_enhanced(self):
214
- """Enhanced deployment process"""
215
- try:
216
- # Generate code
217
- code, lint_results = await self.generate_enhanced_code()
218
-
219
- # Create deployment directory
220
- deploy_dir = Path(f"deployment_{self.app_name}")
221
- deploy_dir.mkdir(exist_ok=True)
222
-
223
- # Save main application file
224
- with open(deploy_dir / "app.py", "w") as f:
225
- f.write(code)
226
-
227
- # Generate requirements.txt
228
- requirements = [
229
- "gradio>=3.50.2",
230
- "pandas",
231
- "numpy",
232
- "plotly",
233
- "pillow",
234
- "scikit-learn"
235
- ]
236
- with open(deploy_dir / "requirements.txt", "w") as f:
237
- f.write("\n".join(requirements))
238
-
239
- # Generate README.md
240
- readme = f"""# {self.app_name}
241
-
242
- Generated by Enhanced App Builder
243
-
244
- ## Features
245
- - Interactive web interface
246
- - Data visualization capabilities
247
- - Responsive design with {self.current_theme} theme
248
- - Advanced component integration
249
-
250
- ## Setup
251
- 1. Install requirements: `pip install -r requirements.txt`
252
- 2. Run the app: `python app.py`
253
- """
254
- with open(deploy_dir / "README.md", "w") as f:
255
- f.write(readme)
256
-
257
- return {
258
- "status": "success",
259
- "message": f"Deployment files generated in {deploy_dir}",
260
- "lint_results": lint_results
261
- }
262
-
263
- except Exception as e:
264
- logger.error(f"Deployment error: {str(e)}")
265
- return {
266
- "status": "error",
267
- "message": str(e)
268
- }
269
-
270
- # Create enhanced interface
271
  def create_enhanced_interface():
272
  app_process = EnhancedAppCreationProcess()
273
 
@@ -287,14 +222,13 @@ def create_enhanced_interface():
287
  with gr.Tabs():
288
  # App Configuration Tab
289
  with gr.TabItem("📱 App Configuration"):
290
- with gr.Group():
291
- app_name_input = gr.Textbox(label="App Name")
292
- template_dropdown = gr.Dropdown(
293
- choices=list(app_process.builder.TEMPLATES.keys()),
294
- label="Template"
295
- )
296
- init_app_button = gr.Button("Initialize App", variant="primary")
297
- init_status = gr.Markdown()
298
 
299
  # Component Builder Tab
300
  with gr.TabItem("🔧 Component Builder"):
@@ -308,95 +242,48 @@ def create_enhanced_interface():
308
  with gr.Column():
309
  components_display = gr.HTML()
310
 
311
- # Style Editor Tab
312
- with gr.TabItem("🎨 Style Editor"):
313
- custom_css = gr.Code(
314
- label="Custom CSS",
315
- language="css"
316
- )
317
- apply_style_button = gr.Button("Apply Style")
318
- style_status = gr.Markdown()
319
-
320
  # Code Generator Tab
321
  with gr.TabItem("💻 Code Generator"):
322
  generate_code_button = gr.Button("Generate Code")
323
  generated_code = gr.Code(language="python")
324
  lint_results = gr.Markdown()
325
 
326
- # Deployment Tab
327
- with gr.TabItem("🚀 Deployment"):
328
- with gr.Group():
329
- deploy_button = gr.Button("Deploy Application")
330
- deployment_status = gr.Markdown()
331
- with gr.Accordion("Deployment Logs", open=False):
332
- deployment_logs = gr.TextArea(label="Logs", interactive=False)
333
-
334
- # Footer
335
- gr.Markdown("---")
336
- with gr.Row():
337
- gr.Markdown("### 📊 Build Status")
338
- components_count = gr.Number(label="Components", value=0)
339
- validation_status = gr.Markdown()
340
-
341
  # Event handlers
342
- async def update_theme(theme_name):
343
- app_process.current_theme = theme_name
344
  return f"Theme updated to {theme_name}"
345
 
346
- async def init_app(name, template):
347
  try:
348
  app_process.app_name = name
349
- # Load template if selected
350
- if template:
351
- # Implementation for template loading
352
- pass
353
  app_process.save_snapshot()
354
  return f"✅ App '{name}' initialized successfully with {template} template!"
355
  except Exception as e:
356
  return f"❌ Error: {str(e)}"
357
 
358
- async def add_component(comp_type):
359
  try:
360
  result = app_process.add_component(comp_type)
361
- count = len(app_process.components)
362
- return result, count, "✅ Component added successfully"
363
  except Exception as e:
364
- return None, 0, f"❌ Error: {str(e)}"
365
 
366
  async def generate_code():
367
  try:
368
  code, lint_results = await app_process.generate_enhanced_code()
369
- return (
370
- code,
371
- "### Lint Results:\n" + "\n".join(lint_results)
372
- )
373
- except Exception as e:
374
- return str(e), "❌ Error in code generation"
375
-
376
- async def deploy():
377
- try:
378
- result = await app_process.deploy_enhanced()
379
- return (
380
- f"### Deployment Status: {result['status']}\n\n{result['message']}",
381
- "\n".join(result.get('lint_results', []))
382
- )
383
  except Exception as e:
384
- return f"❌ Deployment Error: {str(e)}", ""
385
 
386
  # Connect event handlers
387
- theme_dropdown.change(update_theme, inputs=[theme_dropdown], outputs=[style_status])
388
  init_app_button.click(init_app, inputs=[app_name_input, template_dropdown], outputs=[init_status])
389
- add_component_button.click(add_component, inputs=[component_type], outputs=[components_display, components_count, validation_status])
390
  generate_code_button.click(generate_code, outputs=[generated_code, lint_results])
391
- deploy_button.click(deploy, outputs=[deployment_status, deployment_logs])
392
 
393
  return iface
394
 
395
- # Launch the enhanced interface
396
  if __name__ == "__main__":
397
  iface = create_enhanced_interface()
398
- iface.launch(
399
- server_port=7860,
400
- share=True,
401
- debug=True
402
- )
 
7
  import time
8
  from pathlib import Path
9
  from datetime import datetime
 
 
 
10
  import logging
11
+ from typing import Dict, List, Any
 
 
12
 
13
  # Configure logging
14
  logging.basicConfig(
 
17
  )
18
  logger = logging.getLogger(__name__)
19
 
20
+ # Base Component Registry
21
+ components_registry = {
22
+ "Button": {
23
+ "properties": {"label": "Click Me", "onclick": ""},
24
+ "description": "A clickable button",
25
+ "code_snippet": 'gr.Button(value="{label}", variant="primary")',
26
+ },
27
+ "Text Input": {
28
+ "properties": {"value": "", "placeholder": "Enter text"},
29
+ "description": "A field for entering text",
30
+ "code_snippet": 'gr.Textbox(label="{placeholder}")',
31
+ },
32
+ "Image": {
33
+ "properties": {"src": "#", "alt": "Image"},
34
+ "description": "Displays an image",
35
+ "code_snippet": 'gr.Image(label="{alt}")',
36
+ },
37
+ "Dropdown": {
38
+ "properties": {"choices": ["Option 1", "Option 2"], "value": ""},
39
+ "description": "A dropdown menu for selecting options",
40
+ "code_snippet": 'gr.Dropdown(choices={choices}, label="Dropdown")',
41
+ },
42
+ }
43
+
44
+ # Define Component class first
45
+ class Component:
46
+ def __init__(self, type, properties=None, id=None):
47
+ self.id = id or random.randint(1000, 9999)
48
+ self.type = type
49
+ self.properties = properties or components_registry[type]["properties"].copy()
50
+
51
+ def to_dict(self):
52
+ return {
53
+ "id": self.id,
54
+ "type": self.type,
55
+ "properties": self.properties,
56
+ }
57
+
58
+ def render(self):
59
+ if self.type == "Dropdown":
60
+ self.properties["choices"] = (
61
+ str(self.properties["choices"])
62
+ .replace("[", "")
63
+ .replace("]", "")
64
+ .replace("'", "")
65
+ )
66
+ return components_registry[self.type]["code_snippet"].format(**self.properties)
67
+
68
+ # Define AppCreationProcess class before EnhancedAppCreationProcess
69
+ class AppCreationProcess:
70
+ def __init__(self):
71
+ self.current_step = 1
72
+ self.app_name = ""
73
+ self.components = []
74
+ self.theme = "Default"
75
+ self.custom_css = ""
76
+
77
+ def get_current_step_info(self):
78
+ steps = {
79
+ 1: "App Initialization",
80
+ 2: "Component Addition",
81
+ 3: "Property Configuration",
82
+ 4: "Code Generation",
83
+ 5: "Deployment"
84
+ }
85
+ return f"Step {self.current_step}: {steps[self.current_step]}"
86
+
87
+ def add_component(self, component_type):
88
+ new_component = Component(component_type)
89
+ self.components.append(new_component.to_dict())
90
+ return self.update_app_canvas()
91
+
92
+ def update_app_canvas(self):
93
+ components_html = "".join([
94
+ f"<div>Component ID: {component['id']}, Type: {component['type']}, "
95
+ f"Properties: {component['properties']}</div>"
96
+ for component in self.components
97
+ ])
98
+ return components_html
99
+
100
+ def generate_python_code(self):
101
+ code = f"""import gradio as gr\n\nwith gr.Blocks() as {self.app_name}:\n"""
102
+ for component in self.components:
103
+ code += " " + Component(**component).render() + "\n"
104
+ code += f"\n{self.app_name}.launch()\n"
105
+ return code
106
+
107
+ # Now define EnhancedAppBuilder
108
  class EnhancedAppBuilder:
109
  def __init__(self):
110
  self.TEMPLATES = {
 
137
  "multiple": False
138
  },
139
  "code_snippet": 'gr.File(file_types={file_types}, label="{label}")'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
  }
142
 
143
  async def validate_component(self, component: Dict) -> tuple:
 
144
  try:
145
  required_fields = ["type", "properties", "id"]
146
  if not all(field in component for field in required_fields):
147
  return False, "Missing required fields"
148
 
 
149
  if component["type"] not in {**components_registry, **self.ADVANCED_COMPONENTS}:
150
  return False, f"Invalid component type: {component['type']}"
151
 
 
153
  except Exception as e:
154
  return False, f"Validation error: {str(e)}"
155
 
156
+ # Then define EnhancedAppCreationProcess
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  class EnhancedAppCreationProcess(AppCreationProcess):
158
  def __init__(self):
159
  super().__init__()
160
  self.builder = EnhancedAppBuilder()
161
  self.history = []
 
 
162
  self.event_handlers = {}
163
  self.dependencies = []
164
+
165
  def save_snapshot(self):
 
166
  snapshot = {
167
  'timestamp': datetime.now().isoformat(),
168
  'app_name': self.app_name,
169
  'components': self.components.copy(),
170
+ 'theme': self.theme,
171
  'custom_css': self.custom_css
172
  }
173
  self.history.append(snapshot)
174
 
 
 
 
 
 
 
 
 
 
 
 
175
  async def generate_enhanced_code(self):
 
176
  try:
 
177
  code = """import gradio as gr
178
  import pandas as pd
179
  import numpy as np
 
180
  from pathlib import Path
181
  import logging
 
182
 
 
183
  logging.basicConfig(level=logging.INFO)
184
  logger = logging.getLogger(__name__)
185
  """
186
+ theme_config = self.builder.THEMES.get(self.theme, {})
 
 
187
  code += f"\ntheme = gr.themes.Default({', '.join(f'{k}={v!r}' for k, v in theme_config.items())})\n"
188
 
 
189
  if self.custom_css:
190
  code += f"\ncustom_css = '''{self.custom_css}'''\n"
191
 
 
192
  code += f"\nwith gr.Blocks(theme=theme{',' if self.custom_css else ''} css=custom_css) as {self.app_name}:\n"
193
 
194
+ for component in self.components:
 
 
 
 
195
  code += f" {Component(**component).render()}\n"
196
 
 
 
 
 
 
 
197
  code += f"\n{self.app_name}.launch(share=True, debug=True)\n"
198
 
199
+ return code, []
 
 
 
 
 
 
200
 
201
  except Exception as e:
202
  logger.error(f"Code generation error: {str(e)}")
203
  return str(e), []
204
 
205
+ # Create the interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  def create_enhanced_interface():
207
  app_process = EnhancedAppCreationProcess()
208
 
 
222
  with gr.Tabs():
223
  # App Configuration Tab
224
  with gr.TabItem("📱 App Configuration"):
225
+ app_name_input = gr.Textbox(label="App Name")
226
+ template_dropdown = gr.Dropdown(
227
+ choices=list(app_process.builder.TEMPLATES.keys()),
228
+ label="Template"
229
+ )
230
+ init_app_button = gr.Button("Initialize App", variant="primary")
231
+ init_status = gr.Markdown()
 
232
 
233
  # Component Builder Tab
234
  with gr.TabItem("🔧 Component Builder"):
 
242
  with gr.Column():
243
  components_display = gr.HTML()
244
 
 
 
 
 
 
 
 
 
 
245
  # Code Generator Tab
246
  with gr.TabItem("💻 Code Generator"):
247
  generate_code_button = gr.Button("Generate Code")
248
  generated_code = gr.Code(language="python")
249
  lint_results = gr.Markdown()
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  # Event handlers
252
+ def update_theme(theme_name):
253
+ app_process.theme = theme_name
254
  return f"Theme updated to {theme_name}"
255
 
256
+ def init_app(name, template):
257
  try:
258
  app_process.app_name = name
 
 
 
 
259
  app_process.save_snapshot()
260
  return f"✅ App '{name}' initialized successfully with {template} template!"
261
  except Exception as e:
262
  return f"❌ Error: {str(e)}"
263
 
264
+ def add_component(comp_type):
265
  try:
266
  result = app_process.add_component(comp_type)
267
+ return result, "✅ Component added successfully"
 
268
  except Exception as e:
269
+ return None, f"❌ Error: {str(e)}"
270
 
271
  async def generate_code():
272
  try:
273
  code, lint_results = await app_process.generate_enhanced_code()
274
+ return code, "Code generated successfully"
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  except Exception as e:
276
+ return str(e), f"❌ Error in code generation: {str(e)}"
277
 
278
  # Connect event handlers
279
+ theme_dropdown.change(update_theme, inputs=[theme_dropdown], outputs=[init_status])
280
  init_app_button.click(init_app, inputs=[app_name_input, template_dropdown], outputs=[init_status])
281
+ add_component_button.click(add_component, inputs=[component_type], outputs=[components_display, init_status])
282
  generate_code_button.click(generate_code, outputs=[generated_code, lint_results])
 
283
 
284
  return iface
285
 
286
+ # Launch the application
287
  if __name__ == "__main__":
288
  iface = create_enhanced_interface()
289
+ iface.launch(server_port=7860, share=True, debug=True)