wuhp commited on
Commit
51ca703
·
verified ·
1 Parent(s): 3282626

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -73
app.py CHANGED
@@ -39,13 +39,9 @@ def get_sdk_version(sdk_choice: str) -> str:
39
 
40
  def extract_code(text: str) -> str:
41
  """
42
- Extract the last
43
-
44
- block. If none, return whole text.
45
  """
46
- blocks = re.findall(r"
47
- (?:\w*\n)?([\s\S]*?)
48
- ", text)
49
  return blocks[-1].strip() if blocks else text.strip()
50
 
51
  # — HF SPACE LOGGING —
@@ -73,7 +69,7 @@ def fetch_logs(repo_id: str, level: str) -> str:
73
  continue
74
  return "\n".join(lines)
75
 
76
- # — CORE LOOP —
77
 
78
  def handle_user_message(
79
  history,
@@ -84,17 +80,22 @@ def handle_user_message(
84
  profile: gr.OAuthProfile | None,
85
  oauth_token: gr.OAuthToken | None
86
  ):
 
87
  if profile is None or oauth_token is None:
88
- return (
89
- history + [{"role":"assistant","content":"⚠️ Please log in first."}],
90
- "",
91
- "",
92
- "<p>No Space yet.</p>"
93
- )
 
 
 
 
 
94
 
95
- username = profile.username
96
- repo_name = f"{username}-{space_suffix}"
97
- repo_id = f"{username}/{repo_name}"
98
 
99
  client = genai.Client(api_key=gemini_api_key)
100
  system_msg = {
@@ -106,30 +107,26 @@ def handle_user_message(
106
  }
107
  chat = [system_msg] + history
108
 
109
- code_fn = "app.py" if sdk_choice=="gradio" else "streamlit_app.py"
110
  readme_fn = "README.md"
111
  reqs_fn = "requirements.txt"
112
 
113
- # Try up to 5 times to generate & push working code
114
  for _ in range(5):
115
  tools = [Tool(google_search=GoogleSearch())] if grounding_enabled else []
116
  cfg = GenerateContentConfig(tools=tools, response_modalities=["TEXT"])
117
-
118
- resp = client.models.generate_content(
119
  model="gemini-2.5-flash-preview-04-17",
120
  contents=[m["content"] for m in chat],
121
  config=cfg
122
  )
123
 
124
- raw_code = resp.text
125
- code = extract_code(raw_code)
126
  chat.append({"role":"assistant","content":code})
127
 
128
- # Write code file
129
  with open(code_fn, "w") as f:
130
  f.write(code)
131
-
132
- # Write README with dynamic SDK version
133
  sdk_version = get_sdk_version(sdk_choice)
134
  readme = f"""---
135
  title: Wuhp Auto Space
@@ -146,10 +143,8 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
146
  """
147
  with open(readme_fn, "w") as f:
148
  f.write(readme)
149
-
150
- # Write requirements
151
  base_reqs = "pandas\n"
152
- extra = "streamlit\n" if sdk_choice=="streamlit" else "gradio\n"
153
  with open(reqs_fn, "w") as f:
154
  f.write(base_reqs + extra)
155
 
@@ -170,33 +165,29 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
170
  repo_type="space"
171
  )
172
 
173
- # If build succeeds without errors, break; otherwise feed logs back to LLM
174
- build = fetch_logs(repo_id, "build")
175
- run = fetch_logs(repo_id, "run")
176
- if "ERROR" not in build.upper() and "ERROR" not in run.upper():
 
 
 
 
 
 
177
  break
178
 
 
179
  chat.append({
180
- "role":"user",
181
- "content":(
182
- f"Build logs:\n{build}\n\n"
183
- f"Run logs:\n{run}\n\n"
184
  "Please fix the code."
185
  )
186
  })
187
  time.sleep(2)
188
 
189
- # Prepare messages + immediate iframe preview
190
- messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
191
- preview_url = f"https://huggingface.co/spaces/{repo_id}"
192
- iframe = (
193
- f'<iframe src="{preview_url}" '
194
- f'width="100%" height="500px" frameborder="0"></iframe>'
195
- )
196
-
197
- placeholder = "✅ Space created! Click “Refresh Logs” to pull build/run logs."
198
- return messages, placeholder, placeholder, iframe
199
-
200
  # — REFRESH LOGS —
201
 
202
  def refresh_logs(
@@ -212,45 +203,49 @@ def refresh_logs(
212
  # — BUILD THE UI —
213
 
214
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
215
- gr.Markdown("## Sign in + Auto‑Build Spaces\n\n"
216
- "1. Sign in 2. Enter your prompt 3. Watch code, README, requirements, logs, and preview\n\n---")
217
-
218
- # LOGIN controls
219
- login_btn = gr.LoginButton(variant="huggingface", size="lg")
220
- status_md = gr.Markdown("*Not logged in.*")
221
- models_md = gr.Markdown()
222
- demo.load(show_profile, inputs=None, outputs=status_md)
223
- demo.load(list_private_models, inputs=None, outputs=models_md)
 
 
224
  login_btn.click(show_profile, inputs=None, outputs=status_md)
225
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
226
 
227
  # SETTINGS
228
- sdk_choice = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK template")
229
- api_key = gr.Textbox(label="Gemini API Key", type="password")
230
- grounding = gr.Checkbox(label="Enable grounding", value=False)
231
- space_suffix= gr.Textbox(label="Space suffix", value="auto-space",
232
- info="E.g. 'auto-space', 'auto-space2', etc.")
233
 
234
  # CHAT + OUTPUTS
235
- chatbot = gr.Chatbot(type="messages")
236
- user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt")
237
- send_btn = gr.Button("Send")
238
- build_box = gr.Textbox(label="Build logs", lines=5, interactive=False)
239
- run_box = gr.Textbox(label="Run logs", lines=5, interactive=False)
240
- preview = gr.HTML("<p>No Space yet.</p>")
241
-
 
242
  send_btn.click(
243
  fn=handle_user_message,
244
- inputs=[chatbot, sdk_choice, api_key, grounding, space_suffix],
245
- outputs=[chatbot, build_box, run_box, preview]
 
246
  )
247
 
248
- # Manual log refresh
249
  refresh_btn = gr.Button("Refresh Logs")
250
  refresh_btn.click(
251
  fn=refresh_logs,
252
- inputs=[space_suffix],
253
  outputs=[build_box, run_box]
254
  )
255
 
256
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
39
 
40
  def extract_code(text: str) -> str:
41
  """
42
+ Extract the last ```…``` block. If none, return whole text.
 
 
43
  """
44
+ blocks = re.findall(r"```(?:\w*\n)?([\s\S]*?)```", text)
 
 
45
  return blocks[-1].strip() if blocks else text.strip()
46
 
47
  # — HF SPACE LOGGING —
 
69
  continue
70
  return "\n".join(lines)
71
 
72
+ # — CORE LOOP (generator)
73
 
74
  def handle_user_message(
75
  history,
 
80
  profile: gr.OAuthProfile | None,
81
  oauth_token: gr.OAuthToken | None
82
  ):
83
+ # 1) Require login
84
  if profile is None or oauth_token is None:
85
+ yield history + [{"role":"assistant","content":"⚠️ Please log in first."}], "", "", "<p>No Space yet.</p>"
86
+ return
87
+
88
+ username = profile.username
89
+ repo_name = f"{username}-{space_suffix}"
90
+ repo_id = f"{username}/{repo_name}"
91
+ preview_url = f"https://{username}-{space_suffix}.hf.space"
92
+ iframe_html = (
93
+ f'<iframe src="{preview_url}" '
94
+ f'width="100%" height="500px" frameborder="0"></iframe>'
95
+ )
96
 
97
+ # 2) Initial “in progress” update
98
+ yield history + [{"role":"assistant","content":"🚀 Generating and deploying your Space..."}], "Fetching logs…", "Fetching logs…", iframe_html
 
99
 
100
  client = genai.Client(api_key=gemini_api_key)
101
  system_msg = {
 
107
  }
108
  chat = [system_msg] + history
109
 
110
+ code_fn = "app.py" if sdk_choice == "gradio" else "streamlit_app.py"
111
  readme_fn = "README.md"
112
  reqs_fn = "requirements.txt"
113
 
114
+ # 3) Build & retry loop
115
  for _ in range(5):
116
  tools = [Tool(google_search=GoogleSearch())] if grounding_enabled else []
117
  cfg = GenerateContentConfig(tools=tools, response_modalities=["TEXT"])
118
+ resp = client.models.generate_content(
 
119
  model="gemini-2.5-flash-preview-04-17",
120
  contents=[m["content"] for m in chat],
121
  config=cfg
122
  )
123
 
124
+ code = extract_code(resp.text)
 
125
  chat.append({"role":"assistant","content":code})
126
 
127
+ # Write files
128
  with open(code_fn, "w") as f:
129
  f.write(code)
 
 
130
  sdk_version = get_sdk_version(sdk_choice)
131
  readme = f"""---
132
  title: Wuhp Auto Space
 
143
  """
144
  with open(readme_fn, "w") as f:
145
  f.write(readme)
 
 
146
  base_reqs = "pandas\n"
147
+ extra = "streamlit\n" if sdk_choice == "streamlit" else "gradio\n"
148
  with open(reqs_fn, "w") as f:
149
  f.write(base_reqs + extra)
150
 
 
165
  repo_type="space"
166
  )
167
 
168
+ # Fetch logs
169
+ build_logs = fetch_logs(repo_id, "build")
170
+ run_logs = fetch_logs(repo_id, "run")
171
+
172
+ # Stream update
173
+ msgs = [{"role":m["role"], "content":m["content"]} for m in chat if m["role"] != "system"]
174
+ yield msgs, build_logs, run_logs, iframe_html
175
+
176
+ # Stop if successful
177
+ if "ERROR" not in build_logs.upper() and "ERROR" not in run_logs.upper():
178
  break
179
 
180
+ # Otherwise feed logs back for retry
181
  chat.append({
182
+ "role": "user",
183
+ "content": (
184
+ f"Build logs:\n{build_logs}\n\n"
185
+ f"Run logs:\n{run_logs}\n\n"
186
  "Please fix the code."
187
  )
188
  })
189
  time.sleep(2)
190
 
 
 
 
 
 
 
 
 
 
 
 
191
  # — REFRESH LOGS —
192
 
193
  def refresh_logs(
 
203
  # — BUILD THE UI —
204
 
205
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
206
+ gr.Markdown(
207
+ "## Sign in + Auto‑Build Spaces\n\n"
208
+ "1. Sign in 2. Enter your prompt 3. Watch code, README, requirements, logs, and preview\n\n---"
209
+ )
210
+
211
+ # LOGIN controls (captures profile & token)
212
+ login_btn = gr.LoginButton(variant="huggingface", size="lg")
213
+ status_md = gr.Markdown("*Not logged in.*")
214
+ models_md = gr.Markdown()
215
+ demo.load(show_profile, inputs=None, outputs=status_md)
216
+ demo.load(list_private_models, inputs=None, outputs=models_md)
217
  login_btn.click(show_profile, inputs=None, outputs=status_md)
218
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
219
 
220
  # SETTINGS
221
+ sdk_choice = gr.Radio(["gradio", "streamlit"], value="gradio", label="SDK template")
222
+ api_key = gr.Textbox(label="Gemini API Key", type="password")
223
+ grounding = gr.Checkbox(label="Enable grounding", value=False)
224
+ space_suffix = gr.Textbox(label="Space suffix", value="auto-space",
225
+ info="E.g. 'auto-space', 'auto-space2', etc.")
226
 
227
  # CHAT + OUTPUTS
228
+ chatbot = gr.Chatbot(type="messages")
229
+ user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt")
230
+ send_btn = gr.Button("Send")
231
+ build_box = gr.Textbox(label="Build logs", lines=5, interactive=False)
232
+ run_box = gr.Textbox(label="Run logs", lines=5, interactive=False)
233
+ preview = gr.HTML("<p>No Space yet.</p>")
234
+
235
+ # Hook up generator (profile & token pulled from login_btn)
236
  send_btn.click(
237
  fn=handle_user_message,
238
+ inputs=[chatbot, sdk_choice, api_key, grounding, space_suffix, login_btn],
239
+ outputs=[chatbot, build_box, run_box, preview],
240
+ queue=True
241
  )
242
 
243
+ # Optional manual refresh
244
  refresh_btn = gr.Button("Refresh Logs")
245
  refresh_btn.click(
246
  fn=refresh_logs,
247
+ inputs=[space_suffix, login_btn],
248
  outputs=[build_box, run_box]
249
  )
250
 
251
+ demo.launch(server_name="0.0.0.0", server_port=7860)