wuhp commited on
Commit
06f3bae
ยท
verified ยท
1 Parent(s): 5d26448

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -82
app.py CHANGED
@@ -1,7 +1,7 @@
1
- import os, json
2
  import gradio as gr
3
  from huggingface_hub import (
4
- create_repo, list_models, upload_file, constants
5
  )
6
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
7
  from google import genai
@@ -35,13 +35,7 @@ def create_space(repo_name, sdk, profile, token):
35
  if not (profile and token):
36
  return "", "โš ๏ธ Please log in first.", "<p>No Space created yet.</p>"
37
  rid = f"{profile.username}/{repo_name}"
38
- create_repo(
39
- repo_id=rid,
40
- token=token.token,
41
- exist_ok=True,
42
- repo_type="space",
43
- space_sdk=sdk
44
- )
45
  url = f"https://huggingface.co/spaces/{rid}"
46
  return rid, f"โœ… Space ready: {url}", f'<iframe src="{url}" width="100%" height="400px"></iframe>'
47
 
@@ -52,18 +46,11 @@ def upload_file_to_space(file, path, repo_id, profile, token):
52
  return "โš ๏ธ Please create a Space first."
53
  if not file:
54
  return "โš ๏ธ No file selected."
55
- upload_file(
56
- path_or_fileobj=file.name,
57
- path_in_repo=path,
58
- repo_id=repo_id,
59
- token=token.token,
60
- repo_type="space"
61
- )
62
  return f"โœ… Uploaded `{path}` to `{repo_id}`"
63
 
64
  def _fetch_space_logs_level(repo_id, level):
65
- jwt_url = f"{constants.ENDPOINT}/api/spaces/{repo_id}/jwt"
66
- r = get_session().get(jwt_url, headers=build_hf_headers())
67
  hf_raise_for_status(r)
68
  jwt = r.json()["token"]
69
  url = f"https://api.hf.space/v1/{repo_id}/logs/{level}"
@@ -86,12 +73,11 @@ def get_container_logs(repo_id, profile, token):
86
  return "โš ๏ธ Please log in and create a Space first."
87
  return _fetch_space_logs_level(repo_id, "run")
88
 
89
-
90
  # โ€” GEMINI FUNCTION DECLARATIONS โ€”
91
 
