Anupam007 commited on
Commit
af477d2
·
verified ·
1 Parent(s): ce08307

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +310 -0
app.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import google.generativeai as genai
3
+ import zipfile
4
+ import os
5
+ import re
6
+ import toml # Import the toml library
7
+
8
+ # Load secrets from secrets.toml
9
+ try:
10
+ secrets = toml.load("secrets.toml")
11
+ GEMINI_API_KEY = secrets["GEMINI_API_KEY"]
12
+ except FileNotFoundError:
13
+ print("Error: secrets.toml not found. Make sure it exists in the same directory.")
14
+ GEMINI_API_KEY = None # Or some default value
15
+ except KeyError:
16
+ print("Error: GEMINI_API_KEY not found in secrets.toml.")
17
+ GEMINI_API_KEY = None
18
+
19
+ # Step 3: Configure Gemini API
20
+ if GEMINI_API_KEY:
21
+ genai.configure(api_key=GEMINI_API_KEY)
22
+ model = genai.GenerativeModel("gemini-1.5-pro")
23
+ else:
24
+ print("Gemini API key not found. The app will not function correctly.")
25
+ model = None
26
+
27
+ # Step 4: Define enhanced prompts for Firebase integration
28
+ FIREBASE_SETUP_PROMPT = """
29
+ Add detailed Firebase setup instructions including:
30
+ 1. How to create a Firebase project if not already done
31
+ 2. How to add the Firebase SDK to the project
32
+ 3. Proper configuration with environment variables or config files
33
+ 4. Security best practices
34
+ """
35
+
36
+ FIREBASE_AUTH_PROMPT = """
37
+ Include complete Firebase Authentication implementation with:
38
+ 1. User sign-up functionality
39
+ 2. Login functionality
40
+ 3. Password reset capabilities
41
+ 4. Session management
42
+ 5. Protected routes
43
+ """
44
+
45
+ FIREBASE_DATABASE_PROMPT = """
46
+ Include Firebase Realtime Database or Firestore implementation with:
47
+ 1. Data structure design
48
+ 2. CRUD operations
49
+ 3. Real-time listeners
50
+ 4. Security rules
51
+ """
52
+
53
+ FIREBASE_HOSTING_PROMPT = """
54
+ Include Firebase Hosting implementation instructions:
55
+ 1. Project structure for hosting
56
+ 2. Configuration files
57
+ 3. Deployment commands
58
+ 4. Custom domain setup (if needed)
59
+ """
60
+
61
+ # Step 5: Define the Web Development Agent function
62
+ def web_dev_agent(prompt, task_type, use_firebase, include_auth, include_database, include_hosting):
63
+ try:
64
+ if model is None:
65
+ return "Error: Gemini API key not configured.", None, "<html><body><p>Gemini API key not configured. Check the logs.</p></body></html>"
66
+
67
+ # Base prompt
68
+ full_prompt = f"You are an expert web development agent. Generate detailed, production-ready {task_type} code for the following task: {prompt}.\n\n"
69
+
70
+ # Add Firebase-specific instructions if requested
71
+ if use_firebase:
72
+ full_prompt += f"{FIREBASE_SETUP_PROMPT}\n\n"
73
+
74
+ if include_auth:
75
+ full_prompt += f"{FIREBASE_AUTH_PROMPT}\n\n"
76
+
77
+ if include_database:
78
+ full_prompt += f"{FIREBASE_DATABASE_PROMPT}\n\n"
79
+
80
+ if include_hosting:
81
+ full_prompt += f"{FIREBASE_HOSTING_PROMPT}\n\n"
82
+
83
+ # Add specific instructions based on task type
84
+ if task_type.lower() == "frontend":
85
+ full_prompt += "Focus on responsive design, clean UI, and modern frameworks like React, Vue, or Angular as appropriate. Include HTML, CSS, and JavaScript.\n\n"
86
+ else:
87
+ full_prompt += "Focus on secure, scalable backend architecture. Include proper error handling, logging, and API documentation.\n\n"
88
+
89
+ # Add final instruction for code quality
90
+ full_prompt += "Provide complete, well-commented code with clear instructions on how to implement it. Include package.json or similar configuration files where appropriate."
91
+
92
+ # Generate content using Gemini API
93
+ response = model.generate_content(full_prompt)
94
+ code = response.text
95
+
96
+ # Extract and organize code files from the response
97
+ files = extract_code_files(code, task_type.lower())
98
+
99
+ # Create output directory
100
+ os.makedirs("web_output", exist_ok=True)
101
+
102
+ # Create individual files
103
+ for filename, content in files.items():
104
+ file_path = os.path.join("web_output", filename)
105
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
106
+ with open(file_path, "w") as f:
107
+ f.write(content)
108
+
109
+ # Create a README file
110
+ readme_content = f"# Web Development Project\n\n## Description\n{prompt}\n\n## Task Type\n{task_type}\n\n"
111
+ if use_firebase:
112
+ readme_content += "## Firebase Features\n"
113
+ if include_auth:
114
+ readme_content += "- Authentication\n"
115
+ if include_database:
116
+ readme_content += "- Database\n"
117
+ if include_hosting:
118
+ readme_content += "- Hosting\n"
119
+
120
+ with open(os.path.join("web_output", "README.md"), "w") as f:
121
+ f.write(readme_content)
122
+
123
+ # Create a zip file
124
+ zip_path = "web_output/code.zip"
125
+ with zipfile.ZipFile(zip_path, 'w') as zipf:
126
+ for root, _, files in os.walk("web_output"):
127
+ for file in files:
128
+ if file != "code.zip":
129
+ file_path = os.path.join(root, file)
130
+ arcname = os.path.relpath(file_path, "web_output")
131
+ zipf.write(file_path, arcname=arcname)
132
+
133
+ # Create preview HTML for frontend tasks
134
+ if task_type.lower() == "frontend":
135
+ # Try to find an index.html or main HTML file
136
+ html_content = files.get("index.html", "")
137
+ if not html_content:
138
+ for filename, content in files.items():
139
+ if filename.endswith(".html"):
140
+ html_content = content
141
+ break
142
+
143
+ # If no HTML file found, create a simple preview of the code
144
+ if not html_content:
145
+ html_content = f"<html><body><h2>Code Preview</h2><pre>{code}</pre></body></html>"
146
+
147
+ preview_html = html_content
148
+ else:
149
+ # For backend, show a formatted version of the code
150
+ preview_html = f"<html><body><h2>Backend Code Preview</h2><pre>{code}</pre></body></html>"
151
+
152
+ # Return the full code, zip path, and preview
153
+ return code, zip_path, preview_html
154
+
155
+ except Exception as e:
156
+ return f"Error: {str(e)}", None, f"<html><body><p>Error occurred: {str(e)}</p></body></html>"
157
+
158
+ # Helper function to extract code files from the response
159
+ def extract_code_files(code_text, task_type):
160
+ files = {}
161
+
162
+ # Try to extract code blocks with filename specifications
163
+ file_pattern = r"```[\w\s]*\n?(.+?)\n```"
164
+ filename_pattern = r"[`\s]*([\w\-\.\/]+\.\w+)[`\s]*[:]*"
165
+
166
+ # Look for filename specifications followed by code blocks
167
+ filename_matches = re.finditer(filename_pattern, code_text, re.MULTILINE)
168
+ for match in filename_matches:
169
+ filename = match.group(1)
170
+ start_pos = match.end()
171
+ # Look for the next code block after the filename
172
+ code_block_match = re.search(r"```[\w\s]*\n(.*?)```", code_text[start_pos:], re.DOTALL)
173
+ if code_block_match:
174
+ content = code_block_match.group(1).strip()
175
+ files[filename] = content
176
+
177
+ # If no files were extracted using the above method, try another approach
178
+ if not files:
179
+ # Extract all code blocks and try to infer filenames
180
+ code_blocks = re.finditer(r"```([\w\s]*)\n(.*?)```", code_text, re.DOTALL)
181
+
182
+ file_counter = {
183
+ "html": 0,
184
+ "css": 0,
185
+ "js": 0,
186
+ "jsx": 0,
187
+ "tsx": 0,
188
+ "py": 0,
189
+ "json": 0,
190
+ }
191
+
192
+ for i, match in enumerate(code_blocks):
193
+ lang = match.group(1).strip().lower()
194
+ content = match.group(2).strip()
195
+
196
+ # Try to infer filename from language or context
197
+ if lang == "html":
198
+ filename = "index.html" if file_counter["html"] == 0 else f"page{file_counter['html']}.html"
199
+ file_counter["html"] += 1
200
+ elif lang == "css":
201
+ filename = "styles.css" if file_counter["css"] == 0 else f"styles{file_counter['css']}.css"
202
+ file_counter["css"] += 1
203
+ elif lang == "javascript" or lang == "js":
204
+ filename = "script.js" if file_counter["js"] == 0 else f"script{file_counter['js']}.js"
205
+ file_counter["js"] += 1
206
+ elif lang == "jsx":
207
+ filename = "App.jsx" if file_counter["jsx"] == 0 else f"Component{file_counter['jsx']}.jsx"
208
+ file_counter["jsx"] += 1
209
+ elif lang == "tsx":
210
+ filename = "App.tsx" if file_counter["tsx"] == 0 else f"Component{file_counter['tsx']}.tsx"
211
+ file_counter["tsx"] += 1
212
+ elif lang == "python" or lang == "py":
213
+ filename = "app.py" if file_counter["py"] == 0 else f"module{file_counter['py']}.py"
214
+ file_counter["py"] += 1
215
+ elif lang == "json":
216
+ filename = "package.json" if file_counter["json"] == 0 else f"config{file_counter['json']}.json"
217
+ file_counter["json"] += 1
218
+ else:
219
+ # If language can't be determined, use a generic filename
220
+ filename = f"file{i}.txt"
221
+
222
+ files[filename] = content
223
+
224
+ # If we still don't have any files, just create a single file with the entire response
225
+ if not files:
226
+ if task_type == "frontend":
227
+ files["index.html"] = code_text
228
+ else:
229
+ files["app.js"] = code_text
230
+
231
+ return files
232
+
233
+ # Step 6: Create the Gradio UI
234
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
235
+ gr.Markdown("# Gemini 2.0 Web Development Agent with Firebase Integration")
236
+
237
+ with gr.Row():
238
+ with gr.Column(scale=2):
239
+ prompt = gr.Textbox(
240
+ lines=5,
241
+ placeholder="Describe your web development task in detail. Example: 'Create a responsive blog homepage with a navigation bar, featured posts section, and footer'",
242
+ label="Describe your frontend/backend task"
243
+ )
244
+
245
+ with gr.Column(scale=1):
246
+ task_type = gr.Radio(
247
+ ["Frontend", "Backend", "Full-Stack"],
248
+ value="Frontend",
249
+ label="Task Type"
250
+ )
251
+
252
+ use_firebase = gr.Checkbox(
253
+ label="Include Firebase Integration",
254
+ value=False
255
+ )
256
+
257
+ with gr.Group(visible=False) as firebase_options:
258
+ include_auth = gr.Checkbox(label="Authentication (Sign up/Login)", value=True)
259
+ include_database = gr.Checkbox(label="Database (Realtime or Firestore)", value=True)
260
+ include_hosting = gr.Checkbox(label="Hosting", value=True)
261
+
262
+ submit_btn = gr.Button("Generate Code", variant="primary")
263
+
264
+ # Make Firebase options visible only when Firebase integration is checked
265
+ use_firebase.change(
266
+ fn=lambda x: gr.Group(visible=x),
267
+ inputs=[use_firebase],
268
+ outputs=[firebase_options]
269
+ )
270
+
271
+ with gr.Tabs():
272
+ with gr.TabItem("Code"):
273
+ output_code = gr.Code(language="html", label="Generated Code")
274
+
275
+ with gr.TabItem("Preview"):
276
+ preview = gr.HTML(label="Preview (for Frontend only)")
277
+
278
+ with gr.TabItem("Download"):
279
+ gr.Markdown("### Download your code")
280
+ download_btn = gr.File(label="Download Code (.zip)")
281
+
282
+ # Connect the function to the button
283
+ submit_btn.click(
284
+ fn=web_dev_agent,
285
+ inputs=[prompt, task_type, use_firebase, include_auth, include_database, include_hosting],
286
+ outputs=[output_code, download_btn, preview]
287
+ )
288
+
289
+ gr.Markdown("""
290
+ ## How to Use
291
+
292
+ 1. Enter a detailed description of your web development task
293
+ 2. Select the task type (Frontend, Backend, or Full-Stack)
294
+ 3. Check "Include Firebase Integration" if you want Firebase features
295
+ 4. Select which Firebase features you want to include
296
+ 5. Click "Generate Code"
297
+ 6. View the generated code in the "Code" tab
298
+ 7. See a preview in the "Preview" tab (for Frontend code)
299
+ 8. Download the code as a zip file from the "Download" tab
300
+
301
+ ## Firebase Setup
302
+
303
+ After downloading the code:
304
+ 1. Create a Firebase project at [Firebase Console](https://console.firebase.google.com/)
305
+ 2. Follow the setup instructions in the generated code
306
+ 3. Deploy your application using Firebase CLI
307
+ """)
308
+
309
+ # Launch the Gradio app - DO NOT INCLUDE THIS LINE FOR HUGGING FACE
310
+ #demo.launch(debug=True)