wuhp commited on
Commit
18ec03a
·
verified ·
1 Parent(s): b679222

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -89
app.py CHANGED
@@ -2,7 +2,6 @@ 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
@@ -28,7 +27,7 @@ def list_private_models(
28
  ]
29
  return "No models found." if not models else "Models:\n\n" + "\n - ".join(models)
30
 
31
- # — UTILITIES —
32
 
33
  def get_sdk_version(sdk_choice: str) -> str:
34
  pkg = "gradio" if sdk_choice == "gradio" else "streamlit"
@@ -38,13 +37,10 @@ def get_sdk_version(sdk_choice: str) -> str:
38
  return "UNKNOWN"
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 —
48
 
49
  def _get_space_jwt(repo_id: str):
50
  url = f"{constants.ENDPOINT}/api/spaces/{repo_id}/jwt"
@@ -69,28 +65,18 @@ def fetch_logs(repo_id: str, level: str) -> str:
69
  continue
70
  return "\n".join(lines)
71
 
72
- # — CORE LOOP —
73
 
74
  def handle_user_message(
75
  history,
76
  sdk_choice: str,
77
  gemini_api_key: str,
78
  grounding_enabled: bool,
79
- space_suffix: str,
80
  profile: gr.OAuthProfile | None,
81
  oauth_token: gr.OAuthToken | None
82
  ):
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 = {
@@ -105,8 +91,9 @@ def handle_user_message(
105
  code_fn = "app.py" if sdk_choice=="gradio" else "streamlit_app.py"
106
  readme_fn = "README.md"
107
  reqs_fn = "requirements.txt"
 
108
 
109
- # Try up to 5 times to generate & push working code
110
  for _ in range(5):
111
  tools = [Tool(google_search=GoogleSearch())] if grounding_enabled else []
112
  cfg = GenerateContentConfig(tools=tools, response_modalities=["TEXT"])
@@ -117,15 +104,15 @@ def handle_user_message(
117
  config=cfg
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
125
  with open(code_fn, "w") as f:
126
  f.write(code)
127
 
128
- # Write README with dynamic SDK version
129
  sdk_version = get_sdk_version(sdk_choice)
130
  readme = f"""---
131
  title: Wuhp Auto Space
@@ -143,75 +130,45 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
143
  with open(readme_fn, "w") as f:
144
  f.write(readme)
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
 
152
- # Push to Hugging Face
153
- create_repo(
154
- repo_id=repo_id,
155
- token=oauth_token.token,
156
- exist_ok=True,
157
- repo_type="space",
158
- space_sdk=sdk_choice
159
- )
160
  for fn in (code_fn, readme_fn, reqs_fn):
161
- upload_file(
162
- path_or_fileobj=fn,
163
- path_in_repo=fn,
164
- repo_id=repo_id,
165
- token=oauth_token.token,
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 —
197
 
198
- def refresh_logs(
199
- space_suffix: str,
200
- profile: gr.OAuthProfile | None,
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"
212
- "1. Sign in 2. Enter your prompt 3. Watch code, README, requirements, logs, and preview\n\n---")
213
 
214
- # LOGIN controls
215
  login_btn = gr.LoginButton(variant="huggingface", size="lg")
216
  status_md = gr.Markdown("*Not logged in.*")
217
  models_md = gr.Markdown()
@@ -220,33 +177,35 @@ with gr.Blocks(title="HF Space Auto‑Builder") as demo:
220
  login_btn.click(show_profile, inputs=None, outputs=status_md)
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,
240
- inputs=[chatbot, sdk_choice, api_key, grounding, space_suffix],
241
  outputs=[chatbot, build_box, run_box, preview]
242
  )
243
 
244
- # Manual log refresh
 
 
 
 
 
 
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
 
252
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  import json
3
  import time
4
  import importlib.metadata
 
5
  import gradio as gr
6
  from huggingface_hub import create_repo, upload_file, list_models, constants
7
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
 
27
  ]
28
  return "No models found." if not models else "Models:\n\n" + "\n - ".join(models)
29
 
30
+ # — UTILITIES —
31
 
32
  def get_sdk_version(sdk_choice: str) -> str:
33
  pkg = "gradio" if sdk_choice == "gradio" else "streamlit"
 
37
  return "UNKNOWN"
38
 
39
  def extract_code(text: str) -> str:
 
 
 
40
  blocks = re.findall(r"```(?:\w*\n)?([\s\S]*?)```", text)
41
  return blocks[-1].strip() if blocks else text.strip()
42
 
43
+ # — HF SPACE LOGGING —
44
 
45
  def _get_space_jwt(repo_id: str):
46
  url = f"{constants.ENDPOINT}/api/spaces/{repo_id}/jwt"
 
65
  continue
66
  return "\n".join(lines)
67
 
68
+ # — CORE LOOP —
69
 
70
  def handle_user_message(
71
  history,
72
  sdk_choice: str,
73
  gemini_api_key: str,
74
  grounding_enabled: bool,
 
75
  profile: gr.OAuthProfile | None,
76
  oauth_token: gr.OAuthToken | None
77
  ):
78
  if profile is None or oauth_token is None:
79
+ return history + [{"role":"assistant","content":"⚠️ Please log in first."}], "", "", "<p>No Space yet.</p>"
 
 
 
 
 
 
 
 
 
80
 
81
  client = genai.Client(api_key=gemini_api_key)
82
  system_msg = {
 
91
  code_fn = "app.py" if sdk_choice=="gradio" else "streamlit_app.py"
92
  readme_fn = "README.md"
93
  reqs_fn = "requirements.txt"
94
+ repo_id = f"{profile.username}/{profile.username}-auto-space"
95
 
96
+ build_logs = run_logs = ""
97
  for _ in range(5):
98
  tools = [Tool(google_search=GoogleSearch())] if grounding_enabled else []
99
  cfg = GenerateContentConfig(tools=tools, response_modalities=["TEXT"])
 
104
  config=cfg
105
  )
106
 
107
+ raw = resp.text
108
+ code = extract_code(raw)
109
  chat.append({"role":"assistant","content":code})
110
 
111
+ # write code
112
  with open(code_fn, "w") as f:
113
  f.write(code)
114
 
115
+ # write dynamic README
116
  sdk_version = get_sdk_version(sdk_choice)
117
  readme = f"""---
118
  title: Wuhp Auto Space
 
130
  with open(readme_fn, "w") as f:
131
  f.write(readme)
132
 
133
+ # write requirements
134
  base_reqs = "pandas\n"
135
  extra = "streamlit\n" if sdk_choice=="streamlit" else "gradio\n"
136
  with open(reqs_fn, "w") as f:
137
  f.write(base_reqs + extra)
138
 
139
+ # push to HF
140
+ create_repo(repo_id=repo_id, token=oauth_token.token,
141
+ exist_ok=True, repo_type="space", space_sdk=sdk_choice)
 
 
 
 
 
142
  for fn in (code_fn, readme_fn, reqs_fn):
143
+ upload_file(path_or_fileobj=fn, path_in_repo=fn,
144
+ repo_id=repo_id, token=oauth_token.token,
145
+ repo_type="space")
 
 
 
 
146
 
147
+ build_logs = fetch_logs(repo_id, "build")
148
+ run_logs = fetch_logs(repo_id, "run")
149
+ if "ERROR" not in build_logs.upper() and "ERROR" not in run_logs.upper():
 
150
  break
151
 
152
  chat.append({
153
  "role":"user",
154
  "content":(
155
+ f"Build logs:\n{build_logs}\n\n"
156
+ f"Run logs:\n{run_logs}\n\n"
157
  "Please fix the code."
158
  )
159
  })
160
  time.sleep(2)
161
 
 
162
  messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
163
+ iframe = f'<iframe src="https://huggingface.co/spaces/{repo_id}" width="100%" height="500px"></iframe>'
164
+ return messages, build_logs, run_logs, iframe
 
 
 
 
 
 
 
 
165
 
166
+ # — BUILD THE UI —
 
 
 
 
 
 
 
 
 
 
167
 
168
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
169
+ gr.Markdown("## Sign in + Auto‑Build Spaces\n\n1. Sign in 2. Enter your prompt 3. Watch code, README, requirements, logs, and preview\n\n---")
 
170
 
171
+ # LOGIN & MODEL LISTING
172
  login_btn = gr.LoginButton(variant="huggingface", size="lg")
173
  status_md = gr.Markdown("*Not logged in.*")
174
  models_md = gr.Markdown()
 
177
  login_btn.click(show_profile, inputs=None, outputs=status_md)
178
  login_btn.click(list_private_models, inputs=None, outputs=models_md)
179
 
180
+ # CONTROLS
181
+ sdk_choice = gr.Radio(["gradio","streamlit"], value="gradio", label="SDK template")
182
+ api_key = gr.Textbox(label="Gemini API Key", type="password")
183
+ grounding = gr.Checkbox(label="Enable grounding", value=False)
 
 
184
 
185
  # CHAT + OUTPUTS
186
+ chatbot = gr.Chatbot(type="messages")
187
+ user_in = gr.Textbox(placeholder="Your prompt…", label="Prompt")
188
+ send_btn = gr.Button("Send")
189
+
190
+ build_box = gr.Textbox(label="Build logs", lines=5, interactive=False)
191
+ run_box = gr.Textbox(label="Run logs", lines=5, interactive=False)
192
+ preview = gr.HTML("<p>No Space yet.</p>")
193
 
194
  send_btn.click(
195
  fn=handle_user_message,
196
+ inputs=[chatbot, sdk_choice, api_key, grounding],
197
  outputs=[chatbot, build_box, run_box, preview]
198
  )
199
 
200
+ # Refresh Logs button —
201
+ def _refresh(profile: gr.OAuthProfile | None, oauth_token: gr.OAuthToken | None):
202
+ if not profile or not oauth_token:
203
+ return "", ""
204
+ repo = f"{profile.username}/{profile.username}-auto-space"
205
+ return fetch_logs(repo, "build"), fetch_logs(repo, "run")
206
+
207
  refresh_btn = gr.Button("Refresh Logs")
208
+ # Gradio will auto‑inject `profile` and `oauth_token` here.
209
+ refresh_btn.click(_refresh, inputs=None, outputs=[build_box, run_box])
 
 
 
210
 
211
  demo.launch(server_name="0.0.0.0", server_port=7860)