wuhp commited on
Commit
ed27e39
·
verified ·
1 Parent(s): 7fb70ca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -41
app.py CHANGED
@@ -1,10 +1,17 @@
1
  import gradio as gr
2
  import json, time
 
3
  from huggingface_hub import create_repo, upload_file, list_models, constants
4
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
5
  from google import genai
6
  from google.genai.types import Tool, GenerateContentConfig, GoogleSearch
7
 
 
 
 
 
 
 
8
  # — USER INFO & MODEL LISTING —
9
 
10
  def show_profile(profile: gr.OAuthProfile | None) -> str:
@@ -66,41 +73,26 @@ def handle_user_message(
66
  system_msg = {
67
  "role":"system",
68
  "content":(
69
- "You are an AI assistant that generates all files needed for a HuggingFace Space, "
70
- "and returns exactly one JSON object with:\n"
71
- " • repo_name: the new Space name (no username)\n"
72
- " • files: a map of filename→file-content (strings)\n\n"
73
  "Files must include at least:\n"
74
  " - A code file (default name: app.py unless you choose otherwise)\n"
75
  " - requirements.txt with dependencies\n"
76
- " - README.md frontmatter (title, emoji, sdk, sdk_version, app_file, etc.)\n\n"
77
- "Do NOT output any extra text—only the JSON. "
78
- "The user’s request is provided as the next message."
79
  )
80
  }
81
 
82
  # build the chat context
83
  chat = [system_msg] + history + [{"role":"user", "content":user_prompt}]
84
 
85
- # strict JSON schema
86
- schema = {
87
- "type": "object",
88
- "properties": {
89
- "repo_name": { "type": "string" },
90
- "files": {
91
- "type": "object",
92
- "additionalProperties": { "type": "string" }
93
- }
94
- },
95
- "required": ["repo_name","files"]
96
- }
97
-
98
  repo_id = None
99
  build_logs = run_logs = ""
100
 
101
  for _ in range(5):
102
- # detect sdk_version
103
- if sdk_choice=="gradio":
104
  import gradio as _gr; sdk_version = _gr.__version__
105
  else:
106
  import streamlit as _st; sdk_version = _st.__version__
@@ -110,7 +102,7 @@ def handle_user_message(
110
  tools=tools,
111
  response_modalities=["TEXT"],
112
  response_mime_type="application/json",
113
- response_schema=schema
114
  )
115
 
116
  # call the LLM
@@ -119,16 +111,9 @@ def handle_user_message(
119
  contents=[m["content"] for m in chat],
120
  config=cfg
121
  )
122
- ai_json = resp.text
123
-
124
- # parse JSON
125
- try:
126
- spec = json.loads(ai_json)
127
- repo_name = spec["repo_name"]
128
- files = spec["files"]
129
- except Exception:
130
- chat.append({"role":"user","content":"Invalid JSON—please output exactly the JSON object per schema."})
131
- continue
132
 
133
  # prepare repo
134
  repo_id = f"{profile.username}/{repo_name}"
@@ -142,8 +127,8 @@ def handle_user_message(
142
 
143
  # write & upload all files
144
  for fn, content in files.items():
145
- # if README uses placeholder <SDK_VERSION>, replace it
146
- if fn.lower()=="readme.md":
147
  content = content.replace("<SDK_VERSION>", sdk_version)
148
  with open(fn, "w") as f:
149
  f.write(content)
@@ -158,7 +143,6 @@ def handle_user_message(
158
  # fetch logs
159
  build_logs = fetch_logs(repo_id, "build")
160
  run_logs = fetch_logs(repo_id, "run")
161
-
162
  if "ERROR" not in build_logs.upper() and "ERROR" not in run_logs.upper():
163
  break
164
 
@@ -168,12 +152,12 @@ def handle_user_message(
168
  "content":(
169
  f"Build logs:\n{build_logs}\n\n"
170
  f"Run logs:\n{run_logs}\n\n"
171
- "Please fix the JSON spec and return updated JSON."
172
  )
173
  })
174
  time.sleep(2)
175
 
176
- messages = [{"role":m["role"],"content":m["content"]} for m in chat if m["role"]!="system"]
177
  iframe = f'<iframe src="https://huggingface.co/spaces/{repo_id}" width="100%" height="500px"></iframe>'
178
  return messages, build_logs, run_logs, iframe
179
 
@@ -182,7 +166,7 @@ def handle_user_message(
182
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
183
  gr.Markdown("## Sign in + Auto‑Build Spaces\n\n"
184
  "1. Sign in  2. Prompt  3. Deploy & Debug\n\n"
185
- "_LLM will choose filenames, title, code, README, requirements, and iterate._\n\n---")
186
 
187
  login_btn = gr.LoginButton("huggingface", size="lg")
188
  status_md = gr.Markdown("*Not logged in.*")
@@ -203,11 +187,11 @@ with gr.Blocks(title="HF Space Auto‑Builder") as demo:
203
  run_box = gr.Textbox(label="Run logs", lines=5)
204
  preview = gr.HTML("<p>No Space yet.</p>")
205
 
206
- # Now pass user_in explicitly, so history isn’t empty
207
  send_btn.click(
208
  fn=handle_user_message,
209
  inputs=[chatbot, user_in, sdk_choice, api_key, grounding],
210
  outputs=[chatbot, build_box, run_box, preview]
211
  )
212
 
213
- demo.launch()
 
 
1
  import gradio as gr
2
  import json, time
3
+ from pydantic import BaseModel
4
  from huggingface_hub import create_repo, upload_file, list_models, constants
5
  from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
6
  from google import genai
7
  from google.genai.types import Tool, GenerateContentConfig, GoogleSearch
8
 
9
+ # — JSON spec model —
10
+
11
+ class RepoSpec(BaseModel):
12
+ repo_name: str
13
+ files: dict[str, str]
14
+
15
  # — USER INFO & MODEL LISTING —
16
 
17
  def show_profile(profile: gr.OAuthProfile | None) -> str:
 
73
  system_msg = {
74
  "role":"system",
75
  "content":(
76
+ "Return exactly one JSON object matching this schema:\n"
77
+ " repo_name (string)\n"
78
+ " • files (object mapping filename→file-content)\n\n"
 
79
  "Files must include at least:\n"
80
  " - A code file (default name: app.py unless you choose otherwise)\n"
81
  " - requirements.txt with dependencies\n"
82
+ " - README.md with frontmatter (title, emoji, sdk, sdk_version, app_file)\n\n"
83
+ "Do NOT output any extra text—only the JSON object."
 
84
  )
85
  }
86
 
87
  # build the chat context
88
  chat = [system_msg] + history + [{"role":"user", "content":user_prompt}]
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  repo_id = None
91
  build_logs = run_logs = ""
92
 
93
  for _ in range(5):
94
+ # detect sdk_version at runtime
95
+ if sdk_choice == "gradio":
96
  import gradio as _gr; sdk_version = _gr.__version__
97
  else:
98
  import streamlit as _st; sdk_version = _st.__version__
 
102
  tools=tools,
103
  response_modalities=["TEXT"],
104
  response_mime_type="application/json",
105
+ response_schema=RepoSpec
106
  )
107
 
108
  # call the LLM
 
111
  contents=[m["content"] for m in chat],
112
  config=cfg
113
  )
114
+ spec = RepoSpec.model_validate_json(resp.text)
115
+ repo_name = spec.repo_name
116
+ files = spec.files
 
 
 
 
 
 
 
117
 
118
  # prepare repo
119
  repo_id = f"{profile.username}/{repo_name}"
 
127
 
128
  # write & upload all files
129
  for fn, content in files.items():
130
+ # replace placeholder in README
131
+ if fn.lower() == "readme.md":
132
  content = content.replace("<SDK_VERSION>", sdk_version)
133
  with open(fn, "w") as f:
134
  f.write(content)
 
143
  # fetch logs
144
  build_logs = fetch_logs(repo_id, "build")
145
  run_logs = fetch_logs(repo_id, "run")
 
146
  if "ERROR" not in build_logs.upper() and "ERROR" not in run_logs.upper():
147
  break
148
 
 
152
  "content":(
153
  f"Build logs:\n{build_logs}\n\n"
154
  f"Run logs:\n{run_logs}\n\n"
155
+ "Please fix the JSON spec and return updated JSON only."
156
  )
157
  })
