wuhp commited on
Commit
1c7f8b9
·
verified ·
1 Parent(s): 18dce47

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -39
app.py CHANGED
@@ -1,10 +1,11 @@
1
  import re
2
  import json
3
  import time
 
4
  import importlib.metadata
5
 
6
  import gradio as gr
7
- from huggingface_hub import create_repo, upload_file, list_models, constants
8
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
9
  from google import genai
10
  from google.genai.types import Tool, GenerateContentConfig, GoogleSearch
@@ -62,13 +63,36 @@ def fetch_logs(repo_id: str, level: str) -> str:
62
  if raw.startswith(b"data: "):
63
  try:
64
  ev = json.loads(raw[len(b"data: "):].decode())
65
- ts = ev.get("timestamp","")
66
- txt = ev.get("data","")
67
  lines.append(f"[{ts}] {txt}")
68
  except:
69
  continue
70
  return "\n".join(lines)
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  # — CORE LOOP —
73
 
74
  def handle_user_message(
@@ -83,26 +107,41 @@ def handle_user_message(
83
  if profile is None or oauth_token is None:
84
  return (
85
  history + [{"role":"assistant","content":"⚠️ Please log in first."}],
86
- "",
87
- "",
88
- "<p>No Space yet.</p>"
89
  )
90
 
91
- username = profile.username
92
- repo_name = f"{username}-{space_suffix}"
93
- repo_id = f"{username}/{repo_name}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
 
95
  client = genai.Client(api_key=gemini_api_key)
96
  system_msg = {
97
- "role":"system",
98
- "content":(
99
- f"You are an AI assistant writing a HuggingFace Space using the "
100
- f"{sdk_choice} SDK. After producing code, wait for logs; if errors appear, fix them."
101
  )
102
  }
103
  chat = [system_msg] + history
104
 
105
- code_fn = "app.py" if sdk_choice=="gradio" else "streamlit_app.py"
106
  readme_fn = "README.md"
107
  reqs_fn = "requirements.txt"
108
 
@@ -118,7 +157,7 @@ def handle_user_message(
118
  )
119
 
120
  raw_code = resp.text
121
- code = extract_code(raw_code)
122
  chat.append({"role":"assistant","content":code})
123
 
124
  # Write code file
@@ -145,7 +184,7 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
145
 
146
  # Write requirements
147
  base_reqs = "pandas\n"
148
- extra = "streamlit\n" if sdk_choice=="streamlit" else "gradio\n"
149
  with open(reqs_fn, "w") as f:
150
  f.write(base_reqs + extra)
151
 
@@ -166,31 +205,30 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
166
  repo_type="space"
167
  )
168
 
169
- # If build succeeds without errors, break; otherwise feed logs back to LLM
170
  build = fetch_logs(repo_id, "build")
171
  run = fetch_logs(repo_id, "run")
172
  if "ERROR" not in build.upper() and "ERROR" not in run.upper():
173
  break
174
 
 
175
  chat.append({
176
  "role":"user",
177
  "content":(
178
- f"Build logs:\n{build}\n\n"
179
- f"Run logs:\n{run}\n\n"
180
- "Please fix the code."
181
  )
182
  })
183
  time.sleep(2)
184
 
185
- # Prepare messages + immediate iframe preview
186
- messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
187
- preview_url = f"https://huggingface.co/spaces/{repo_id}"
188
  iframe = (
189
  f'<iframe src="{preview_url}" '
190
  f'width="100%" height="500px" frameborder="0"></iframe>'
191
  )
192
 
193
- placeholder = "✅ Space created! Click “Refresh Logs” to pull build/run logs."
194
  return messages, placeholder, placeholder, iframe
195
 
196
  # — REFRESH LOGS —
@@ -201,11 +239,12 @@ def refresh_logs(
201
  oauth_token: gr.OAuthToken | None
202
  ):
203
  if profile is None or oauth_token is None:
204
- return "⚠️ Please log in.", "⚠️ Please log in."
205
  repo_id = f"{profile.username}/{profile.username}-{space_suffix}"
206
- return fetch_logs(repo_id, "build"), fetch_logs(repo_id, "run")
 
207
 
208
- # — BUILD THE UI —
209
 
210
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
211
  gr.Markdown("## Sign in + Auto‑Build Spaces\n\n"
@@ -221,19 +260,19 @@ with gr.Blocks(title="HF Space Auto‑Builder") as demo:
221
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
222
 
223
  # SETTINGS
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
- space_suffix= gr.Textbox(label="Space suffix", value="auto-space",
228
- info="E.g. 'auto-space', 'auto-space2', etc.")
229
 
230
  # CHAT + OUTPUTS
231
- chatbot = gr.Chatbot(type="messages")
232
- user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt")
233
- send_btn = gr.Button("Send")
234
- build_box = gr.Textbox(label="Build logs", lines=5, interactive=False)
235
- run_box = gr.Textbox(label="Run logs", lines=5, interactive=False)
236
- preview = gr.HTML("<p>No Space yet.</p>")
237
 
238
  send_btn.click(
239
  fn=handle_user_message,
@@ -245,7 +284,7 @@ with gr.Blocks(title="HF Space Auto‑Builder") as demo:
245
  refresh_btn = gr.Button("Refresh Logs")
246
  refresh_btn.click(
247
  fn=refresh_logs,
248
- inputs=[space_suffix],
249
  outputs=[build_box, run_box]
250
  )
251
 
 
1
  import re
2
  import json
3
  import time
4
+ import os
5
  import importlib.metadata
6
 
7
  import gradio as gr
8
+ from huggingface_hub import create_repo, upload_file, list_models, constants, Repository
9
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
10
  from google import genai
11
  from google.genai.types import Tool, GenerateContentConfig, GoogleSearch
 
63
  if raw.startswith(b"data: "):
64
  try:
65
  ev = json.loads(raw[len(b"data: "):].decode())
66
+ ts = ev.get("timestamp", "")
67
+ txt = ev.get("data", "")
68
  lines.append(f"[{ts}] {txt}")
69
  except:
70
  continue
71
  return "\n".join(lines)
72
 
73
+ def fetch_all_logs(repo_id: str) -> str:
74
+ """Return combined build + run logs."""
75
+ build = fetch_logs(repo_id, "build")
76
+ run = fetch_logs(repo_id, "run")
77
+ return f"--- BUILD ---\n{build}\n\n--- RUN ---\n{run}"
78
+
79
+ # — SYNC MANUAL EDITS —
80
+
81
+ def sync_and_read_code(username: str, repo_name: str, token: str, code_filename: str) -> str:
82
+ """Clone or pull the HF Space repo locally and return the latest code."""
83
+ local_dir = f"./{repo_name}"
84
+ repo_url = f"https://huggingface.co/spaces/{username}/{repo_name}"
85
+ repo = Repository(
86
+ local_dir,
87
+ clone_from=repo_url,
88
+ use_auth_token=token,
89
+ repo_type="space"
90
+ )
91
+ repo.git_pull()
92
+ path = os.path.join(local_dir, code_filename)
93
+ with open(path, "r") as f:
94
+ return f.read()
95
+
96
  # — CORE LOOP —
97
 
98
  def handle_user_message(
 
107
  if profile is None or oauth_token is None:
108
  return (
109
  history + [{"role":"assistant","content":"⚠️ Please log in first."}],
110
+ "", "", "<p>No Space yet.</p>"
 
 
111
  )
112
 
113
+ username = profile.username
114
+ repo_name = f"{username}-{space_suffix}"
115
+ repo_id = f"{username}/{repo_name}"
116
+ code_fn = "app.py" if sdk_choice == "gradio" else "streamlit_app.py"
117
+
118
+ # Sync manual edits into history before LLM generation
119
+ try:
120
+ latest_code = sync_and_read_code(username, repo_name, oauth_token.token, code_fn)
121
+ history.append({
122
+ "role": "assistant",
123
+ "content": (
124
+ f"🔄 Synced latest `{code_fn}` from the Space:\n"
125
+ "```python\n"
126
+ f"{latest_code}\n"
127
+ "```"
128
+ )
129
+ })
130
+ except Exception:
131
+ # If repo doesn't exist yet, skip sync
132
+ pass
133
 
134
+ # Build chat context
135
  client = genai.Client(api_key=gemini_api_key)
136
  system_msg = {
137
+ "role": "system",
138
+ "content": (
139
+ f"You are an AI assistant writing a HuggingFace Space using the {sdk_choice} SDK. "
140
+ "After producing code, wait for logs; if errors appear, fix them."
141
  )
142
  }
143
  chat = [system_msg] + history
144
 
 
145
  readme_fn = "README.md"
146
  reqs_fn = "requirements.txt"
147
 
 
157
  )
158
 
159
  raw_code = resp.text
160
+ code = extract_code(raw_code)
161
  chat.append({"role":"assistant","content":code})
162
 
163
  # Write code file
 
184
 
185
  # Write requirements
186
  base_reqs = "pandas\n"
187
+ extra = "streamlit\n" if sdk_choice == "streamlit" else "gradio\n"
188
  with open(reqs_fn, "w") as f:
189
  f.write(base_reqs + extra)
190
 
 
205
  repo_type="space"
206
  )
207
 
208
+ # Fetch logs and break if no errors
209
  build = fetch_logs(repo_id, "build")
210
  run = fetch_logs(repo_id, "run")
211
  if "ERROR" not in build.upper() and "ERROR" not in run.upper():
212
  break
213
 
214
+ # Feed errors back to LLM
215
  chat.append({
216
  "role":"user",
217
  "content":(
218
+ f"Build logs:\n{build}\n\nRun logs:\n{run}\n\nPlease fix the code."
 
 
219
  )
220
  })
221
  time.sleep(2)
222
 
223
+ # Prepare messages + iframe preview
224
+ messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"] != "system"]
225
+ preview_url = f"https://huggingface.co/spaces/{username}/{repo_name}"
226
  iframe = (
227
  f'<iframe src="{preview_url}" '
228
  f'width="100%" height="500px" frameborder="0"></iframe>'
229
  )
230
 
231
+ placeholder = "✅ Space created! Click “Refresh Logs” to pull logs."
232
  return messages, placeholder, placeholder, iframe
233
 
234
  # — REFRESH LOGS —
 
239
  oauth_token: gr.OAuthToken | None
240
  ):
241
  if profile is None or oauth_token is None:
242
+ return "⚠️ Please log in.", ""
243
  repo_id = f"{profile.username}/{profile.username}-{space_suffix}"
244
+ combined = fetch_all_logs(repo_id)
245
+ return combined, ""
246
 
247
+ # — BUILD THE UI —
248
 
249
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
250
  gr.Markdown("## Sign in + Auto‑Build Spaces\n\n"
 
260
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
261
 
262
  # SETTINGS
263
+ sdk_choice = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK template")
264
+ api_key = gr.Textbox(label="Gemini API Key", type="password")
265
+ grounding = gr.Checkbox(label="Enable grounding", value=False)
266
+ space_suffix = gr.Textbox(label="Space suffix", value="auto-space",
267
+ info="E.g. 'auto-space', 'auto-space2', etc.")
268
 
269
  # CHAT + OUTPUTS
270
+ chatbot = gr.Chatbot(type="messages")
271
+ user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt")
272
+ send_btn = gr.Button("Send")
273
+ build_box = gr.Textbox(label="Build logs", lines=10, interactive=False)
274
+ run_box = gr.Textbox(label="Run logs", lines=1, interactive=False)
275
+ preview = gr.HTML("<p>No Space yet.</p>")
276
 
277
  send_btn.click(
278
  fn=handle_user_message,
 
284
  refresh_btn = gr.Button("Refresh Logs")
285
  refresh_btn.click(
286
  fn=refresh_logs,
287
+ inputs=[space_suffix, status_md, api_key],
288
  outputs=[build_box, run_box]
289
  )
290