92
  func_decls = [
93
  {
94
- "name":"create_space","description":"Create or get a Hugging Face Space",
95
  "parameters":{
96
  "type":"object",
97
  "properties":{
@@ -102,7 +88,7 @@ func_decls = [
102
  }
103
  },
104
  {
105
- "name":"list_files","description":"List files in the Space",
106
  "parameters":{
107
  "type":"object",
108
  "properties":{"repo_id":{"type":"string"}},
@@ -136,8 +122,8 @@ def process_message(profile, token, user_msg,
136
  client = genai.Client(api_key=gemini_key)
137
  cfg = types.GenerateContentConfig(
138
  system_instruction=(
139
- "You are a HF Spaces admin. "
140
- "Use functions to create spaces, list files, and fetch logs."
141
  ),
142
  temperature=0,
143
  tools=[ types.Tool(function_declarations=func_decls) ]
@@ -154,20 +140,18 @@ def process_message(profile, token, user_msg,
154
  if part.function_call:
155
  name = part.function_call.name
156
  args = json.loads(part.function_call.args)
157
- if name=="create_space":
158
  rid, log, iframe = create_space(
159
  args["repo_name"], args["sdk"], profile, token
160
  )
161
  session["repo_id"] = rid
162
  result = {"log": log, "iframe": iframe}
163
- elif name=="list_files":
164
- files = list_repo_files(
165
- session["repo_id"], token=token.token, repo_type="space"
166
- )
167
- result = {"files": "\n".join(files)}
168
- elif name=="get_build_logs":
169
  result = {"log": get_build_logs(session["repo_id"], profile, token)}
170
- elif name=="get_run_logs":
171
  result = {"log": get_container_logs(session["repo_id"], profile, token)}
172
  else:
173
  result = {"log": f"โš ๏ธ Unknown function {name}"}
@@ -185,7 +169,6 @@ def process_message(profile, token, user_msg,
185
  else:
186
  final = part.text
187
 
188
- # update panels
189
  if "iframe" in result: session["iframe"] = result["iframe"]
190
  if "log" in result: session["log"] = result["log"]
191
  if "files" in result: session["files"] = result["files"]
@@ -203,25 +186,19 @@ def sync_manual(profile, token, session):
203
  "โš ๏ธ Cannot sync manual changes.",
204
  session.get("files",""),
205
  session)
206
- files = list_repo_files(
207
- session["repo_id"], token=token.token, repo_type="space"
208
- )
209
- session["files"] = "\n".join(files)
210
  session["log"] = "๐Ÿ”„ Manual changes synced."
211
  return (session.get("iframe",""),
212
  session["log"],
213
  session["files"],
214
  session)
215
 
216
- def capture_login(profile, oauth_token):
217
- return profile, oauth_token
218
-
219
-
220
- # โ€” BUILD THE UI โ€”
221
 
222
  with gr.Blocks(css="""
223
- #sidebar {background:#f0f0f0;padding:1rem;border-right:1px solid #ccc;}
224
- #main {padding:1rem;}
225
  """) as demo:
226
 
227
  with gr.Row():
@@ -229,17 +206,14 @@ with gr.Blocks(css="""
229
  with gr.Column(elem_id="sidebar", scale=1):
230
  gr.Markdown("### ๐Ÿ”‘ HF Login & Config")
231
  login_btn = gr.LoginButton(variant="huggingface", size="sm")
232
- profile_state = gr.State()
233
- token_state = gr.State()
234
 
235
- login_btn.click(capture_login,
236
- inputs=[login_btn],
237
- outputs=[profile_state, token_state])
238
 
239
  status_md = gr.Markdown("*Not logged in.*")
240
- profile_state.change(show_profile,
241
- inputs=[profile_state],
242
- outputs=[status_md])
243
 
244
  models_md = gr.Markdown()
245
  profile_state.change(list_private_models,
@@ -248,8 +222,7 @@ with gr.Blocks(css="""
248
 
249
  gemini_key = gr.Textbox(label="Gemini API Key", type="password")
250
  sidebar_repo = gr.Textbox(label="Space name", placeholder="my-space")
251
- sidebar_sdk = gr.Radio(["gradio","streamlit"],
252
- value="gradio", label="SDK")
253
 
254
  gr.Markdown("---")
255
  confirm_btn = gr.Button("๐Ÿ”„ Confirm Manual Changes")
@@ -259,19 +232,16 @@ with gr.Blocks(css="""
259
  tabs = gr.Tabs()
260
  with tabs:
261
  with gr.TabItem("๐Ÿ’ฌ Chat"):
262
- chatbox = gr.Chatbot(type="pairs")
263
- user_input = gr.Textbox(show_label=False,
264
- placeholder="Ask the LLMโ€ฆ")
265
  send_btn = gr.Button("Send")
266
  with gr.TabItem("๐Ÿ› ๏ธ Manual"):
267
  gr.Markdown("#### Create a Space")
268
- repo_m = gr.Textbox(label="Name")
269
- sdk_m = gr.Radio(["gradio","streamlit"],
270
- value="gradio", label="SDK")
271
  create_btn = gr.Button("Create Space")
272
  sess_id = gr.Textbox(visible=False)
273
- log_c = gr.Textbox(label="Log",
274
- interactive=False, lines=2)
275
  preview = gr.HTML("<p>No Space yet.</p>")
276
 
277
  create_btn.click(create_space,
@@ -280,37 +250,30 @@ with gr.Blocks(css="""
280
  outputs=[sess_id, log_c, preview])
281
 
282
  gr.Markdown("#### Upload File")
283
- path_in_repo = gr.Textbox(label="Path in Repo",
284
- value="app.py")
285
- file_uploader = gr.File()
286
- up_btn = gr.Button("Upload File")
287
- log_u = gr.Textbox(label="Log",
288
- interactive=False, lines=2)
289
-
290
- up_btn.click(upload_file_to_space,
291
- inputs=[file_uploader, path_in_repo,
292
- sess_id,
293
- profile_state, token_state],
294
- outputs=[log_u])
295
 
296
  gr.Markdown("#### Fetch Logs")
297
  b_btn = gr.Button("Build Logs")
298
  r_btn = gr.Button("Run Logs")
299
- log_b = gr.Textbox(label="Build",
300
- interactive=False, lines=5)
301
- log_r = gr.Textbox(label="Run",
302
- interactive=False, lines=5)
303
 
304
  b_btn.click(get_build_logs,
305
- inputs=[sess_id,
306
- profile_state, token_state],
307
  outputs=[log_b])
308
  r_btn.click(get_container_logs,
309
- inputs=[sess_id,
310
- profile_state, token_state],
311
  outputs=[log_r])
312
 
313
- # Persistent panels
314
  gr.Markdown("---")
315
  iframe_out = gr.HTML(label="๐Ÿ–ผ๏ธ Preview")
316
  log_out = gr.Textbox(label="๐Ÿ“‹ Latest Log", lines=4)
 
1
+ import json, os
2
  import gradio as gr
3
  from huggingface_hub import (
4
+ create_repo, list_models, upload_file, list_repo_files, constants
5
  )
6
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
7
  from google import genai
 
35
  if not (profile and token):
36
  return "", "โš ๏ธ Please log in first.", "<p>No Space created yet.</p>"
37
  rid = f"{profile.username}/{repo_name}"
38
+ create_repo(rid, token=token.token, exist_ok=True, repo_type="space", space_sdk=sdk)
 
 
 
 
 
 
39
  url = f"https://huggingface.co/spaces/{rid}"
40
  return rid, f"โœ… Space ready: {url}", f'<iframe src="{url}" width="100%" height="400px"></iframe>'
41
 
 
46
  return "โš ๏ธ Please create a Space first."
47
  if not file:
48
  return "โš ๏ธ No file selected."
49
+ upload_file(file.name, path, repo_id, token=token.token, repo_type="space")
 
 
 
 
 
 
50
  return f"โœ… Uploaded `{path}` to `{repo_id}`"
51
 
52
  def _fetch_space_logs_level(repo_id, level):
53
+ r = get_session().get(f"{constants.ENDPOINT}/api/spaces/{repo_id}/jwt", headers=build_hf_headers())
 
54
  hf_raise_for_status(r)
55
  jwt = r.json()["token"]
56
  url = f"https://api.hf.space/v1/{repo_id}/logs/{level}"
 
73
  return "โš ๏ธ Please log in and create a Space first."
74
  return _fetch_space_logs_level(repo_id, "run")
75
 
 
76
  # โ€” GEMINI FUNCTION DECLARATIONS โ€”
77
 
78
  func_decls = [
79
  {
80
+ "name":"create_space","description":"Create/get a HF Space",
81
  "parameters":{
82
  "type":"object",
83
  "properties":{
 
88
  }
89
  },
90
  {
91
+ "name":"list_files","description":"List files in Space",
92
  "parameters":{
93
  "type":"object",
94
  "properties":{"repo_id":{"type":"string"}},
 
122
  client = genai.Client(api_key=gemini_key)
123
  cfg = types.GenerateContentConfig(
124
  system_instruction=(
125
+ "You are a HF Spaces admin. Use functions to create spaces, "
126
+ "list files, and fetch logs."
127
  ),
128
  temperature=0,
129
  tools=[ types.Tool(function_declarations=func_decls) ]
 
140
  if part.function_call:
141
  name = part.function_call.name
142
  args = json.loads(part.function_call.args)
143
+ if name == "create_space":
144
  rid, log, iframe = create_space(
145
  args["repo_name"], args["sdk"], profile, token
146
  )
147
  session["repo_id"] = rid
148
  result = {"log": log, "iframe": iframe}
149
+ elif name == "list_files":
150
+ fl = list_repo_files(session["repo_id"], token=token.token, repo_type="space")
151
+ result = {"files": "\n".join(fl)}
152
+ elif name == "get_build_logs":
 
 
153
  result = {"log": get_build_logs(session["repo_id"], profile, token)}
154
+ elif name == "get_run_logs":
155
  result = {"log": get_container_logs(session["repo_id"], profile, token)}
156
  else:
157
  result = {"log": f"โš ๏ธ Unknown function {name}"}
 
169
  else:
170
  final = part.text
171
 
 
172
  if "iframe" in result: session["iframe"] = result["iframe"]
173
  if "log" in result: session["log"] = result["log"]
174
  if "files" in result: session["files"] = result["files"]
 
186
  "โš ๏ธ Cannot sync manual changes.",
187
  session.get("files",""),
188
  session)
189
+ fl = list_repo_files(session["repo_id"], token=token.token, repo_type="space")
190
+ session["files"] = "\n".join(fl)
 
 
191
  session["log"] = "๐Ÿ”„ Manual changes synced."
192
  return (session.get("iframe",""),
193
  session["log"],
194
  session["files"],
195
  session)
196
 
197
+ # โ€” BUILD UI โ€”
 
 
 
 
198
 
199
  with gr.Blocks(css="""
200
+ #sidebar { background: #f2f2f2; padding: 1rem; border-right:1px solid #ccc; }
201
+ #main { padding: 1rem; }
202
  """) as demo:
203
 
204
  with gr.Row():
 
206
  with gr.Column(elem_id="sidebar", scale=1):
207
  gr.Markdown("### ๐Ÿ”‘ HF Login & Config")
208
  login_btn = gr.LoginButton(variant="huggingface", size="sm")
209
+ profile_state = gr.State(None)
210
+ token_state = gr.State(None)
211
 
212
+ # capture both outputs
213
+ login_btn.click(None, [], [profile_state, token_state])
 
214
 
215
  status_md = gr.Markdown("*Not logged in.*")
216
+ profile_state.change(show_profile, inputs=[profile_state], outputs=[status_md])
 
 
217
 
218
  models_md = gr.Markdown()
219
  profile_state.change(list_private_models,
 
222
 
223
  gemini_key = gr.Textbox(label="Gemini API Key", type="password")
224
  sidebar_repo = gr.Textbox(label="Space name", placeholder="my-space")
225
+ sidebar_sdk = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK")
 
226
 
227
  gr.Markdown("---")
228
  confirm_btn = gr.Button("๐Ÿ”„ Confirm Manual Changes")
 
232
  tabs = gr.Tabs()
233
  with tabs:
234
  with gr.TabItem("๐Ÿ’ฌ Chat"):
235
+ chatbox = gr.Chatbot(type="tuples")
236
+ user_input = gr.Textbox(show_label=False, placeholder="Ask the LLMโ€ฆ")
 
237
  send_btn = gr.Button("Send")
238
  with gr.TabItem("๐Ÿ› ๏ธ Manual"):
239
  gr.Markdown("#### Create a Space")
240
+ repo_m = gr.Textbox(label="Name")
241
+ sdk_m = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK")
 
242
  create_btn = gr.Button("Create Space")
243
  sess_id = gr.Textbox(visible=False)
244
+ log_c = gr.Textbox(label="Log", interactive=False, lines=2)
 
245
  preview = gr.HTML("<p>No Space yet.</p>")
246
 
247
  create_btn.click(create_space,
 
250
  outputs=[sess_id, log_c, preview])
251
 
252
  gr.Markdown("#### Upload File")
253
+ path = gr.Textbox(label="Path", value="app.py")
254
+ file_u = gr.File()
255
+ upload_btn = gr.Button("Upload File")
256
+ log_u = gr.Textbox(label="Log", interactive=False, lines=2)
257
+
258
+ upload_btn.click(upload_file_to_space,
259
+ inputs=[file_u, path, sess_id,
260
+ profile_state, token_state],
261
+ outputs=[log_u])
 
 
 
262
 
263
  gr.Markdown("#### Fetch Logs")
264
  b_btn = gr.Button("Build Logs")
265
  r_btn = gr.Button("Run Logs")
266
+ log_b = gr.Textbox(label="Build", interactive=False, lines=5)
267
+ log_r = gr.Textbox(label="Run", interactive=False, lines=5)
 
 
268
 
269
  b_btn.click(get_build_logs,
270
+ inputs=[sess_id, profile_state, token_state],
 
271
  outputs=[log_b])
272
  r_btn.click(get_container_logs,
273
+ inputs=[sess_id, profile_state, token_state],
 
274
  outputs=[log_r])
275
 
276
+ # persistent panels
277
  gr.Markdown("---")
278
  iframe_out = gr.HTML(label="๐Ÿ–ผ๏ธ Preview")
279
  log_out = gr.Textbox(label="๐Ÿ“‹ Latest Log", lines=4)