158
  time.sleep(2)
159
 
160
+ messages = [{"role":m["role"], "content":m["content"]} for m in chat if m["role"]!="system"]
161
  iframe = f'<iframe src="https://huggingface.co/spaces/{repo_id}" width="100%" height="500px"></iframe>'
162
  return messages, build_logs, run_logs, iframe
163
 
 
166
  with gr.Blocks(title="HF Space Auto‑Builder") as demo:
167
  gr.Markdown("## Sign in + Auto‑Build Spaces\n\n"
168
  "1. Sign in  2. Prompt  3. Deploy & Debug\n\n"
169
+ "_LLM controls filenames, code, README, requirements, and iterates until successful._\n\n---")
170
 
171
  login_btn = gr.LoginButton("huggingface", size="lg")
172
  status_md = gr.Markdown("*Not logged in.*")
 
187
  run_box = gr.Textbox(label="Run logs", lines=5)
188
  preview = gr.HTML("<p>No Space yet.</p>")
189
 
 
190
  send_btn.click(
191
  fn=handle_user_message,
192
  inputs=[chatbot, user_in, sdk_choice, api_key, grounding],
193
  outputs=[chatbot, build_box, run_box, preview]
194
  )
195
 
196
+ if __name__ == "__main__":
197
+ demo.launch()