wuhp commited on
Commit
b4396cd
·
verified ·
1 Parent(s): 549a148

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -100
app.py CHANGED
@@ -3,6 +3,7 @@ import json
3
  import os
4
 
5
  import gradio as gr
 
6
  from huggingface_hub import (
7
  create_repo, list_models, upload_file, list_repo_files, constants
8
  )
@@ -38,7 +39,7 @@ def enable_repo_actions(repo_id, profile, token):
38
  def create_space(repo_name, sdk, profile, token):
39
  if not (profile and token):
40
  return "", "⚠️ Please log in first.", "<p>No Space created yet.</p>"
41
- rid = f"{profile.username}/{repo_name}"
42
  create_repo(
43
  repo_id=rid,
44
  token=token.token,
@@ -110,9 +111,7 @@ def get_container_logs(repo_id, profile, token):
110
  return "⚠️ Please log in and create a Space first."
111
  return _fetch_space_logs_level(repo_id, "run")
112
 
113
-
114
- # — FUNCTION DECLARATIONS & TOOL —
115
- # Build a single Tool containing all function declarations.
116
 
117
  func_decls = [
118
  types.FunctionDeclaration(
@@ -169,16 +168,16 @@ func_decls = [
169
  ]
170
  tool = types.Tool(function_declarations=func_decls)
171
 
172
-
173
- # — CHAT HANDLER —
174
 
175
  def execute_function_by_name(name, args, profile, token, session):
176
- """Dispatch to the right function and return a raw dict result."""
177
  if name == "create_space":
178
  rid, log, iframe = create_space(
179
  args["repo_name"], session["sdk"], profile, token
180
  )
181
  session["repo_id"] = rid
 
 
182
  return {"log": log, "iframe": iframe}
183
  if name == "write_file":
184
  status = write_file(
@@ -201,18 +200,15 @@ def execute_function_by_name(name, args, profile, token, session):
201
  )}
202
  return {"error": f"Unknown function {name}"}
203
 
204
-
205
  def process_message(
206
  profile, token, user_msg,
207
  gemini_key, sidebar_repo, sidebar_sdk,
208
  chat_history, session
209
  ):
210
- # Initialize chat once
211
  if session.get("chat") is None:
212
  client = genai.Client(api_key=gemini_key)
213
- # Pass the Tool object, not a list of dicts
214
  model = client.chats.create(
215
- model="gemini-2.0-flash",
216
  config=types.GenerateContentConfig(
217
  system_instruction=(
218
  "You are a HF Spaces admin. You can create spaces, "
@@ -228,150 +224,97 @@ def process_message(
228
  "sdk": sidebar_sdk,
229
  "messages": []
230
  })
231
-
232
- # Remember current SDK choice
233
  session["sdk"] = sidebar_sdk
234
-
235
- # Pre-chat “call it X” handler
236
  if session["repo_id"] is None:
237
- m = re.search(r"call (?:it )?([A-Za-z0-9_-]+)", user_msg)
238
  if m:
239
  args = {"repo_name": m.group(1), "sdk": sidebar_sdk}
240
  result = execute_function_by_name("create_space", args, profile, token, session)
241
  session["messages"].append({"role": "assistant", "content": result["log"]})
242
- return session["messages"], result.get("iframe", ""), result["log"], "", session
243
-
244
- # Append user message
245
  session["messages"].append({"role": "user", "content": user_msg})
246
  response = session["chat"].send_message(user_msg)
247
-
248
- # Handle function-calling loop
249
  while True:
250
  part = response.candidates[0].content.parts[0]
251
  if not part.function_call:
252
- break # no more tools needed
253
  fname = part.function_call.name
254
  fargs = part.function_call.args or {}
255
- # Run the tool
256
  result = execute_function_by_name(fname, fargs, profile, token, session)
257
- # Send function result back to model
258
  resp_part = types.Part.from_function_response(name=fname, response=result)
259
- response = session["chat"].send_message(types.Content(role="user", parts=[resp_part]))
260
-
261
- # Final assistant text
262
  assistant_text = response.text
263
  session["messages"].append({"role": "assistant", "content": assistant_text})
264
-
265
- # Update UI panels
266
- iframe = session.get("iframe", "")
267
- log = session.get("log", "")
268
- files = session.get("files", "")
269
- return session["messages"], iframe, log, files, session
270
-
271
-
272
- # — MANUAL SYNC —
273
 
274
  def sync_manual(profile, token, session):
275
  if not (profile and token and session.get("repo_id")):
276
  return "", "⚠️ Cannot sync manual changes.", "", session
277
  files = list_repo_files(session["repo_id"], token=token.token, repo_type="space")
278
  log = "🔄 Manual changes synced."
279
- return session.get("iframe",""), log, "\n".join(files), session
280
-
281
-
282
- # — GRADIO UI —
283
 
284
  with gr.Blocks(css="""
285
  #sidebar { background:#f2f2f2; padding:1rem; border-right:1px solid #ccc; }
286
  #main { padding:1rem; }
287
  """) as demo:
288
-
289
- # Sidebar
290
  with gr.Column(elem_id="sidebar", scale=1):
291
  gr.Markdown("### 🔑 HF Login & Config")
292
  login_btn = gr.LoginButton(variant="huggingface", size="sm")
293
  profile_state = gr.State(None)
294
  token_state = gr.State(None)
295
  login_btn.click(None, [], [profile_state, token_state])
296
-
297
  status_md = gr.Markdown("*Not logged in.*")
298
  profile_state.change(show_profile, [profile_state], [status_md])
299
-
300
  models_md = gr.Markdown()
301
- profile_state.change(list_private_models,
302
- [profile_state, token_state], [models_md])
303
-
304
  gemini_key = gr.Textbox(label="Gemini API Key", type="password")
305
  sidebar_repo = gr.Textbox(label="Space name", placeholder="blurrtest")
306
- sidebar_sdk = gr.Radio(["gradio","streamlit"],
307
- value="gradio", label="SDK")
308
-
309
  gr.Markdown("---")
310
  confirm_btn = gr.Button("🔄 Sync Manual Changes")
311
-
312
- # Main area
313
  with gr.Column(elem_id="main", scale=3):
314
  tabs = gr.Tabs()
315
  with tabs:
316
  with gr.TabItem("💬 Chat"):
317
- chatbox = gr.Chatbot(type="messages")
318
- user_input = gr.Textbox(show_label=False,
319
- placeholder="Generate code…")
320
- send_btn = gr.Button("Send")
321
  with gr.TabItem("🛠️ Manual"):
322
  gr.Markdown("#### Create / Rename Space")
323
- repo_m = gr.Textbox(label="Name", value="")
324
- sdk_m = gr.Radio(["gradio","streamlit"],
325
- value="gradio", label="SDK")
326
  create_btn = gr.Button("Create Space")
327
- sess_id = gr.Textbox(visible=False)
328
- log_c = gr.Textbox(label="Log", interactive=False, lines=2)
329
- preview = gr.HTML("<p>No Space yet.</p>")
330
-
331
- create_btn.click(create_space,
332
- [repo_m, sdk_m, profile_state, token_state],
333
- [sess_id, log_c, preview])
334
-
335
  gr.Markdown("#### Upload File")
336
- path = gr.Textbox(label="Path", value="app.py")
337
- file_u = gr.File()
338
- upload_btn = gr.Button("Upload File")
339
- log_u = gr.Textbox(label="Upload Log",
340
- interactive=False, lines=2)
341
-
342
- upload_btn.click(upload_file_to_space,
343
- [file_u, path, sess_id, profile_state, token_state],
344
- [log_u])
345
-
346
  gr.Markdown("#### Fetch Logs")
347
  b_btn = gr.Button("Build Logs")
348
  r_btn = gr.Button("Run Logs")
349
- log_b = gr.Textbox(label="Build", interactive=False, lines=5)
350
- log_r = gr.Textbox(label="Run", interactive=False, lines=5)
351
-
352
- b_btn.click(get_build_logs,
353
- [sess_id, profile_state, token_state],
354
- [log_b])
355
- r_btn.click(get_container_logs,
356
- [sess_id, profile_state, token_state],
357
- [log_r])
358
-
359
  gr.Markdown("---")
360
  iframe_out = gr.HTML(label="🖼️ Preview")
361
- log_out = gr.Textbox(label="📋 Latest Log", lines=4)
362
- files_out = gr.Textbox(label="📚 Files", lines=4)
363
-
364
  state = gr.State({})
365
- send_btn.click(process_message,
366
- [profile_state, token_state,
367
- user_input, gemini_key,
368
- sidebar_repo, sidebar_sdk,
369
- chatbox, state],
370
- [chatbox, iframe_out, log_out, files_out, state])
371
-
372
- confirm_btn.click(sync_manual,
373
- [profile_state, token_state, state],
374
- [iframe_out, log_out, files_out, state])
375
 
376
  if __name__ == "__main__":
377
  demo.launch()
 
3
  import os
4
 
5
  import gradio as gr
6
+ from PIL import Image, ImageFilter
7
  from huggingface_hub import (
8
  create_repo, list_models, upload_file, list_repo_files, constants
9
  )
 
39
  def create_space(repo_name, sdk, profile, token):
40
  if not (profile and token):
41
  return "", "⚠️ Please log in first.", "<p>No Space created yet.</p>"
42
+ rid = f"{profile.username}/{repo_name.replace(' ', '-') }"
43
  create_repo(
44
  repo_id=rid,
45
  token=token.token,
 
111
  return "⚠️ Please log in and create a Space first."
112
  return _fetch_space_logs_level(repo_id, "run")
113
 
114
+ # — FUNCTION DECLARATIONS & TOOL —
 
 
115
 
116
  func_decls = [
117
  types.FunctionDeclaration(
 
168
  ]
169
  tool = types.Tool(function_declarations=func_decls)
170
 
171
+ # — CHAT HANDLER —
 
172
 
173
  def execute_function_by_name(name, args, profile, token, session):
 
174
  if name == "create_space":
175
  rid, log, iframe = create_space(
176
  args["repo_name"], session["sdk"], profile, token
177
  )
178
  session["repo_id"] = rid
179
+ session["iframe"] = iframe
180
+ session["log"] = log
181
  return {"log": log, "iframe": iframe}
182
  if name == "write_file":
183
  status = write_file(
 
200
  )}
201
  return {"error": f"Unknown function {name}"}
202
 
 
203
  def process_message(
204
  profile, token, user_msg,
205
  gemini_key, sidebar_repo, sidebar_sdk,
206
  chat_history, session
207
  ):
 
208
  if session.get("chat") is None:
209
  client = genai.Client(api_key=gemini_key)
 
210
  model = client.chats.create(
211
+ model="gemini-2.5-flash-preview-04-17",
212
  config=types.GenerateContentConfig(
213
  system_instruction=(
214
  "You are a HF Spaces admin. You can create spaces, "
 
224
  "sdk": sidebar_sdk,
225
  "messages": []
226
  })
 
 
227
  session["sdk"] = sidebar_sdk
 
 
228
  if session["repo_id"] is None:
229
+ m = re.search(r"(?:call it|called)\s+([\w- ]+)", user_msg, re.IGNORECASE)
230
  if m:
231
  args = {"repo_name": m.group(1), "sdk": sidebar_sdk}
232
  result = execute_function_by_name("create_space", args, profile, token, session)
233
  session["messages"].append({"role": "assistant", "content": result["log"]})
234
+ return session["messages"], session["iframe"], session["log"], "", session
 
 
235
  session["messages"].append({"role": "user", "content": user_msg})
236
  response = session["chat"].send_message(user_msg)
 
 
237
  while True:
238
  part = response.candidates[0].content.parts[0]
239
  if not part.function_call:
240
+ break
241
  fname = part.function_call.name
242
  fargs = part.function_call.args or {}
 
243
  result = execute_function_by_name(fname, fargs, profile, token, session)
 
244
  resp_part = types.Part.from_function_response(name=fname, response=result)
245
+ response = session["chat"].send_message(resp_part)
 
 
246
  assistant_text = response.text
247
  session["messages"].append({"role": "assistant", "content": assistant_text})
248
+ return (
249
+ session["messages"],
250
+ session.get("iframe", ""),
251
+ session.get("log", ""),
252
+ session.get("files", ""),
253
+ session
254
+ )
 
 
255
 
256
  def sync_manual(profile, token, session):
257
  if not (profile and token and session.get("repo_id")):
258
  return "", "⚠️ Cannot sync manual changes.", "", session
259
  files = list_repo_files(session["repo_id"], token=token.token, repo_type="space")
260
  log = "🔄 Manual changes synced."
261
+ return session.get("iframe", ""), log, "\n".join(files), session
 
 
 
262
 
263
  with gr.Blocks(css="""
264
  #sidebar { background:#f2f2f2; padding:1rem; border-right:1px solid #ccc; }
265
  #main { padding:1rem; }
266
  """) as demo:
 
 
267
  with gr.Column(elem_id="sidebar", scale=1):
268
  gr.Markdown("### 🔑 HF Login & Config")
269
  login_btn = gr.LoginButton(variant="huggingface", size="sm")
270
  profile_state = gr.State(None)
271
  token_state = gr.State(None)
272
  login_btn.click(None, [], [profile_state, token_state])
 
273
  status_md = gr.Markdown("*Not logged in.*")
274
  profile_state.change(show_profile, [profile_state], [status_md])
 
275
  models_md = gr.Markdown()
276
+ profile_state.change(list_private_models,[profile_state, token_state],[models_md])
 
 
277
  gemini_key = gr.Textbox(label="Gemini API Key", type="password")
278
  sidebar_repo = gr.Textbox(label="Space name", placeholder="blurrtest")
279
+ sidebar_sdk = gr.Radio(["gradio","streamlit"],value="gradio",label="SDK")
 
 
280
  gr.Markdown("---")
281
  confirm_btn = gr.Button("🔄 Sync Manual Changes")
 
 
282
  with gr.Column(elem_id="main", scale=3):
283
  tabs = gr.Tabs()
284
  with tabs:
285
  with gr.TabItem("💬 Chat"):
286
+ chatbox = gr.Chatbot(type="messages")
287
+ user_input = gr.Textbox(show_label=False, placeholder="Generate code…")
288
+ send_btn = gr.Button("Send")
 
289
  with gr.TabItem("🛠️ Manual"):
290
  gr.Markdown("#### Create / Rename Space")
291
+ repo_m = gr.Textbox(label="Name", value="")
292
+ sdk_m = gr.Radio(["gradio","streamlit"],value="gradio",label="SDK")
 
293
  create_btn = gr.Button("Create Space")
294
+ sess_id = gr.Textbox(visible=False)
295
+ log_c = gr.Textbox(label="Log",interactive=False,lines=2)
296
+ preview = gr.HTML("<p>No Space yet.</p>")
297
+ create_btn.click(create_space,[repo_m,sdk_m,profile_state,token_state],[sess_id,log_c,preview])
 
 
 
 
298
  gr.Markdown("#### Upload File")
299
+ path = gr.Textbox(label="Path",value="app.py")
300
+ file_u = gr.File()
301
+ upload_btn = gr.Button("Upload File")
302
+ log_u = gr.Textbox(label="Upload Log",interactive=False,lines=2)
303
+ upload_btn.click(upload_file_to_space,[file_u,path,sess_id,profile_state,token_state],[log_u])
 
 
 
 
 
304
  gr.Markdown("#### Fetch Logs")
305
  b_btn = gr.Button("Build Logs")
306
  r_btn = gr.Button("Run Logs")
307
+ log_b = gr.Textbox(label="Build",interactive=False,lines=5)
308
+ log_r = gr.Textbox(label="Run",interactive=False,lines=5)
309
+ b_btn.click(get_build_logs,[sess_id,profile_state,token_state],[log_b])
310
+ r_btn.click(get_container_logs,[sess_id,profile_state,token_state],[log_r])
 
 
 
 
 
 
311
  gr.Markdown("---")
312
  iframe_out = gr.HTML(label="🖼️ Preview")
313
+ log_out = gr.Textbox(label="📋 Latest Log",lines=4)
314
+ files_out = gr.Textbox(label="📚 Files",lines=4)
 
315
  state = gr.State({})
316
+ send_btn.click(process_message,[profile_state,token_state,user_input,gemini_key,sidebar_repo,sidebar_sdk,chatbox,state],[chatbox,iframe_out,log_out,files_out,state])
317
+ confirm_btn.click(sync_manual,[profile_state,token_state,state],[iframe_out,log_out,files_out,state])
 
 
 
 
 
 
 
 
318
 
319
  if __name__ == "__main__":
320
  demo.launch()