codeboosterstech commited on
Commit
03ee311
·
verified ·
1 Parent(s): 63962af

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +379 -0
app.py ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Main application file for Hugging Face Space Creator
3
+ Enterprise-grade Gradio application for converting Python code to deployable Gradio apps
4
+ """
5
+
6
+ import gradio as gr
7
+ import tempfile
8
+ import os
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ # Add utils and components to path
13
+ sys.path.append(str(Path(__file__).parent))
14
+
15
+ from utils.converter import convert_code
16
+ from utils.deployer import deploy_to_space
17
+ from utils.file_handler import (
18
+ create_zip_archive,
19
+ read_file_content,
20
+ parse_notebook,
21
+ save_individual_file
22
+ )
23
+ from utils.validator import validate_inputs
24
+
25
+ from components.header import create_header
26
+ from components.sidebar import create_sidebar
27
+ from components.api_guide import create_api_guide
28
+ from components.file_downloader import create_file_download_section
29
+
30
+ # Constants
31
+ MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
32
+ SUPPORTED_EXTENSIONS = ['.py', '.ipynb', '.txt']
33
+
34
+
35
+ class SpaceCreatorApp:
36
+ """Main application class for Hugging Face Space Creator"""
37
+
38
+ def __init__(self):
39
+ self.temp_files = []
40
+ self.current_step = 1
41
+ self.generated_files = {}
42
+
43
+ def cleanup(self):
44
+ """Clean up temporary files"""
45
+ for file_path in self.temp_files:
46
+ try:
47
+ if os.path.exists(file_path):
48
+ os.remove(file_path)
49
+ except:
50
+ pass
51
+ self.temp_files = []
52
+
53
+ def process_step1(self, input_text, input_file, groq_api_key):
54
+ """Step 1: Convert code to Gradio app"""
55
+ try:
56
+ # Validate inputs
57
+ validation_errors = validate_inputs(groq_api_key, None, None, "Convert Only")
58
+ if validation_errors:
59
+ return None, None, None, None, self._format_errors(validation_errors), 1
60
+
61
+ # Get source code
62
+ code_content = self._extract_code(input_text, input_file)
63
+ if not code_content.strip():
64
+ return None, None, None, None, "Please provide Python code to convert.", 1
65
+
66
+ # Convert code
67
+ conversion_result = convert_code(code_content, groq_api_key)
68
+
69
+ # Store generated files
70
+ self.generated_files = {
71
+ "app.py": conversion_result["app_py"],
72
+ "requirements.txt": conversion_result["requirements_txt"],
73
+ "README.md": conversion_result["readme_md"]
74
+ }
75
+
76
+ # Create individual files for download
77
+ file_paths = {}
78
+ for filename, content in self.generated_files.items():
79
+ file_path = save_individual_file(filename, content)
80
+ self.temp_files.append(file_path)
81
+ file_paths[filename] = file_path
82
+
83
+ status = self._create_status_message("success", "Code conversion successful!")
84
+ return (file_paths["app.py"], file_paths["requirements.txt"],
85
+ file_paths["README.md"], None, status, 2)
86
+
87
+ except Exception as e:
88
+ error_msg = self._create_status_message("error", f"Conversion failed: {str(e)}")
89
+ return None, None, None, None, error_msg, 1
90
+
91
+ def process_step2(self, hf_token, space_name, deploy_mode):
92
+ """Step 2: Deploy to Hugging Face"""
93
+ try:
94
+ if deploy_mode != "Deploy to Hugging Face Space":
95
+ status = self._create_status_message("info", "Skipping deployment as requested.")
96
+ return None, status, 2
97
+
98
+ # Validate deployment inputs
99
+ validation_errors = validate_inputs(None, hf_token, space_name, "Deploy")
100
+ if validation_errors:
101
+ return None, self._format_errors(validation_errors), 2
102
+
103
+ # Deploy to Hugging Face
104
+ deploy_url = deploy_to_space(hf_token, space_name, self.generated_files)
105
+
106
+ # Create zip archive of all files
107
+ zip_bytes = create_zip_archive(self.generated_files)
108
+ zip_path = save_individual_file("gradio_app_full_package.zip", zip_bytes, binary=True)
109
+ self.temp_files.append(zip_path)
110
+
111
+ status = self._create_status_message("success",
112
+ f"Deployment successful! Space URL: {deploy_url}")
113
+ return zip_path, status, 3
114
+
115
+ except Exception as e:
116
+ error_msg = self._create_status_message("error", f"Deployment failed: {str(e)}")
117
+ return None, error_msg, 2
118
+
119
+ def _extract_code(self, input_text, input_file):
120
+ """Extract code from text or file"""
121
+ code_content = ""
122
+ if input_file is not None:
123
+ file_content = read_file_content(input_file)
124
+ if input_file.name.endswith('.ipynb') if hasattr(input_file, 'name') else False:
125
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.ipynb', delete=False, encoding='utf-8') as tmp:
126
+ tmp.write(file_content)
127
+ tmp_path = tmp.name
128
+ try:
129
+ code_content = parse_notebook(tmp_path)
130
+ finally:
131
+ os.unlink(tmp_path)
132
+ else:
133
+ code_content = file_content
134
+ elif input_text.strip():
135
+ code_content = input_text
136
+ return code_content
137
+
138
+ def _format_errors(self, errors):
139
+ """Format validation errors"""
140
+ error_html = '<div class="error-message"><h4>Validation Errors:</h4><ul>'
141
+ for error in errors:
142
+ error_html += f'<li>{error}</li>'
143
+ error_html += '</ul></div>'
144
+ return error_html
145
+
146
+ def _create_status_message(self, msg_type, message):
147
+ """Create formatted status message"""
148
+ icons = {
149
+ "success": "check_circle",
150
+ "error": "error",
151
+ "warning": "warning",
152
+ "info": "info"
153
+ }
154
+ colors = {
155
+ "success": "#10B981",
156
+ "error": "#EF4444",
157
+ "warning": "#F59E0B",
158
+ "info": "#3B82F6"
159
+ }
160
+
161
+ return f'''
162
+ <div class="status-message {msg_type}">
163
+ <span class="material-icons" style="color: {colors[msg_type]}; vertical-align: middle;">
164
+ {icons[msg_type]}
165
+ </span>
166
+ <span style="vertical-align: middle; margin-left: 8px;">{message}</span>
167
+ </div>
168
+ '''
169
+
170
+
171
+ def create_app():
172
+ """Create the Gradio application interface"""
173
+ app = SpaceCreatorApp()
174
+
175
+ with gr.Blocks(
176
+ title="Hugging Face Space Creator",
177
+ theme=gr.themes.Soft(primary_hue="yellow"),
178
+ css="static/css/style.css"
179
+ ) as demo:
180
+
181
+ # Custom CSS
182
+ gr.HTML('<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">')
183
+
184
+ # Header
185
+ create_header()
186
+
187
+ with gr.Row():
188
+ # Sidebar with steps
189
+ with gr.Column(scale=1, min_width=300):
190
+ current_step = gr.State(1)
191
+ sidebar = create_sidebar(current_step)
192
+
193
+ # Main content area
194
+ with gr.Column(scale=3):
195
+ # Step 1: Code Input and Conversion
196
+ with gr.Group(visible=True) as step1_group:
197
+ gr.Markdown("### Step 1: Provide Your Code")
198
+
199
+ with gr.Tabs():
200
+ with gr.Tab("Upload File", id="upload_tab"):
201
+ file_input = gr.File(
202
+ label="Upload Python or Jupyter Notebook",
203
+ file_types=SUPPORTED_EXTENSIONS,
204
+ type="filepath"
205
+ )
206
+
207
+ with gr.Tab("Paste Code", id="paste_tab"):
208
+ text_input = gr.Textbox(
209
+ label="Python Code",
210
+ lines=20,
211
+ placeholder="# Paste your Python code here...\n\n# Example:\ndef add(a, b):\n return a + b\n\ndef greet(name):\n return f\"Hello, {name}!\"",
212
+ elem_id="code_editor"
213
+ )
214
+
215
+ gr.Markdown("### Step 1b: API Configuration")
216
+ with gr.Row():
217
+ with gr.Column():
218
+ groq_api_key = gr.Textbox(
219
+ label="Groq API Key",
220
+ type="password",
221
+ placeholder="Enter your Groq API key starting with gsk_",
222
+ info="Required for AI-powered conversion"
223
+ )
224
+
225
+ # API Key Creation Guide
226
+ api_guide = create_api_guide()
227
+
228
+ with gr.Row():
229
+ convert_btn = gr.Button(
230
+ "Convert Code",
231
+ variant="primary",
232
+ size="lg",
233
+ elem_id="convert_btn"
234
+ )
235
+
236
+ # Step 2: Generated Files
237
+ with gr.Group(visible=False) as step2_group:
238
+ gr.Markdown("### Step 2: Generated Files")
239
+
240
+ with gr.Row():
241
+ with gr.Column():
242
+ app_py_download = gr.File(
243
+ label="app.py",
244
+ file_types=[".py"],
245
+ interactive=False
246
+ )
247
+
248
+ with gr.Column():
249
+ requirements_download = gr.File(
250
+ label="requirements.txt",
251
+ file_types=[".txt"],
252
+ interactive=False
253
+ )
254
+
255
+ with gr.Column():
256
+ readme_download = gr.File(
257
+ label="README.md",
258
+ file_types=[".md"],
259
+ interactive=False
260
+ )
261
+
262
+ gr.Markdown("### Step 2b: Deployment Options")
263
+
264
+ with gr.Row():
265
+ with gr.Column():
266
+ hf_token = gr.Textbox(
267
+ label="Hugging Face Token",
268
+ type="password",
269
+ placeholder="Enter your Hugging Face token starting with hf_",
270
+ info="Required for deployment"
271
+ )
272
+
273
+ with gr.Column():
274
+ space_name = gr.Textbox(
275
+ label="Space Name",
276
+ placeholder="my-gradio-application",
277
+ info="Lowercase letters, numbers, and hyphens only"
278
+ )
279
+
280
+ deploy_mode = gr.Radio(
281
+ choices=["Download Only", "Deploy to Hugging Face Space"],
282
+ label="Select Action",
283
+ value="Download Only",
284
+ elem_id="deploy_mode"
285
+ )
286
+
287
+ with gr.Row():
288
+ back_btn_step2 = gr.Button("Back", variant="secondary")
289
+ deploy_btn = gr.Button("Proceed to Deployment", variant="primary")
290
+
291
+ # Step 3: Deployment Results
292
+ with gr.Group(visible=False) as step3_group:
293
+ gr.Markdown("### Step 3: Deployment Complete")
294
+
295
+ with gr.Row():
296
+ with gr.Column():
297
+ full_package_download = gr.File(
298
+ label="Complete Application Package",
299
+ file_types=[".zip"],
300
+ interactive=False
301
+ )
302
+
303
+ deployment_status = gr.Markdown()
304
+
305
+ with gr.Row():
306
+ back_btn_step3 = gr.Button("Start New Project", variant="secondary")
307
+ finish_btn = gr.Button("Finish", variant="primary")
308
+
309
+ # Status output
310
+ status_output = gr.HTML(
311
+ value='<div class="status-container"></div>',
312
+ elem_id="status_output"
313
+ )
314
+
315
+ # Event handlers
316
+ convert_btn.click(
317
+ fn=app.process_step1,
318
+ inputs=[text_input, file_input, groq_api_key],
319
+ outputs=[
320
+ app_py_download,
321
+ requirements_download,
322
+ readme_download,
323
+ full_package_download,
324
+ status_output,
325
+ current_step
326
+ ]
327
+ ).then(
328
+ fn=lambda step: (gr.update(visible=step==1), gr.update(visible=step==2), gr.update(visible=step==3)),
329
+ inputs=[current_step],
330
+ outputs=[step1_group, step2_group, step3_group]
331
+ )
332
+
333
+ deploy_btn.click(
334
+ fn=app.process_step2,
335
+ inputs=[hf_token, space_name, deploy_mode],
336
+ outputs=[full_package_download, status_output, current_step]
337
+ ).then(
338
+ fn=lambda step: (gr.update(visible=step==1), gr.update(visible=step==2), gr.update(visible=step==3)),
339
+ inputs=[current_step],
340
+ outputs=[step1_group, step2_group, step3_group]
341
+ )
342
+
343
+ back_btn_step2.click(
344
+ fn=lambda: (1, gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)),
345
+ outputs=[current_step, step1_group, step2_group, step3_group]
346
+ )
347
+
348
+ back_btn_step3.click(
349
+ fn=lambda: (1, gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)),
350
+ outputs=[current_step, step1_group, step2_group, step3_group]
351
+ ).then(
352
+ fn=app.cleanup,
353
+ inputs=None,
354
+ outputs=None
355
+ )
356
+
357
+ finish_btn.click(
358
+ fn=app.cleanup,
359
+ inputs=None,
360
+ outputs=None
361
+ )
362
+
363
+ return demo
364
+
365
+
366
+ if __name__ == "__main__":
367
+ print("Starting Hugging Face Space Creator...")
368
+ print("=" * 50)
369
+ print("Enterprise-grade Python to Gradio App Converter")
370
+ print("=" * 50)
371
+
372
+ app = create_app()
373
+ app.launch(
374
+ server_name="0.0.0.0",
375
+ server_port=7860,
376
+ share=False,
377
+ debug=True,
378
+ favicon_path=None
379
+ )