wuhp commited on
Commit
3d43200
·
verified ·
1 Parent(s): e87ed80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -83
app.py CHANGED
@@ -78,8 +78,7 @@ def fetch_logs(repo_id: str, level: str) -> str:
78
 
79
  def check_iframe(url: str, timeout: int = 5) -> bool:
80
  try:
81
- r = requests.get(url, timeout=timeout)
82
- return r.status_code == 200
83
  except:
84
  return False
85
 
@@ -102,9 +101,8 @@ def handle_user_message(
102
  system_msg = {
103
  "role":"system",
104
  "content":(
105
- f"You are an AI assistant that scaffolds a complete HuggingFace Space using the "
106
- f"{sdk_choice} SDK. Generate working code, handle errors, and ensure the deployed "
107
- "iframe loads successfully."
108
  )
109
  }
110
  chat = [system_msg] + history
@@ -127,7 +125,6 @@ def handle_user_message(
127
  max_output_tokens=max_output_tokens,
128
  )
129
 
130
- # generate code
131
  resp = client.models.generate_content(
132
  model="gemini-2.5-flash-preview-04-17",
133
  contents=[m["content"] for m in chat],
@@ -136,19 +133,15 @@ def handle_user_message(
136
  code = extract_code(resp.text)
137
  chat.append({"role":"assistant","content":code})
138
 
139
- # local syntax check
140
  try:
141
  compile(code, code_fn, "exec")
142
  except SyntaxError as e:
143
- chat.append({
144
- "role":"user",
145
- "content": f"SyntaxError caught locally: {e}. Please fix the code."
146
- })
147
- time.sleep(backoff)
148
- backoff = min(backoff * 2, 30)
149
  continue
150
 
151
- # write files
152
  sdk_version = get_sdk_version(sdk_choice)
153
  files = {
154
  code_fn: code,
@@ -169,89 +162,75 @@ See https://huggingface.co/docs/hub/spaces-config-reference
169
  with open(fn, "w") as f:
170
  f.write(content)
171
 
172
- # push to HuggingFace
173
  create_repo(repo_id=repo_id, token=oauth_token.token,
174
  exist_ok=True, repo_type="space", space_sdk=sdk_choice)
175
  for fn in files:
176
- upload_file(fn, fn, repo_id=repo_id,
177
- token=oauth_token.token, repo_type="space")
 
 
 
 
 
178
 
179
- # fetch logs
180
  build_logs = fetch_logs(repo_id, "build")
181
  run_logs = fetch_logs(repo_id, "run")
182
  errors = classify_errors(build_logs + "\n" + run_logs)
183
 
184
- # success?
185
  if "ERROR" not in build_logs.upper() and \
186
  "ERROR" not in run_logs.upper() and \
187
  check_iframe(iframe_url):
188
  break
189
 
190
- # ask for fixes
191
  chat.append({
192
  "role":"user",
193
  "content":(
194
- f"Attempt {attempt} encountered {errors} errors.\n"
195
  f"Build logs:\n{build_logs}\n\n"
196
  f"Run logs:\n{run_logs}\n\n"
197
- f"Please fix the code and ensure the iframe at {iframe_url} returns HTTP 200."
198
  )
199
  })
200
- time.sleep(backoff)
201
- backoff = min(backoff * 2, 30)
202
 
203
  messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
204
  iframe_html = (
205
  f'<iframe src="{iframe_url}" width="100%" height="500px"></iframe>'
206
- + ("" if check_iframe(iframe_url) else
207
  "<p style='color:red;'>⚠️ iframe not responding.</p>")
208
  )
209
  return messages, build_logs, run_logs, iframe_html
210
 
211
- # — BUILD THE UI (Improved)
212
-
213
- custom_css = """
214
- .gradio-container { max-width: 1200px; margin: auto; }
215
- .log-box { font-family: monospace; white-space: pre; }
216
- """
217
-
218
- with gr.Blocks(title="HF Space Auto‑Builder", css=custom_css) as demo:
219
- with gr.Row():
220
- with gr.Column(scale=1, min_width=250):
221
- login_btn = gr.LoginButton(variant="huggingface", size="sm")
222
- status_md = gr.Markdown("*Not logged in.*")
223
- models_md = gr.Markdown()
224
- sdk_choice = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK template")
225
- api_key = gr.Textbox(label="Gemini API Key", type="password")
226
- grounding = gr.Checkbox(label="Enable grounding", value=False)
227
- temp = gr.Slider(0,1,value=0.2,label="LLM temperature")
228
- max_tokens = gr.Slider(256,4096,value=1024,step=256,label="Max tokens")
229
- clear_btn = gr.Button("Clear Chat", variant="secondary")
230
-
231
- with gr.Column(scale=3):
232
- gr.Markdown("## 🐢 Wuhp Auto‑Builder\nSign in, enter your prompt, and watch your Space live.")
233
- chatbot = gr.Chatbot(elem_id="chatbot", type="messages")
234
- user_in = gr.Textbox(placeholder="Type your prompt and hit Enter…", label="Prompt", lines=1)
235
- send_btn = gr.Button("Send", variant="primary")
236
-
237
- with gr.Tabs():
238
- with gr.TabItem("Chat"):
239
- pass
240
- with gr.TabItem("Logs"):
241
- with gr.Accordion("🔨 Build Logs", open=True):
242
- build_box = gr.Textbox(lines=8, interactive=False, elem_classes="log-box")
243
- with gr.Accordion("🚀 Run Logs", open=False):
244
- run_box = gr.Textbox(lines=8, interactive=False, elem_classes="log-box")
245
- with gr.TabItem("Preview"):
246
- preview = gr.HTML("<p>No Space yet.</p>")
247
-
248
- # load auth status
249
- demo.load(show_profile, inputs=None, outputs=status_md)
250
  demo.load(list_private_models, inputs=None, outputs=models_md)
251
- login_btn.click(show_profile, inputs=None, outputs=status_md)
252
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
253
 
254
- # send / submit callbacks (Gradio auto-injects profile & oauth_token)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  send_btn.click(
256
  fn=handle_user_message,
257
  inputs=[chatbot, sdk_choice, api_key, grounding, temp, max_tokens],
@@ -263,22 +242,11 @@ with gr.Blocks(title="HF Space Auto‑Builder", css=custom_css) as demo:
263
  outputs=[chatbot, build_box, run_box, preview]
264
  )
265
 
266
- # clear chat
267
- def _clear_chat():
268
- return [], "", "", "<p>No Space yet.</p>"
269
- clear_btn.click(
270
- fn=_clear_chat,
271
- inputs=None,
272
- outputs=[chatbot, build_box, run_box, preview]
273
- )
274
-
275
- # refresh logs (auto-injected profile & oauth_token)
276
- refresh_btn = gr.Button("Refresh Logs", variant="secondary", size="sm")
277
- refresh_btn.click(
278
- fn=lambda profile,token: (fetch_logs(f"{profile.username}/{profile.username}-auto-space","build"),
279
- fetch_logs(f"{profile.username}/{profile.username}-auto-space","run")),
280
- inputs=None,
281
- outputs=[build_box, run_box]
282
- )
283
 
284
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
78
 
79
  def check_iframe(url: str, timeout: int = 5) -> bool:
80
  try:
81
+ return requests.get(url, timeout=timeout).status_code == 200
 
82
  except:
83
  return False
84
 
 
101
  system_msg = {
102
  "role":"system",
103
  "content":(
104
+ f"You are an AI assistant scaffolding a complete HuggingFace Space using "
105
+ f"{sdk_choice}. Generate working code, handle errors, and verify the iframe loads."
 
106
  )
107
  }
108
  chat = [system_msg] + history
 
125
  max_output_tokens=max_output_tokens,
126
  )
127
 
 
128
  resp = client.models.generate_content(
129
  model="gemini-2.5-flash-preview-04-17",
130
  contents=[m["content"] for m in chat],
 
133
  code = extract_code(resp.text)
134
  chat.append({"role":"assistant","content":code})
135
 
136
+ # Syntax check
137
  try:
138
  compile(code, code_fn, "exec")
139
  except SyntaxError as e:
140
+ chat.append({"role":"user","content":f"SyntaxError: {e}. Please fix."})
141
+ time.sleep(backoff); backoff = min(backoff*2, 30)
 
 
 
 
142
  continue
143
 
144
+ # Write files
145
  sdk_version = get_sdk_version(sdk_choice)
146
  files = {
147
  code_fn: code,
 
162
  with open(fn, "w") as f:
163
  f.write(content)
164
 
165
+ # Push to HF
166
  create_repo(repo_id=repo_id, token=oauth_token.token,
167
  exist_ok=True, repo_type="space", space_sdk=sdk_choice)
168
  for fn in files:
169
+ upload_file(
170
+ path_or_fileobj=fn,
171
+ path_in_repo=fn,
172
+ repo_id=repo_id,
173
+ token=oauth_token.token,
174
+ repo_type="space"
175
+ )
176
 
 
177
  build_logs = fetch_logs(repo_id, "build")
178
  run_logs = fetch_logs(repo_id, "run")
179
  errors = classify_errors(build_logs + "\n" + run_logs)
180
 
 
181
  if "ERROR" not in build_logs.upper() and \
182
  "ERROR" not in run_logs.upper() and \
183
  check_iframe(iframe_url):
184
  break
185
 
 
186
  chat.append({
187
  "role":"user",
188
  "content":(
189
+ f"Attempt {attempt} had {errors} errors.\n"
190
  f"Build logs:\n{build_logs}\n\n"
191
  f"Run logs:\n{run_logs}\n\n"
192
+ f"Please fix and ensure iframe at {iframe_url} returns HTTP 200."
193
  )
194
  })
195
+ time.sleep(backoff); backoff = min(backoff*2, 30)
 
196
 
197
  messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
198
  iframe_html = (
199
  f'<iframe src="{iframe_url}" width="100%" height="500px"></iframe>'
200
+ + ("" if check_iframe(iframe_url) else
201
  "<p style='color:red;'>⚠️ iframe not responding.</p>")
202
  )
203
  return messages, build_logs, run_logs, iframe_html
204
 
205
+ # — SIMPLE UI —
206
+
207
+ with gr.Blocks(title="HF Space Auto‑Builder") as demo:
208
+ gr.Markdown("## 🐢 HF Space Auto‑Builder\n1) Sign in  2) Enter prompt  3) Watch code, logs & preview")
209
+
210
+ # Auth
211
+ login_btn = gr.LoginButton(variant="huggingface", size="lg")
212
+ status_md = gr.Markdown("*Not logged in.*")
213
+ models_md = gr.Markdown()
214
+ demo.load(show_profile, inputs=None, outputs=status_md)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  demo.load(list_private_models, inputs=None, outputs=models_md)
216
+ login_btn.click(show_profile, inputs=None, outputs=status_md)
217
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
218
 
219
+ # Controls
220
+ sdk_choice = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK")
221
+ api_key = gr.Textbox(label="Gemini API Key", type="password")
222
+ grounding = gr.Checkbox(label="Enable grounding", value=False)
223
+ temp = gr.Slider(0,1,value=0.2, label="Temperature")
224
+ max_tokens = gr.Slider(256,4096,value=1024,step=256, label="Max tokens")
225
+
226
+ # Chat + outputs
227
+ chatbot = gr.Chatbot(type="messages")
228
+ user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt", lines=1)
229
+ send_btn = gr.Button("Send")
230
+ build_box = gr.Textbox(label="Build logs", lines=5, interactive=False)
231
+ run_box = gr.Textbox(label="Run logs", lines=5, interactive=False)
232
+ preview = gr.HTML("<p>No Space yet.</p>")
233
+
234
  send_btn.click(
235
  fn=handle_user_message,
236
  inputs=[chatbot, sdk_choice, api_key, grounding, temp, max_tokens],
 
242
  outputs=[chatbot, build_box, run_box, preview]
243
  )
244
 
245
+ # Refresh logs (auto-injects profile & oauth_token)
246
+ refresh_btn = gr.Button("Refresh Logs")
247
+ def _refresh(profile, oauth_token):
248
+ repo = f"{profile.username}/{profile.username}-auto-space"
249
+ return fetch_logs(repo, "build"), fetch_logs(repo, "run")
250
+ refresh_btn.click(fn=_refresh, outputs=[build_box, run_box])
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  demo.launch(server_name="0.0.0.0", server_port=7860)